"use client";

import React, {
  forwardRef,
  useEffect,
  useImperativeHandle,
  useState,
} from "react";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import { signUpValidationSchema } from "@/utils/form";
import {
  login,
  signup,
  createCheckoutSession,
  mailchimp,
} from "@/app/(auth)/actions";
import { CheckoutSession, ModalStatus, SignUpForm, TextOnUse } from "@/types";
import { toast } from "react-toastify";
import { useRouter } from "next/navigation";
import { FormRefMethods } from "../ModalSignIn/ModalSignInForm";

interface ModalSignUpFormProps {
  generateCheckoutSession: boolean;
  textOnUse: TextOnUse;
  companySizeList: string[];
  setStatus: React.Dispatch<React.SetStateAction<ModalStatus>>;
  getPriceId: () => string | undefined;
}

const ModalSignUpForm = forwardRef<FormRefMethods, ModalSignUpFormProps>(
  (
    {
      generateCheckoutSession,
      companySizeList,
      textOnUse,
      setStatus,
      getPriceId,
    }: ModalSignUpFormProps,
    ref
  ) => {
    const router = useRouter();
    const [email, setEmail] = useState("");
    const [password, setPassword] = useState("");
    const [organisation, setOrganisation] = useState("");

    const {
      register,
      handleSubmit,
      reset,
      formState: { errors },
    } = useForm({
      resolver: yupResolver(signUpValidationSchema),
    });

    const submitForm = async (data: SignUpForm) => {
      setEmail(data.email);
      setPassword(data.password!);
      setOrganisation(data.organisation);
      setStatus(ModalStatus.Loading);
      try {
        await sendMailchimpRequest(data);
        await sendSignUpRequest(data);
        await sendSignInRequest(data);
        const price_id = getPriceId();
        console.log("price_id", price_id);
        const checkoutSession = await checkoutSessionRequest(price_id);
        setEmail("");
        setPassword("");
        setOrganisation("");
        reset();
        setStatus(ModalStatus.Success);
        if (!!checkoutSession) {
          router.push(checkoutSession.url);
        }
      } catch (error) {
        if (error instanceof Error) {
          toast.error(error.message, {
            position: "bottom-left",
            autoClose: 5000,
            hideProgressBar: false,
            closeOnClick: true,
            pauseOnHover: true,
            draggable: true,
            progress: undefined,
            theme: "colored",
          });
        }
        setStatus(ModalStatus.Default);
      }
    };

    const sendMailchimpRequest = async (data: SignUpForm) => {
      console.log("sendMailchimpRequest call initiated");
      await mailchimp({
        email: data.email,
        first_name: data.first_name,
        last_name: data.last_name,
        phone_number: !data.phone_number ? "" : data.phone_number,
        company_size: data.company_size,
        source: textOnUse.source,
      });
      console.log("sendMailchimpRequest call success");
    };

    const checkoutSessionRequest = async (price_id?: string) => {
      if (!price_id) {
        return;
      }
      console.log("createCheckoutSession call initiated");
      const checkoutSession = await createCheckoutSession(price_id);
      console.log("createCheckoutSession successful");
      return checkoutSession;
    };

    const sendSignUpRequest = async (data: SignUpForm) => {
      try {
        console.log("Signup call initiated");
        await signup(data);
        console.log("Signup successful");
      } catch (error) {
        if (error instanceof Error) {
          console.error(
            "Error during the signup or email process:",
            error.message
          );
        }
        throw error; // This will allow .catch block outside this function to capture the error
      }
    };

    const sendSignInRequest = async (data: SignUpForm) => {
      try {
        console.log("SignIn call initiated");
        await login({ email: data.email, password: data.password! });
        console.log("SignIn successful");
      } catch (error) {
        if (error instanceof Error) {
          console.error(
            "Error during the SignIn or email process:",
            error.message
          );
        }
        throw error; // This will allow .catch block outside this function to capture the error
      }
    };
    useImperativeHandle(ref, () => ({
      resetForm: () => {
        reset();
        setEmail("");
        setPassword("");
        setOrganisation("");
      },
    }));

    return (
      <form onSubmit={handleSubmit(submitForm)} className="w-full md:w-1/2">
        <div className="relative mt-3">
          <input
            {...register("email")}
            type="text"
            id="SignUpEmail"
            className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black  dark:placeholder-white dark:border-white"
            placeholder="Email…"
            aria-label="Email…"
            autoComplete="on"
          />
          <label
            htmlFor="SignUpEmail"
            className="md:absolute top-[50%] translate-y-[-50%] left-[105%] w-[220px] text-red-400"
          >
            {errors.email ? "*" + errors.email.message : ""}
          </label>
        </div>
        <div className="relative mt-1">
          <input
            {...register("first_name")}
            id="SignUpFirstName"
            type="text"
            className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black"
            placeholder="First Name…"
            aria-label="First Name…"
            autoComplete="on"
          />
          <label
            htmlFor="SignUpFirstName"
            className="md:absolute top-[50%] translate-y-[-50%] left-[105%] w-[220px] text-red-400"
          >
            {errors.first_name ? "*" + errors.first_name.message : ""}
          </label>
        </div>
        <div className="relative mt-1">
          <input
            {...register("last_name")}
            id="SignUpLastName"
            type="text"
            className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black  dark:placeholder-white dark:border-white"
            placeholder="Last Name…"
            aria-label="Last Name…"
          />
          <label
            htmlFor="SignUpLastName"
            className="md:absolute top-[50%] translate-y-[-50%] left-[105%] w-[220px] text-red-400"
          >
            {errors.last_name ? "*" + errors.last_name.message : ""}
          </label>
        </div>

        <div className="relative mt-1">
          <input
            {...register("phone_number")}
            id="SignUpPhoneNumber"
            type="text"
            className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black  dark:placeholder-white dark:border-white"
            placeholder="Phone Number…"
            aria-label="Phone Number…"
          />
          <label
            htmlFor="SignUpPhoneNumber"
            className="md:absolute top-[50%] translate-y-[-50%] left-[105%] w-[220px] text-red-400"
          >
            {errors.phone_number ? "*" + errors.phone_number.message : ""}
          </label>
        </div>
        <div className="relative mt-1">
          <input
            {...register("organisation")}
            id="SignUpOrganisation"
            type="text"
            className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black  dark:placeholder-white dark:border-white"
            placeholder="Organisation…"
            aria-label="Organisation…"
          />
          <label
            htmlFor="SignUpOrganisation"
            className="md:absolute top-[50%] translate-y-[-50%] left-[105%] w-[220px] text-red-400"
          >
            {errors.organisation ? "*" + errors.organisation.message : ""}
          </label>
        </div>
        <div className="relative mt-1">
          <select
            {...register("company_size")}
            id="SignUpCompanySize"
            defaultValue={""}
            className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black  dark:placeholder-white dark:border-white"
          >
            <option className="bg-gray-850" value={""} disabled>
              Company Size…
            </option>
            {companySizeList.map((companySizeOption, i) => {
              return (
                <option
                  className="bg-gray-850"
                  value={companySizeOption}
                  key={i}
                >
                  {companySizeOption}
                </option>
              );
            })}
          </select>
          <label
            htmlFor="SignUpCompanySize"
            className="md:absolute top-[50%] translate-y-[-50%] left-[105%] w-[220px] text-red-400"
          >
            {errors.company_size ? "*" + errors.company_size.message : ""}
          </label>
        </div>
        <div className="relative mt-1">
          <input
            {...register("password")}
            id="SignUpPwd"
            type="password"
            className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black  dark:placeholder-white dark:border-white"
            placeholder="Password..."
            aria-label="Password"
          />
          <label
            htmlFor="SignUpPwd"
            className="md:absolute top-[50%] translate-y-[-50%] left-[105%] w-[220px] text-red-400"
          >
            {errors.password ? "*" + errors.password.message : ""}
          </label>
        </div>
        <div className="relative mt-1 mb-4">
          <input
            {...register("passwordConfirmation")}
            id="SignUpPwdConfirm"
            type="password"
            className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black  dark:placeholder-white dark:border-white"
            placeholder="Confirmed Password..."
            aria-label="Confirmed Password"
          />
          <label
            htmlFor="SignUpPwd"
            className="md:absolute top-[50%] translate-y-[-50%] left-[105%] w-[220px] text-red-400"
          >
            {errors.passwordConfirmation
              ? "*" + errors.passwordConfirmation.message
              : ""}
          </label>
        </div>

        <button
          type="submit"
          className="btn capitalize font-bold text-black bg-base-100 hover:bg-base-100 shadow"
        >
          {textOnUse.buttonText}
        </button>
      </form>
    );
  }
);

ModalSignUpForm.displayName = "ModalSignUpForm";
export default ModalSignUpForm;
