"use client";
import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { useLocale, useTranslations } from "next-intl";
import { Input } from "@/components/ui/input";
import CustomBreadcrumb from "@/app/ui/shared/CustomBreadcrumb";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import PasswordInput from "../../ui/form/PassowrdInput";
import CustomPhoneInput from "../../ui/shared/CustomPhoneInput";
import { Checkbox } from "@/components/ui/checkbox";
import CountrySelect from "../../ui/shared/CountrySelect";
import postData from "@/api/post-data";
import getCountryId from "@/api/countries/getCountryId";
import SubmitButton from "../../ui/shared/SubmitButton";
import { toastError, toastSuccess } from "@/services/custom-toast";
import { useRouter } from "next/navigation";
import Link from "next/link";
import clsx from "clsx";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { FaSpinner } from "react-icons/fa";
import { useEffect, useState } from "react";
import fetchData from "@/api/fetch-data";
import { useSettings } from "@/stores/settings";
import ReCAPTCHA from "react-google-recaptcha";

/**
 * @author: Ahmed Badran
 * Created At: 21-10-2024
 *
 * Edit By: Ahmed Badran
 * Edit At: 29-10-2024
 *
 * It validates the following fields:
 * - name: required, min length of 1
 * - email: required, valid email address
 * - country: required, min length of 1
 * - gender: required, one of "male" or "female"
 * - birthday: required, valid date in the format "YYYY-MM-DD"
 * - password: required, min length of 8
 * - confirm_password: required, same as password
 *
 * The form is rendered as a vertical list of form fields with labels and
 * validation messages. The country field is rendered as a select menu with a
 * placeholder label. The gender field is rendered as a radio group with two
 * options. The birthday field is rendered as a calendar picker. The password
 * field is rendered as an input with a password toggle button.
 *
 * The form is wrapped in a <Form> component from the `@radix-ui/react-form`
 * library, which provides a way to manage form state and validation.
 *
 * @returns {JSX.Element} The rendered SignUp component.
 */
