"use client";

import { useTransition } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import Link from "next/link";
import { useSession, signIn as clientSignIn } from "next-auth/react";
import { useForm, Controller } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Loader2, Globe, Music2 } from "lucide-react";
import { toast } from "sonner";

import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Separator } from "@/components/ui/separator";
import { FormField } from "@/components/auth/form-field";
import { FormError } from "@/components/auth/form-error";
import { PasswordInput } from "@/components/auth/password-input";
import { loginAction } from "@/actions/auth-actions";
import { loginSchema, type LoginInput } from "@/validators/auth";
import { useLanguage } from "@/lib/i18n/context";

export function LoginForm({ googleEnabled = false }: { googleEnabled?: boolean }) {
  const router = useRouter();
  const searchParams = useSearchParams();
  const { update: updateSession } = useSession();
  const { t, locale } = useLanguage();
  const f = t.auth.form;
  const [isPending, startTransition] = useTransition();
  const [isGooglePending, startGoogleTransition] = useTransition();

  const {
    register,
    handleSubmit,
    control,
    setError,
    formState: { errors },
  } = useForm<LoginInput>({
    resolver: zodResolver(loginSchema),
    defaultValues: { email: "", password: "", remember: true },
  });

  function onSubmit(values: LoginInput) {
    startTransition(async () => {
      const result = await loginAction(values, locale);

      if (!result.success) {
        toast.error(result.error);
        setError("root", { message: result.error });
        return;
      }

      toast.success(f.welcomeBackToast);
      // The sign-in happened inside the server action, so the client-side
      // session (context from SessionProvider) doesn't know yet — force a
      // refetch so the header updates immediately instead of waiting for
      // the next focus/interval revalidation.
      await updateSession();
      const callbackUrl = searchParams.get("callbackUrl");
      router.push(callbackUrl && callbackUrl.startsWith("/") ? callbackUrl : "/dashboard");
      router.refresh();
    });
  }

  function handleGoogle() {
    if (!googleEnabled) {
      toast.info(f.googleComingSoon);
      return;
    }
    const callbackUrl = searchParams.get("callbackUrl");
    startGoogleTransition(() => {
      void clientSignIn("google", {
        callbackUrl: callbackUrl && callbackUrl.startsWith("/") ? callbackUrl : "/dashboard",
      });
    });
  }

  return (
    <div className="flex flex-col gap-6">
      <form onSubmit={handleSubmit(onSubmit)} noValidate className="flex flex-col gap-4">
        <FormField id="email" label={f.email} error={errors.email?.message}>
          <Input
            id="email"
            type="email"
            autoComplete="email"
            aria-invalid={!!errors.email}
            {...register("email")}
          />
        </FormField>

        <FormField id="password" label={f.password} error={errors.password?.message}>
          <PasswordInput
            id="password"
            autoComplete="current-password"
            aria-invalid={!!errors.password}
            {...register("password")}
          />
        </FormField>

        <div className="flex items-center justify-between">
          <div className="flex items-center gap-2">
            <Controller
              name="remember"
              control={control}
              render={({ field }) => (
                <Checkbox
                  id="remember"
                  checked={field.value}
                  onCheckedChange={(checked) => field.onChange(checked === true)}
                />
              )}
            />
            <label htmlFor="remember" className="text-sm text-muted-foreground">
              {f.rememberMe}
            </label>
          </div>
          <Link
            href="/forgot-password"
            className="text-sm font-medium text-primary underline-offset-2 hover:underline"
          >
            {f.forgotPasswordLink}
          </Link>
        </div>

        <FormError message={errors.root?.message} />

        <Button type="submit" size="lg" disabled={isPending} className="mt-2">
          {isPending ? <Loader2 className="size-4 animate-spin" /> : null}
          {f.logIn}
        </Button>
      </form>

      <div className="flex items-center gap-3">
        <Separator className="flex-1" />
        <span className="text-xs text-muted-foreground">{f.or}</span>
        <Separator className="flex-1" />
      </div>

      <div className="flex flex-col gap-2.5">
        <Button
          type="button"
          variant="outline"
          size="lg"
          onClick={handleGoogle}
          disabled={isGooglePending}
        >
          {isGooglePending ? <Loader2 className="size-4 animate-spin" /> : <Globe className="size-4" />}
          {f.continueWithGoogle}
        </Button>
        <Button
          type="button"
          variant="outline"
          size="lg"
          disabled
          aria-disabled="true"
          title={f.tiktokComingSoon}
        >
          <Music2 className="size-4" />
          {f.continueWithTikTok}
        </Button>
      </div>
    </div>
  );
}
