import { zodResolver } from "@hookform/resolvers/zod";
import { Loader2 } from "lucide-react";
import { type ComponentProps, useContext } from "react";
import { useForm } from "react-hook-form";
import * as z from "zod";
import { authLocalization } from "../../lib/auth-localization";
import { AuthUIContext } from "../../lib/auth-ui-provider";
import { cn, getLocalizedError } from "../../lib/utils";
import { Button } from "../ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "../ui/dialog";
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "../ui/form";
import { Input } from "../ui/input";
import type { SettingsCardClassNames } from "./shared/settings-card";

export interface DeleteAccountDialogProps
  extends ComponentProps<typeof Dialog> {
  classNames?: SettingsCardClassNames;
  accounts?: { provider: string }[] | null;
}

export function DeleteAccountDialog({
  classNames,
  accounts,
  onOpenChange,
  ...props
}: DeleteAccountDialogProps) {
  const {
    authClient,
    basePath,
    baseURL,
    freshAge,
    hooks: { useSession },
    viewPaths,
    navigate,
    toast,
  } = useContext(AuthUIContext);

  const localization = authLocalization;

  const { data: sessionData } = useSession();

  const credentialsLinked = accounts?.some(
    (acc) => acc.provider === "credential"
  );

  const formSchema = z.object({
    password: credentialsLinked
      ? z.string().min(1, { message: localization.passwordRequired! })
      : z.string().optional(),
  });

  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      password: "",
    },
  });

  const { isSubmitting } = form.formState;

  const deleteAccount = async ({ password }: z.infer<typeof formSchema>) => {
    try {
      await authClient.deleteUser({
        fetchOptions: {
          throw: true,
        },
      });
      toast({
        variant: "success",
        message: localization.deleteAccountSuccess!,
      });
      navigate(`${basePath}/${viewPaths.signOut}`);
    } catch (error) {
      toast({
        variant: "error",
        message: getLocalizedError({ error, localization }),
      });
    }

    onOpenChange?.(false);
  };

  return (
    <Dialog onOpenChange={onOpenChange} {...props}>
      <DialogContent className={cn("sm:max-w-md", classNames?.dialog?.content)}>
        <DialogHeader className={classNames?.dialog?.header}>
          <DialogTitle className={cn("text-lg md:text-xl", classNames?.title)}>
            {localization?.deleteAccount}
          </DialogTitle>

          <DialogDescription
            className={cn("text-xs md:text-sm", classNames?.description)}
          >
            {localization?.deleteAccountNotFresh}
          </DialogDescription>
        </DialogHeader>

        <Form {...form}>
          <form
            onSubmit={form.handleSubmit(deleteAccount)}
            className="grid gap-4"
          >
            {credentialsLinked && (
              <FormField
                control={form.control}
                name="password"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel className={classNames?.label}>
                      {localization?.password}
                    </FormLabel>

                    <FormControl>
                      <Input
                        autoComplete="current-password"
                        placeholder={localization?.passwordPlaceholder}
                        type="password"
                        className={classNames?.input}
                        {...field}
                      />
                    </FormControl>

                    <FormMessage className={classNames?.error} />
                  </FormItem>
                )}
              />
            )}

            <DialogFooter className={classNames?.dialog?.footer}>
              <Button
                type="button"
                variant="secondary"
                className={cn(classNames?.button, classNames?.secondaryButton)}
                onClick={() => onOpenChange?.(false)}
              >
                {localization.cancel}
              </Button>

              <Button
                className={cn(
                  classNames?.button,
                  classNames?.destructiveButton
                )}
                disabled={isSubmitting}
                variant="destructive"
                type="submit"
              >
                {isSubmitting && <Loader2 className="animate-spin" />}
                {localization?.deleteAccount}
              </Button>
            </DialogFooter>
          </form>
        </Form>
      </DialogContent>
    </Dialog>
  );
}
