"use client";

import React, { useState, useEffect } from "react";
import { Formik, Field, Form, ErrorMessage } from "formik";
import * as Yup from "yup";
import { useDispatch, useSelector } from "react-redux";
import { sellerRegister, stateLocation } from "../../../api/api";
import { AppDispatch } from "../../../store";
import eye from "../../../assets/eye.svg";
import closedeye from "../../../assets/closedeye.png";
import { toast } from "react-toastify";
import Modal from "../../../components/bayerProfile/pages/components/modal";
import { RootState } from "../../../store";
import Image from "next/image";
import { useRouter } from "next/navigation";

const RegistrationForm: React.FC = () => {
  const dispatch: AppDispatch = useDispatch();
  const router = useRouter();
  const [showPassword, setShowPassword] = useState(false);
  const [password, setPassword] = useState("");
  const [confirmError, setConfirmError] = useState("");
  console.log(confirmError);
  const [confirmPassword, setConfirmPassword] = useState("");
  const [isLoading, setIsLoading] = useState(false);
  const [modalOpen, setModalOpen] = useState(false);
  const [locationLatitude, setLocationLatitude] = useState<any>();
  const [locationLongitude, setLocationLongitude] = useState<any>();
  const [isClient, setIsClient] = useState(false);

  const { stateLocationData, loadings } = useSelector(
    (state: RootState) => state.StateLocationReducer
  );
  const [selectedCountry, setSelectedCountry] = useState<string>("");

  const [requirements, setRequirements] = useState({
    length: false,
    uppercase: false,
    lowercase: false,
    number: false,
    specialChar: false,
  });

  useEffect(() => {
    const routesToPrefetch = [
      "/auth/login",
      "/terms",
      "/privacy",
      "/auth/login",
    ];

    routesToPrefetch.forEach((route) => {
      router.prefetch(route);
    });
  }, [router]);

  useEffect(() => {
    setIsClient(true);
  }, []);

  const handleChangePwd = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;
    setPassword(value);

    setRequirements({
      length: value.length >= 8,
      uppercase: /[A-Z]/.test(value),
      lowercase: /[a-z]/.test(value),
      number: /[0-9]/.test(value),
      specialChar: /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(value),
    });

    if (value !== confirmPassword && confirmPassword) {
      setConfirmError("Passwords must match");
    } else {
      setConfirmError("");
    }
  };

  const handleConfirmPwdChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;
    setConfirmPassword(value);
    if (value !== password) {
      setConfirmError("Passwords must match");
    } else {
      setConfirmError("");
    }
  };

  const isAllRequirementsMet = () => {
    return (
      requirements.length &&
      requirements.uppercase &&
      requirements.lowercase &&
      requirements.number &&
      requirements.specialChar
    );
  };

  const handleCountrySelection = (value: string) => {
    setSelectedCountry(value);
    dispatch(stateLocation(value));
  };

  const fieldName =
    stateLocationData?.data?.type === "states" ? "state" : "province";

  return (
    <div className="max-w-4xl mx-auto bg-white mt-10 rounded-xl p-8 px-8 mb-10">
      <h1 className="text-3xl font-bold mb-4 text-black text-center">
        Register
      </h1>
      <Formik
        initialValues={{
          first_name: "",
          last_name: "",
          email: "",
          password: "",
          confirmPassword: "",
          terms: false,
          privacy: false,
          location_longitude: "",
          location_latitude: "",
          phone: "",
          house_number: "",
          city: "",
          postal_code: "",
          province: "",
          country: "",
          state: "",
        }}
        validationSchema={Yup.object({
          first_name: Yup.string()
            .trim()
            .matches(
              /^[A-Za-z\s]+$/,
              "First name must contain only letters and spaces"
            )
            .max(50, "First name must be at most 50 characters")
            .required("First name is required"),

          last_name: Yup.string()
            .trim()
            .matches(
              /^[A-Za-z\s]+$/,
              "Last name must contain only letters and spaces"
            )
            .max(50, "Last name must be at most 50 characters")
            .required("Last name is required"),

          email: Yup.string()
            .trim()
            .email("Invalid email address")
            .matches(
              /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
              "Invalid email address"
            )
            .required("Email is required"),

          password: Yup.string()
            .trim()
            .min(8, "Password must be at least 8 characters")
            .matches(
              /[A-Z]/,
              "Password must contain at least one uppercase letter"
            )
            .matches(
              /[a-z]/,
              "Password must contain at least one lowercase letter"
            )
            .matches(/[0-9]/, "Password must contain at least one number")
            .matches(
              /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/,
              "Password must contain at least one special character"
            )
            .required("Password is required"),

          confirmPassword: Yup.string()
            .required("Confirm Password is required")
            .oneOf([Yup.ref("password")], "Passwords must match"),

          terms: Yup.boolean()
            .oneOf([true], "You must accept the terms and conditions")
            .required("You must accept the terms and conditions"),

          privacy: Yup.boolean()
            .oneOf([true], "You must accept the privacy policy")
            .required("You must accept the privacy policy"),

          phone: Yup.string().when("country", {
            is: (val: string) => val === "US" || val === "CAN",
            then: (schema) =>
              schema
                .matches(
                  /^(\(\d{3}\)\s*|\d{3}[-\s]?)\d{3}[-\s]?\d{4}$/,
                  "Phone number must be valid (e.g. 123-456-7890)"
                )
                .required("Phone number is required"),
            otherwise: (schema) => schema.required("Phone number is required"),
          }),
          house_number: Yup.string().required("Building/Flat is required"),
          city: Yup.string().required("City is required"),
          postal_code: Yup.string()
            .matches(/^[A-Za-z0-9\-]+$/, "Postal Code must be alphanumeric")
            .required("Postal Code is required"),
          country: Yup.string()
            .required("Country is required")
            .oneOf(["US", "CAN"], "Please select a valid country"),
          ...(stateLocationData?.data?.type == "states"
            ? {
                state: Yup.string().required("State is required"),
                province: Yup.string(),
              }
            : {
                province: Yup.string().required("Province is required"),
                state: Yup.string(),
              }),
        })}
        onSubmit={(values) => {
          setIsLoading(true);

          const normalizedCountry =
            values.country === "US"
              ? "USA"
              : values.country === "CAN"
              ? "Canada"
              : values.country;

          const { terms, privacy, ...rest } = values;

          const updatedValues = {
            ...rest,
            country: normalizedCountry,
            location_latitude: locationLatitude,
            location_longitude: locationLongitude,
          };

          dispatch(sellerRegister(updatedValues)).then((response: any) => {
            if (response.payload.status_code === 201) {
              toast.success("Registered successfully!");
              router.push("/auth/login");
            } else {
              toast.error(
                response.payload?.error || "An unexpected error occurred"
              );
              setIsLoading(false);
            }
          });
        }}
      >
        {(formikProps) => {
          const handleCustomSubmit = async () => {
            formikProps.setTouched(
              Object.keys(formikProps.values).reduce((acc, key) => {
                acc[key] = true;
                return acc;
              }, {} as Record<string, boolean>)
            );

            const errors = await formikProps.validateForm();

            if (Object.keys(errors).length === 0) {
              formikProps.handleSubmit();
            }
          };

          const handleStateChange = (
            event: React.ChangeEvent<HTMLInputElement>,
            stateName: string
          ) => {
            const [latitude, longitude] = event.target.value.split(",");
            formikProps.setFieldValue(fieldName, stateName);
            setLocationLatitude(latitude);
            setLocationLongitude(longitude);
            setModalOpen(false);
          };

          return (
            <Form className="space-y-5 ">
              <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                <div className="text-start relative">
                  <label className="text-lg font-semibold text-black">
                    First Name <span className="text-red-600 text-2xl">*</span>
                  </label>
                  <div className="relative">
                    <Field
                      type="text"
                      id="first_name"
                      name="first_name"
                      className={`block mt-2 w-full border ${
                        formikProps.errors.first_name &&
                        formikProps.touched.first_name
                          ? "border-red-500"
                          : "border-gray-300"
                      } rounded-md p-2 form-input text-black`}
                      placeholder="Full Name"
                    />
                  </div>
                  {formikProps.errors.first_name &&
                    formikProps.touched.first_name && (
                      <span className="text-red-500 text-xs mt-1 block">
                        {formikProps.errors.first_name}
                      </span>
                    )}
                </div>
                <div className="text-start relative">
                  <label className="text-lg font-semibold text-black">
                    Last Name <span className="text-red-600 text-2xl">*</span>
                  </label>
                  <div className="relative">
                    <Field
                      type="text"
                      id="last_name"
                      name="last_name"
                      className={`block mt-2 w-full border ${
                        formikProps.errors.last_name &&
                        formikProps.touched.last_name
                          ? "border-red-500"
                          : "border-gray-300"
                      } rounded-md p-2 form-input text-black`}
                      placeholder="Last Name"
                    />
                  </div>
                  {formikProps.errors.last_name &&
                    formikProps.touched.last_name && (
                      <span className="text-red-500 text-xs mt-1 block">
                        {formikProps.errors.last_name}
                      </span>
                    )}
                </div>

                <div className="text-start relative">
                  <label className="text-lg font-semibold text-black">
                    Phone Number{" "}
                    <span className="text-red-600 text-2xl">*</span>
                  </label>
                  <div className="relative">
                    <Field
                      type="phone"
                      id="phone"
                      name="phone"
                      className={`block mt-2 w-full border ${
                        formikProps.errors.phone && formikProps.touched.phone
                          ? "border-red-500"
                          : "border-gray-300"
                      } rounded-md p-2 form-input text-black`}
                      placeholder="Phone Number"
                    />
                  </div>
                  {formikProps.errors.phone && formikProps.touched.phone && (
                    <span className="text-red-500 text-xs mt-1 block">
                      {formikProps.errors.phone}
                    </span>
                  )}
                </div>

                <div className="text-start relative">
                  <label className="text-lg font-semibold text-black">
                    Email <span className="text-red-600 text-2xl">*</span>
                  </label>
                  <div className="relative">
                    <Field
                      type="email"
                      id="email"
                      name="email"
                      className={`block mt-2 w-full border ${
                        formikProps.errors.email && formikProps.touched.email
                          ? "border-red-500"
                          : "border-gray-300"
                      } rounded-md p-2 form-input text-black`}
                      placeholder="Email Address"
                    />
                  </div>
                  {formikProps.errors.email && formikProps.touched.email && (
                    <span className="text-red-500 text-xs mt-1 block">
                      {formikProps.errors.email}
                    </span>
                  )}
                </div>

                <div className="relative text-start">
                  <label className="text-lg font-semibold text-black">
                    Password <span className="text-red-600 text-2xl">*</span>
                  </label>
                  <Field
                    type={showPassword ? "text" : "password"}
                    id="password"
                    name="password"
                    className={`block mt-2 w-full border text-black ${
                      formikProps.errors.password &&
                      formikProps.touched.password &&
                      !isAllRequirementsMet()
                        ? "border-red-500"
                        : "border-gray-300 "
                    } rounded-md p-2 form-input`}
                    placeholder="Password"
                    value={password}
                    onChange={(e: any) => {
                      formikProps.handleChange(e);
                      handleChangePwd(e);
                    }}
                  />
                  <Image
                    unoptimized
                    src={showPassword ? closedeye : eye} // pass the imported image object, not .src
                    alt="toggle password visibility"
                    onClick={() => setShowPassword(!showPassword)}
                    className={`cursor-pointer absolute w-4 right-[2%] ${
                      showPassword ? "top-[53px]" : "top-[56px]"
                    }`}
                    width={16} // since w-4 means 1rem = 16px width, adjust accordingly
                    height={16} // adjust height proportionally
                    // style={{
                    //   position: "absolute",
                    //   top: "54px",
                    //   right: "2%",
                    //   cursor: "pointer",
                    // }} // optional, or use className
                  />
                  {formikProps.errors.password &&
                    formikProps.touched.password && (
                      <span className="text-red-500 text-xs mt-1 block">
                        {formikProps.errors.password}
                      </span>
                    )}
                </div>

                <div className="text-start">
                  <label className="text-lg font-semibold text-black">
                    Confirm Password{" "}
                    <span className="text-red-600 text-2xl">*</span>
                  </label>
                  <Field
                    type="password"
                    id="confirmPassword"
                    name="confirmPassword"
                    className={`block w-full border mt-2 text-black ${
                      formikProps.errors.confirmPassword &&
                      formikProps.touched.confirmPassword
                        ? "border-red-500"
                        : "border-gray-300"
                    } rounded-md p-2 form-input`}
                    placeholder="Confirm Password"
                    onChange={(e: any) => {
                      formikProps.handleChange(e);
                      handleConfirmPwdChange(e);
                    }}
                    value={confirmPassword}
                  />
                  {formikProps.errors.confirmPassword &&
                    formikProps.touched.confirmPassword && (
                      <span className="text-red-500 text-xs mt-1 block">
                        {formikProps.errors.confirmPassword}
                      </span>
                    )}
                </div>

                <div className=" flex flex-wrap gap-x-4 gap-y-2 font-semibold text-sm">
                  <div className="flex items-center min-w-[115px] gap-1 text-black">
                    <input
                      type="checkbox"
                      checked={requirements.length}
                      disabled
                      className="h-4 w-4 rounded border-gray-400 text-black "
                    />{" "}
                    8 Characters
                  </div>
                  <div className="flex items-center gap-1 min-w-[115px] text-black">
                    <input
                      type="checkbox"
                      checked={requirements.lowercase}
                      disabled
                      className="h-4 w-4 rounded border-gray-400 text-black "
                    />{" "}
                    Lowercase
                  </div>
                  <div className="flex items-center gap-1 min-w-[115px] text-black">
                    <input
                      type="checkbox"
                      checked={requirements.specialChar}
                      disabled
                      className="h-4 w-4 rounded border-gray-400 text-black "
                    />{" "}
                    Special Character
                  </div>
                  <div className="flex items-center gap-1 min-w-[115px] text-black">
                    <input
                      type="checkbox"
                      checked={requirements.uppercase}
                      disabled
                      className="h-4 w-4 rounded border-gray-400 text-black "
                    />{" "}
                    Uppercase
                  </div>
                  <div className="flex items-center gap-1 min-w-[115px] text-black">
                    <input
                      type="checkbox"
                      checked={requirements.number}
                      disabled
                      className="h-4 w-4 rounded border-gray-400 text-black "
                    />{" "}
                    Number
                  </div>
                </div>
              </div>
              <div className="">
                <div>
                  <label className="text-lg font-semibold text-black text-start block">
                    Apt. No. -Street No., Street name{" "}
                    <span className="text-red-600 text-2xl">*</span>
                  </label>
                  <Field
                    name="house_number"
                    type="text"
                    placeholder="House Number"
                    className={`w-full p-2 mt-2 mb-1 border border-gray-300 rounded text-black ${
                      formikProps.errors.house_number &&
                      formikProps.touched.house_number
                        ? "border-red-500"
                        : "border-gray-300"
                    } `}
                  />
                  <ErrorMessage
                    name="house_number"
                    component="div"
                    className="text-red-500 text-xs text-left"
                  />
                </div>
                <div className="grid grid-cols-1 mt-2 md:grid-cols-2 gap-4">
                  <div>
                    <label className="block text-lg text-start font-semibold text-black ">
                      City <span className="text-red-600 text-2xl">*</span>
                    </label>
                    <Field
                      name="city"
                      type="text"
                      placeholder="City"
                      className={`w-full p-2 border mt-2 mb-1 border-gray-300 rounded-md text-black ${
                        formikProps.errors.city && formikProps.touched.city
                          ? "border-red-500"
                          : "border-gray-300"
                      } `}
                    />
                    <ErrorMessage
                      name="city"
                      component="div"
                      className="text-red-500 text-xs text-left"
                    />
                  </div>

                  <div>
                    <label className="block text-lg text-start font-semibold text-black">
                      Country <span className="text-red-600 text-2xl">*</span>
                    </label>
                    <Field
                      as="select"
                      id="country"
                      name="country"
                      value={selectedCountry}
                      onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
                        const value = e.target.value;
                        setSelectedCountry(value);
                        formikProps.setFieldValue("country", value);
                        formikProps.setFieldValue(fieldName, "");
                        handleCountrySelection(value);

                        if (value === "") {
                          e.target.classList.add(
                            "text-gray-500",
                            "font-normal"
                          );
                          e.target.classList.remove(
                            "text-black",
                            "font-semibold"
                          );
                        } else {
                          e.target.classList.remove(
                            "text-gray-500",
                            "font-normal"
                          );
                          e.target.classList.add("text-black", "font-semibold");
                        }
                      }}
                      className={`w-full mt-2 border rounded-md  border-gray-300 focus:ring-blue-500 focus:border-blue-500 block p-2
                       ${
                         selectedCountry === ""
                           ? "text-gray-500 font-normal"
                           : "text-black font-semibold"
                       }`}
                    >
                      <option value="" disabled>
                        Select a country
                      </option>
                      <option value="US">USA</option>
                      <option value="CAN">Canada</option>
                    </Field>

                    <ErrorMessage
                      name="country"
                      component="div"
                      className="text-red-500 text-xs text-left"
                    />
                  </div>

                  {isClient && (
                    <div>
                      <label className="block text-lg text-start font-semibold text-black ">
                        State/Province{" "}
                        <span className="text-red-600 text-2xl">*</span>
                      </label>
                      <Field
                        name={fieldName}
                        type="text"
                        readOnly
                        placeholder="State/Province"
                        onClick={() => selectedCountry && setModalOpen(true)}
                        disabled={!selectedCountry}
                        className={`w-full p-2 border mt-2 mb-1 rounded-md text-black ${
                          !selectedCountry
                            ? "bg-gray-100 cursor-not-allowed"
                            : ""
                        } ${
                          formikProps.errors[fieldName] &&
                          formikProps.touched[fieldName]
                            ? "border-red-500"
                            : "border-gray-300"
                        }`}
                      />
                      <ErrorMessage
                        name={fieldName}
                        component="div"
                        className="text-red-500 text-xs text-left"
                      />
                      <Modal
                        isOpen={modalOpen}
                        onClose={() => setModalOpen(false)}
                        title={
                          loadings
                            ? "..."
                            : `Select a ${
                                stateLocationData?.data?.type === "states"
                                  ? "State"
                                  : "Province"
                              }`
                        }
                      >
                        {loadings ? (
                          <p className="text-black">Loading...</p>
                        ) : (
                          <form>
                            <div className="grid grid-cols-2 gap-4 text-black">
                              {stateLocationData?.data?.list.map(
                                (state: any) => (
                                  <label
                                    key={state.code}
                                    className="flex items-center gap-4 cursor-pointer"
                                  >
                                    <input
                                      type="radio"
                                      name="state"
                                      value={`${state.latitude},${state.longitude}`}
                                      onChange={(e) =>
                                        handleStateChange(e, state.name)
                                      }
                                      className="form-radio cursor-pointer"
                                    />
                                    <span className="text-black text-start cursor-pointer">
                                      {state.name}
                                    </span>
                                  </label>
                                )
                              )}
                            </div>
                          </form>
                        )}
                        {/* <button
                          onClick={() => setModalOpen(false)}
                          className="mt-4 px-4 py-1 bg-yellow-500 cursor-pointer text-black rounded "
                        >
                          Close Modal
                        </button> */}
                      </Modal>
                    </div>
                  )}

                  <div>
                    <label className="block text-lg text-start font-semibold text-black ">
                      Postal Code{" "}
                      <span className="text-red-600 text-2xl">*</span>
                    </label>
                    <Field
                      name="postal_code"
                      type="text"
                      placeholder="Postal Code"
                      className={`w-full p-2 border border-gray-300 mt-2 rounded-md text-black ${
                        formikProps.errors.postal_code &&
                        formikProps.touched.postal_code
                          ? "border-red-500"
                          : "border-gray-300"
                      } `}
                    />
                    <ErrorMessage
                      name="postal_code"
                      component="div"
                      className="text-red-500 text-xs text-left"
                    />
                  </div>
                </div>
              </div>

              <div className="font-semibold text-sm w-full md:w-7/12">
                <div className="flex gap-1 justify-start ">
                  <Field
                    type="checkbox"
                    name="terms"
                    className="h-4 w-4 rounded border-gray-400 text-black mt-1"
                  />
                  <p className="text-black text-start ">
                    I understand and agree to RESERVITT{" "}
                    <span
                      onClick={() => router.push("/terms")}
                      // href={"/terms"}
                      className="text-blue-700 cursor-pointer"
                    >
                      Terms of Use
                    </span>
                    .
                  </p>
                </div>
                <ErrorMessage
                  name="terms"
                  component="div"
                  className="text-red-500 text-left text-xs "
                />
                <div className="flex gap-1 mt-2">
                  <Field
                    type="checkbox"
                    name="privacy"
                    className="h-4 w-4 rounded border-gray-400 text-black mt-1"
                  />
                  <p className="text-black text-start ">
                    I understand and agree that my personal information will be
                    processed in accordance with RESERVITT{" "}
                    <span
                      onClick={() => router.push("/privacy")}
                      className="text-blue-700 cursor-pointer"
                    >
                      Privacy Policy
                    </span>
                    .
                  </p>
                </div>

                <ErrorMessage
                  name="privacy"
                  component="div"
                  className="text-red-500 text-xs text-left"
                />

                <div className="mt-4">
                  <button
                    type="button"
                    onClick={handleCustomSubmit}
                    className="custom-button text-black w-full cursor-pointer"
                  >
                    {isLoading ? (
                      <span className="loader absolute"></span>
                    ) : (
                      "Register"
                    )}
                  </button>
                </div>
                <p className="text-center text-sm mt-2 font-semibold text-black">
                  Already have an account?{" "}
                  <span
                    className="text-blue-600 cursor-pointer"
                    onClick={() => router.push("/auth/login")}
                  >
                    Log in
                  </span>
                </p>
              </div>
            </Form>
          );
        }}
      </Formik>
    </div>
  );
};

export default RegistrationForm;
