import { FormBuilder } from "@/components/FormBuilder";
import { FormCard, FormContent } from "@/components/FormCard";
import { Form } from "@/components/ui/form";
import { useGlobal } from "@/context/global";
import { ConvertJSONToFormData, ServerRequest } from "@/lib/actions";
import getChangePasswordField from "@/models/files/_getChangePasswordFields";
import {
  ChangePasswordSchema,
  getChangePasswordSchema,
} from "@/schemas/account/_changepassword";
import {
  changeUserPassword,
  confirmaccount,
  requestCode,
} from "@/services/users";
import { faKey } from "@fortawesome/free-solid-svg-icons";
import { zodResolver } from "@hookform/resolvers/zod";
import { signOut, useSession } from "next-auth/react";
import { useRouter } from "next/navigation";
import { useEffect, useState, useTransition } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";

export default function ChangePassword() {
  const { data } = useSession();

  const { dict, closeModal } = useGlobal();

  const router = useRouter();

  const [isPending, startTransition] = useTransition();

  const [isUserValid, setIsUserValid] = useState<boolean>(false);
  const [isPassForgotten, setIsPassForgotten] = useState<boolean>(false);

  const form = useForm<ChangePasswordSchema>({
    resolver: zodResolver(getChangePasswordSchema(dict)),
    mode: "onChange",
    defaultValues: {
      user: data?.user?.email || "",
      password: "",
      "new-password": "",
      "rep-password": "",
      code: "",
      csrfToken: "",
    },
  });

  const handleConfirmAccount = async () => {
    startTransition(() => {
      const [user, code, password] = form.getValues([
        "user",
        "code",
        "password",
      ]);

      const promise = new Promise(async (resolve, reject) => {
        const formData = ConvertJSONToFormData({
          user,
          code,
          password,
        });

        const result = await ServerRequest(confirmaccount(formData));

        if (!result.operation) {
          return reject(result);
        }

        setIsUserValid(true);
        return resolve(result);
      });

      toast.promise(promise, {
        loading: dict.alerts.change_password.loading.confirm_account,
        success: ({ message }: any) => message,
        error: ({ message }) => message,
      });
    });
  };

  const handleSendCode = async () => {
    const promise = new Promise(async (resolve, reject) => {
      const user = form.getValues("user");

      const formData = new FormData();

      formData.append("user-email", user);

      const result = await ServerRequest(requestCode(formData));

      if (!result.operation) {
        return reject(result);
      }

      return resolve(result);
    });

    toast.promise(promise, {
      loading: dict.alerts.change_password.loading.send_code,
      success: ({ message }) => message,
      error: ({ message }) => message,
    });
  };

  const onSubmit = async (values: ChangePasswordSchema) => {
    const promise = new Promise(async (resolve, reject) => {
      if (values["new-password"] !== values["rep-password"]) {
        return reject({
          error: dict.alerts.change_password.error.pass_not_match,
        });
      }

      const formData = ConvertJSONToFormData({
        user: values.user,
        password: values["new-password"],
      });

      const result = await ServerRequest(changeUserPassword(formData));

      if (!result.operation) {
        return reject(result);
      }

      const signout = await signOut({ redirect: false });
      resolve(result);
    });

    toast.promise(promise, {
      loading: dict.alerts.change_password.loading.change,
      success: ({ message }) => {
        router.push("/auth/login");
        return message;
      },
      error: ({ message }) => message,
    });
  };

  useEffect(() => {
    form.setValue("new-password", "");
    form.setValue("rep-password", "");

    return () => {
      form.reset();
    };
  }, [isUserValid]);

  return (
    <div className="space-y-4 rounded-md bg-white p-4 shadow">
      <FormCard>
        <FormContent
          icon={faKey}
          title={dict.pages.settings.account.form.title}
        >
          <Form {...form}>
            <form onSubmit={form.handleSubmit(onSubmit)}>
              <FormBuilder
                form={form}
                elements={getChangePasswordField({
                  isUserValid,
                  isPassForgotten,
                  setIsPassForgotten,
                  handleConfirmAccount,
                  handleSendCode,
                  onSubmit,
                  closeModal,
                  isPending,
                  form,
                  dict,
                })}
                upperLabel
              />
            </form>
          </Form>
        </FormContent>
      </FormCard>
    </div>
  );
}