export default function SignUpAsVendor() {
  const t = useTranslations("sign-up");
  const error = useTranslations("form-errors");
  const label = useTranslations("form-labels");
  const router = useRouter();
  const locale = useLocale();
  const [isCitiesLoading, setIsCitiesLoading] = useState(false);
  const [cities, setCities] = useState([]);
  const [countryId, setCountryId] = useState(null);
  const [captcha, setCaptcha] = useState();
  const [captchaError, setCaptchaError] = useState(false);
  const [captchaState, setCaptchaState] = useState(0);
  const { settings } = useSettings();
  const form = useForm({
    resolver: zodResolver(
      z
        .object({
          name: z
            .string({ message: error("required") })
            .min(3, { message: error("min3") })
            .max({ message: error("max32") }),
          lastname: z
            .string({ message: error("required") })
            .min(3, { message: error("min3") })
            .max({ message: error("max32") }),
          email: z
            .string({ message: error("required") })
            .email({ message: error("email") }),
          phone: z
            .string({ errorMap: () => ({ message: error("mobile") }) })
            .min(10)
            .max(16),
          country_id: z
            .string({ errorMap: () => ({ message: error("required") }) })
            .min(1),
          gender: z
            .string({ errorMap: () => ({ message: error("required") }) })
            .min(1),
          city_id: z
            .string({ errorMap: () => ({ message: error("required") }) })
            .min(1),
          privacy: z.boolean().refine((value) => value),
          password: z
            .string({ message: error("required") })
            .min(6, { message: error("min6") })
            .max({ message: error("max64") }),
          confirm_password: z
            .string({ message: error("required") })
            .min(6, { message: error("min6") })
            .max({ message: error("max64") }),
        })
        .refine((data) => data.password === data.confirm_password, {
          message: error("confirm-password"),
          path: ["confirm_password"],
        })
    ),
  });
  useEffect(() => {
    setCaptchaState(settings?.site_settings?.captcha_enabled)
  }, [settings?.site_settings?.captcha_enabled])

  const {
    formState: { isSubmitting, isSubmitted },
    setError,
  } = form; // Get form helpers

  /**
   * @author: Ahmed Badran
   * Created At: 29-10-2024
   *
   * Submits the sign-up form data to the server for user registration.
   *
   * This function processes the form data, removing unnecessary fields,
   * and prepares it for submission. It handles server validation errors
   * and displays appropriate messages. Upon successful registration, it
   * redirects the user to the sign-in page.
   *
   * @param {Object} data - The form data to be submitted.
   * @param {string} data.mobile - The user's mobile number, which will be formatted.
   * @param {string} data.confirm_password - The confirmation password, which will be removed.
   * @param {string} data.country_id - The user's country, which will be resolved to an ID.
   *
   * @returns {Promise<void>}
   */
  async function onSubmit(values) {
    if (!captcha && captchaState == 1) {
      setCaptchaError(true); // Show error if captcha is not filled
      return; // Prevent form submission
    }
    delete values.confirm_password; // Remove confirm_password from data
    values.country_id = countryId;
    const formData = new FormData();
    for (const [key, value] of Object.entries(values)) {
      // Replace data to FormData().
      formData.append(key, value);
    }
    formData.append("is_vendor", "1");
    // Registry Api
    const { error, data, message } = await postData({
      endPoint: "/user/register",
      body: formData,
    });

    if (error) {
      if (message === "Validation failed") {
        for (const [key, value] of Object.entries(data)) {
          setError(
            key,
            {
              type: "server",
              message: value,
            },
            { shouldFocus: true }
          );
        }
        return;
      }
      toastError(message);
      return;
    }
    toastSuccess(message);
    router.push("/sign-in-vendor");
  }

  async function getCitiesByCountryId(countryCode) {
    const { setValue } = form;
    setValue("country_id", countryCode);
    const countryId = await getCountryId(countryCode);
    setCountryId(countryId);

    if (countryId) {
      setIsCitiesLoading(true);
      const response = await fetchData({
        endPoint: `/cities/${countryId}`,
        locale,
      });
      if (response.error == false) {
        setCities(response.data);
      }
      setIsCitiesLoading(false);
    }
  }

  return (
    <>
      <CustomBreadcrumb />
      <section className="max-md:mx-4 mt-12 mb-20 rounded-lg p-4 md:p-8 shadow-lg md:w-1/2 mx-auto">
        <div className="space-y-2 mb-12">
          <h1 className="font-bold text-xl text-center md:text-2xl lg:text-3xl text-dark">
            {t("create-account-vendor")}
          </h1>
        </div>
        <Form {...form}>
          <form
            method="post"
            onSubmit={form.handleSubmit(onSubmit)}
            className="space-y-4"
          >
            <FormField
              name="name"
              control={form.control}
              render={({ field }) => (
                <FormItem>
                  <FormControl>
                    <Input
                      className="focus-visible:ring-main"
                      placeholder={label("first-name")}
                      {...field}
                    />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              name="lastname"
              control={form.control}
              render={({ field }) => (
                <FormItem>
                  <FormControl>
                    <Input
                      className="focus-visible:ring-main"
                      placeholder={label("last-name")}
                      {...field}
                    />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              name="email"
              control={form.control}
              render={({ field }) => (
                <FormItem>
                  <FormControl>
                    <Input
                      className="focus-visible:ring-main"
                      placeholder={label("email")}
                      {...field}
                    />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              name="country_id"
              control={form.control}
              render={({ field }) => (
                <FormItem>
                  <FormControl>
                    <CountrySelect
                      value={field.value}
                      onChange={getCitiesByCountryId}
                      placeholder={label("country")}
                      className="focus:border-main focus:border-2"
                    />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              name="city_id"
              control={form.control}
              render={({ field }) => (
                <FormItem>
                  <FormControl>
                    <Select
                      dir={locale === "ar" ? "rtl" : "ltr"}
                      value={field.value}
                      onValueChange={field.onChange}
                    >
                      <SelectTrigger className="focus-visible:ring-dark border-dark">
                        <SelectValue placeholder={label("city")} />
                      </SelectTrigger>
                      <SelectContent className="max-h-60">
                        {!isCitiesLoading ? (
                          cities.length > 0 ? (
                            cities?.map((city, i) => (
                              <SelectItem key={i} value={String(city.id)}>
                                {city.title}
                              </SelectItem>
                            ))
                          ) : (
                            <p className="text-center">
                              {locale === "ar"
                                ? "لا يوجد مدن"
                                : "No cities found"}
                            </p>
                          )
                        ) : (
                          <FaSpinner className="animate-spin m-5 " />
                        )}
                      </SelectContent>
                    </Select>
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              name="phone"
              control={form.control}
              render={({ field }) => (
                <FormItem>
                  <FormControl>
                    <CustomPhoneInput
                      value={field.value}
                      valueOnChange={field.onChange}
                      placeholder={label("mobile")}
                      className={"flex gap-2"}
                    />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              name="gender"
              control={form.control}
              render={({ field }) => (
                <FormItem className="flex items-end gap-4 space-y-0">
                  <FormLabel>{label("gender")}</FormLabel>
                  <FormControl>
                    <RadioGroup
                      onValueChange={field.onChange}
                      defaultValue={field.value}
                      className="flex gap-2 items-center"
                    >
                      <FormItem className="flex items-center gap-3">
                        <FormLabel>{label("male")}</FormLabel>
                        <FormControl>
                          <RadioGroupItem value="male" />
                        </FormControl>
                      </FormItem>
                      <FormItem className="flex items-center gap-3">
                        <FormLabel>{label("female")}</FormLabel>
                        <FormControl>
                          <RadioGroupItem value="female" />
                        </FormControl>
                      </FormItem>
                    </RadioGroup>
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              name="password"
              control={form.control}
              render={({ field }) => (
                <FormItem>
                  <FormControl>
                    <PasswordInput
                      field={field}
                      placeholder={label("password")}
                    />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              name="confirm_password"
              control={form.control}
              render={({ field }) => (
                <FormItem>
                  <FormControl>
                    <PasswordInput
                      field={field}
                      placeholder={label("confirm-password")}
                    />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              name="privacy"
              control={form.control}
              render={({ field }) => (
                <FormItem className="flex text-sm items-end gap-2">
                  <FormLabel
                    className={clsx({
                      "text-red-500": isSubmitted && !field.value,
                    })}
                  >
                    {label("privacy")} &nbsp;
                    <Link
                      href="/terms-and-conditions"
                      className={clsx("text-main underline", {
                        "text-red-500": isSubmitted && !field.value,
                      })}
                    >
                      {t("read-more")}
                    </Link>
                  </FormLabel>
                  <FormControl>
                    <Checkbox
                      checked={field.value}
                      onCheckedChange={field.onChange}
                      className="border-btnColor text-btnColor"
                    />
                  </FormControl>
                </FormItem>
              )}
            />
            {captchaState == 1 && (<ReCAPTCHA
              sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY}
              onChange={(value) => {
                setCaptcha(value);
                setCaptchaError(false); // Clear error if captcha is filled
              }}
            />
            )}
            {captchaError && <p className="text-red-500 text-sm">
              {error('captchaerror')}</p>}

            <SubmitButton
              text={label("create-account")}
              loading={isSubmitting}
            />
            <FormDescription className="text-center">
              {t("have-account")}{" "}
              <Link href="/sign-in-vendor" className="text-main underline">
                {t("sign-in-vendor")}
              </Link>
            </FormDescription>
          </form>
        </Form>
      </section>
    </>
  );
}
