import React, { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import { object, string, SchemaOf } from "yup";
import Image from "next/image";
import { mapboxAddressActionUrl, replaceCapitalLettersAndUnderscores } from "@/helpers/projectHelper";

import {
  getCustomersparsonalDetails,
  customersparsonalDetailsUpdate,
} from "@/services/profile";
import { useSession } from "next-auth/react";
import { ToastContainer, toast } from "react-toastify";
import { Form, FormGroup, FormLabel, FormControl } from "react-bootstrap";
import { ScaleLoader } from "react-spinners";
import { useUser } from "@/components/Context/UserContext";
import useAuthProvider from "@/useAuthProvider";
interface FormData {
  firstName: string;
  lastName: string;
  business_email: string;
  company_name: string;
  billing_address: string;
  current_address: string;
  phone_number: number;
  currentpassword: any;
  confirmpassword: any;
  newpassword: any;
}

const schema: SchemaOf<FormData> = object().shape({
  firstName: string()
    .required("First name is required")
    .min(2, "Minimum 2 characters required")
    .max(20, "Maximum 20 characters allowed"),
  lastName: string()
    .required("Last name is required")
    .min(2, "Minimum 2 characters required")
    .max(20, "Maximum 20 characters allowed"),
  business_email: string()
    .email("Please enter a valid email address")
    .required("Email is required"),
  company_name: string()
    .required("Company name is required")
    .min(2, "Minimum 2 characters required")
    .max(50, "Maximum 50 characters allowed"),
  billing_address: string()
    .required("Billing address is required")
    .min(2, "Minimum 2 characters required")
    .max(200, "Maximum 200 characters allowed"),
  current_address: string()
    .required("Current address is required")
    .min(2, "Minimum 2 characters required")
    .max(200, "Maximum 200 characters allowed"),

    phone_number: string()
    .required("Phone number is required")
    .test(
      "len",
      "Phone number must be 10 digits",
      (val) => {
        const cleaned = val.replace(/\D/g, "");
        return cleaned.length === 10; // Check for 10  digits
      }
    ),
  currentpassword: string().test({
    name: "currentpassword",
    message: "New password is required",
    test: function (value) {
      const newpassword = this.parent.newpassword;
      return newpassword ? !!value : true;
    },
  }),

  newpassword: string().test({
    name: "newpassword",
    message: "New password is required",
    test: function (value) {
      const currentPassword = this.parent.currentpassword;
      return currentPassword ? !!value : true;
    },
  }),

  confirmpassword: string().test(
    "passwords-match",
    "The passwords do not match",
    function (value) {
      return this.parent.newpassword === value;
    },
  ),
});

function CustomerPersonalDetails() {
  const { data } = useSession();
  const { Permission: userData } = useAuthProvider();

  const [isloading, setIsloading] = useState(true);
  const token = data?.user?.image;
  const userId = data?.user?.id;
  const [customeAddressError, setCustomeAddressError] = useState("");
  const [selectedOriginDestination, setSelectedOriginDestination] =
    useState("");
  const [selectedbillingDestination, setselectedbillingDestination] =
    useState("");
  const [searchedSuggestions, setSearchSuggestions] = useState([]);
  const [searchedbillingSuggestions, setSearchbillingSuggestions] = useState(
    [],
  );
  const [MapState, setMapState] = useState()
  const [MapCity, setMapCity] = useState()
  const { updateUserName, updatelastName } = useUser();
  const [buttonDisable, setButtonDisable] = useState(false);
  const [firstname, setFirstName] = useState("");
  const [lastName, setLastName] = useState("");
  const [companyName, setcompanyName] = useState("");
  const [businessEmail, setbusinessEmail] = useState("");
  const [number, setNumber] = useState("");
  const [checked, setChecked] = useState(false);

  const [showPassword, setShowPassword] = useState(false);
  const [showNewPassword, setNewShowPassword] = useState(false);
  const [showConfirmPassword, setShowConfirmPassword] = useState(false);
  const [customerusername, setCustomerUsername] = useState("");
  const setFieldValueAndState = (
    field: string,
    stateSetter: (value: string) => void,
  ) => {
    return (e: React.ChangeEvent<HTMLInputElement>) => {
      const value = e.target.value;
      setValue(field, value);
      stateSetter(value);
    };
  };

  function capitalizeFirstLetter(item: string) {
    return item?.charAt(0)?.toUpperCase() + item?.slice(1)?.toLowerCase();
  }

  function numberformat(phoneNumberString: string) {
    const phoneNumberParts = phoneNumberString.split("-");
    return parseInt(
      phoneNumberParts[0] + phoneNumberParts[1] + phoneNumberParts[2],
    );
  }

  const handleFieldChange = (
    field: string,
    stateSetter: (value: string) => void,
  ) => {
    return {
      onKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => {
        if (e.which === 32 && e.target.value.trim() === "") {
          e.preventDefault();
        }
      },
      placeholder: replaceCapitalLettersAndUnderscores(field),
      type: "text",
      value: getFieldState(field),
      className: `form-control ${errors[field] ? "is-invalid" : ""}`,
      id: field,
      ...register(field, {
        onChange: setFieldValueAndState(field, stateSetter),
      }),
    };
  };

  const getFieldState = (field: string) => {
    switch (field) {
      case "firstName":
        return firstname;
      case "lastName":
        return lastName;
      case "business_email":
        return businessEmail;
      case "phone_number":
        return number;
      default:
        return companyName;
    }
  };

  function formatPhoneNumber(input) {
    const cleaned = input?.replace(/\D/g, "");
  
    if (cleaned?.length === 10) {
      return cleaned?.replace(/(\d{3})(\d{3})(\d{4})/, "$1-$2-$3");
    }
  
    return input;
  }
  
  const {
    handleSubmit,
    setValue,
    register,
    formState: { errors },
  } = useForm<FormData>({
    resolver: yupResolver(schema),
  });

  useEffect(() => {
    getCustomersparsonalDetails(token, userId).then((response) => {
      setIsloading(true);
      if (response?.status === "success") {
        const {
          billing_address: BillingAddress,
          billing_address1: currentaddress,
          first_name: firstName,
          last_name: lastNameuser,
          business_email: businessUserEmail,
          business_company: companyUserName,
          phone,
          username
        } = response.data;

        const parts = currentaddress?.split(",") ?? [];
        const city = parts[0]?.trim() ?? "";
        const stateAndZip = parts.slice(1).join(",").trim();
        const lastSpaceIndex = stateAndZip.lastIndexOf(" ");
        const state = stateAndZip.slice(0, lastSpaceIndex).trim();

        const formattedPhoneNumber = formatPhoneNumber(phone);

        setMapCity(city);
        setMapState(state);
        setValue("firstName", capitalizeFirstLetter(firstName));
        setValue("lastName", capitalizeFirstLetter(lastNameuser));
        setValue("business_email", businessUserEmail);
        setValue("billing_address", BillingAddress || "");
        setValue("current_address", currentaddress || "");
        setValue("company_name", companyUserName);
        setValue("phone_number", formattedPhoneNumber);
        setNumber(formattedPhoneNumber);
        setFirstName(firstName);
        setLastName(lastNameuser);
        setbusinessEmail(businessUserEmail);
        setCustomerUsername(username);
        setselectedbillingDestination(BillingAddress || "");
        setSelectedOriginDestination(currentaddress || "");
        setcompanyName(companyUserName);
        setIsloading(false);
      } else {
        setIsloading(false);
      }

    });
  }, [token, isloading]);

  const spacehandler = (event) => {
    if (event.which === 32 && event.target.value.trim() === "") {
      event.preventDefault();
    }
  };

  const spaceblockhandler = (event) => {
    const charCode = event.which;
    if (
      !(
        (charCode >= 65 && charCode <= 90) ||
        (charCode >= 97 && charCode <= 122)
      )
    ) {
      event.preventDefault();
    }
  };

  function bindSelectedAddress(item: SelectAddressType) {
    setValue("current_address", item.name);
    setSearchSuggestions([]);
    setSelectedOriginDestination(item.name);
    setCustomeAddressError("");
  }

  function bindbillingSelectedAddress(item: SelectAddressType) {
    setValue("billing_address", item.name);
    setSearchbillingSuggestions([]);
    setselectedbillingDestination(item.name);
    setCustomeAddressError("");
  }

  const parseContextData = (contextData) => {
    let stateCode = null;
    let postalCode = null;
    let city = null;
    let state = null;

    contextData?.forEach((context) => {
      if (context?.id?.includes("region")) {
        stateCode = context?.short_code;
        state = context?.text;
      }
      if (context?.id.includes("postcode")) {
        postalCode = context?.text;
      }
      if (context?.id.includes("place")) {
        city = context?.text;
      }
    });

    return { stateCode, postalCode, city, state };
  };

  const formatSuggestions = (features) => {
    return features.reduce((suggestionsArray, item) => {
      const { stateCode, postalCode, city, state } = parseContextData(item?.context);
      if (item?.place_type?.[0] !== "country" && stateCode !== null) {
        suggestionsArray?.push({
          name: item?.place_name,
          lat: item?.center[1],
          lng: item.center[0],
          state_code: stateCode,
          post_code: postalCode,
          state: state,
          city: city,
        });
      }
      return suggestionsArray;
    }, []);
  };

  const handleAddressChange = async (
    event,
    setAddressValue,
    setSuggestions
  ) => {
    try {
      const searchedString = event.target.value;
      if (searchedString.length > 2) {
        const searchResponse = await fetch(mapboxAddressActionUrl(searchedString));
        const searchedResponseData = await searchResponse?.json();
        const suggestionsArray = formatSuggestions(searchedResponseData.features);
        setSuggestions(suggestionsArray);
      } else {
        setSuggestions([]);
      }
    } catch (error) {
      setSuggestions([]);
    }
  };

  const sameAddressHandler = (e) => {
    setChecked(e.target.checked);
    if (checked) {
      setselectedbillingDestination("");
      setValue("billing_address", "");
    } else {
      setValue("billing_address", selectedOriginDestination);
      setselectedbillingDestination(selectedOriginDestination);
    }
  };

  const onSubmit = async (FormData: any) => {
    setButtonDisable(true);
    setIsloading(true);
    const response = await customersparsonalDetailsUpdate(token, {
      dispatcher_id: userId,
      first_name: FormData.firstName,
      last_name: FormData.lastName,
      company_name: FormData.company_name,
      email: FormData.business_email,
      current_address: FormData.current_address,
      billing_address: FormData.billing_address,
      phone: numberformat(FormData.phone_number),
      state: MapState,
      city: MapCity,
      current_password: FormData.currentpassword,
      new_password: FormData.newpassword,
    });
    updateUserName(FormData.firstName);
    updatelastName(FormData.lastName);
    if (response.status == "success") {

      getCustomersparsonalDetails(token, userId)
      setButtonDisable(false);
      setIsloading(false);
      toast.success(response?.message, {
        position: toast.POSITION.TOP_CENTER,
      });
      setValue("currentpassword", "");
      setValue("newpassword", "");
      setValue("confirmpassword", "");
    } else {
      setButtonDisable(false);
      setIsloading(false);
      toast.error(response?.message, {
        position: toast.POSITION.TOP_CENTER,
      });
      setValue("currentpassword", "");
      setValue("newpassword", "");
      setValue("confirmpassword", "");
    }
  };

  return (
    <div>
      {isloading && (
        <div id="loader_table">
          <ScaleLoader color="#3180f3" className="table_loader" />
        </div>
      )}
      <ToastContainer />
      <div
        className="tab-pane fade show active"
        id="pills-home"
        role="tabpanel"
        aria-labelledby="pills-home-tab"
      >
        <div className="tab_content">
          <div className="edit_btn_block ">
            <i
              className="fa fa-pencil-square-o"
              aria-hidden="true"
              title="Edit fields"
            />
          </div>
          <form className="row g-4" onSubmit={handleSubmit(onSubmit)}>
            <div className="col-md-4 mb-3">
              <FormLabel htmlFor="firstName">First Name:</FormLabel>
              <FormControl
                onKeyPress={spaceblockhandler}
                {...handleFieldChange("firstName", setFirstName)}
              />
              <p className="text-danger">{errors?.firstName?.message}</p>
            </div>
            <div className="col-md-4 mb-3">
              <FormLabel htmlFor="lastName">Last Name:</FormLabel>
              <FormControl
                onKeyPress={spaceblockhandler}
                {...handleFieldChange("lastName", setLastName)}
              />
              <p className="text-danger">{errors?.lastName?.message}</p>
            </div>

            <div className="col-md-4 mb-3  ">
              <FormLabel htmlFor="business_email">Email:</FormLabel>
              <FormControl
                disabled
                readOnly
                {...handleFieldChange("business_email", setbusinessEmail)}
              />
              <p className="text-danger">{errors?.business_email?.message}</p>
            </div>
            <div className="col-md-4 mb-3  ">
              <FormLabel htmlFor="username">Username:</FormLabel>
              <FormControl
                disabled
                type="text"
                id={"username"}
                value={customerusername}
                placeholder="Username"
              />
            </div>
            <div className="col-md-4 mb-3" style={{ display: "grid" }}>
              <FormLabel htmlFor="Phone number">Phone Number:</FormLabel>
              <FormControl
                type="number"
                disabled={phonenumDisable(data)}
                value={formatPhoneNumber(number)}
                {...handleFieldChange("phone_number", setNumber)}
                mask="999-999-9999"
                placeholder="xxx-xxx-xxxx"
                {...register("phone_number")}
                className={phoneClassName(errors)}
              />
              <p className="text-danger">{errors?.phone_number?.message}</p>
            </div>
            <div className="col-md-4 mb-3  ">
              <FormLabel htmlFor="company_name">Company Name:</FormLabel>
              <FormControl
                disabled={phonenumDisable(data)}
                {...handleFieldChange("company_name", setcompanyName)}
              />
              <p className="text-danger">{errors?.company_name?.message}</p>
            </div>
            <div className="col-md-4 mb-3  ">
              <FormLabel htmlFor="current_address">Current Address:</FormLabel>
              <div className="address-autocomplete-parent">
                <FormControl
                  disabled={phonenumDisable(data)}
                  {...register("current_address")}
                  className={
                    addressClass(selectedOriginDestination, errors, customeAddressError)
                  }
                  onKeyDown={spacehandler}
                  id="origin_destination"
                  placeholder="Current address"
                  autoComplete="off"
                  onInput={(e) => {
                    e.preventDefault();
                    handleAddressChange(
                      e,
                      (value) => setSelectedOriginDestination(value),
                      setSearchSuggestions,
                    );
                  }}
                  value={selectedOriginDestination}
                  onChange={(e) => setSelectedOriginDestination(e.target.value)}
                />
                <div className={suggestionClass(searchedSuggestions)}>
                  <ul className="city-listing-css" style={{ zIndex: 99 }}>
                    {searchedSuggestions.map((item: any) => (
                      <li
                        key={item.name}
                        onKeyDown={spacehandler}
                        onClick={() => {
                          bindSelectedAddress({
                            name: item.name,
                            lat: item.lat,
                            lng: item.lng,
                            state_code: item.state_code,
                            post_code: item.post_code,
                          });
                          setMapState(item.state)
                          setMapCity(item.city)
                          setSelectedOriginDestination(item.name);
                        }}
                      >
                        <div className="mb-3">{item?.name}</div>
                      </li>
                    ))}
                  </ul>
                </div>
                <Form.Control.Feedback type="invalid">
                  {suggestionError(selectedOriginDestination, errors, customeAddressError)}
                </Form.Control.Feedback>
              </div>
            </div>

            <div className="col-md-4 mb-3 mt-1">
              <div className="form-check-inline">
                <label className="form-check-label">
                  <input
                    type="checkbox"
                    className="form-check-input"
                    checked={checked}
                    onChange={sameAddressHandler}
                  />
                  &nbsp;Same as Current address :
                </label>
              </div>

              <div className="auto_fill">
                <FormLabel htmlFor="billing_address">
                  Billing Address:
                </FormLabel>
                <div className="address-autocomplete-parent">
                  <FormControl
                    disabled={phonenumDisable(data)}
                    {...register("billing_address")}
                    className={
                      billingClass(selectedbillingDestination, errors, customeAddressError)
                    }
                    id="origin_destination"
                    placeholder="Billing address"
                    autoComplete="off"
                    onKeyDown={spacehandler}
                    onInput={(e) => {
                      e.preventDefault();
                      handleAddressChange(
                        e,
                        (value) => setselectedbillingDestination(value),
                        setSearchbillingSuggestions,
                      );
                    }}
                    value={selectedbillingDestination}
                    onChange={(e) => {
                      setselectedbillingDestination(e.target.value);
                      setCustomeAddressError("");
                    }}
                  />

                  <div
                    className={
                      searchedbillingSuggestions.length < 1 ? "d-none" : ""
                    }
                  >
                    <ul className="city-listing-css" style={{ zIndex: 99 }}>
                      {searchedbillingSuggestions.map((item: any) => (
                        <li
                          key={item.name}
                          onClick={() => {
                            bindbillingSelectedAddress({
                              name: item.name,
                              lat: item.lat,
                              lng: item.lng,
                              state_code: item.state_code,
                              post_code: item.post_code,
                            });
                            setselectedbillingDestination(item.name);
                          }}
                        >
                          <div className="mb-3">{item?.name}</div>
                        </li>
                      ))}
                    </ul>
                  </div>
                  <Form.Control.Feedback type="invalid">
                    {(selectedbillingDestination === "" &&
                      errors.billing_address?.message?.toString()) ??
                      customeAddressError}
                  </Form.Control.Feedback>
                </div>
              </div>
            </div>

            <div className="col-md-4 mb-3 mt-4">
              <FormLabel htmlFor="currentpassword">Current Password:</FormLabel>
              <FormGroup className="form-group">
                <CustomFormControl
                  state={showPassword}
                  errors={errors}
                  register={register}
                  id="currentpassword"
                  placeHolder="Enter current password"
                />
                <PasswordVisibilityImage
                  alt="currentpassword"
                  setState={setShowPassword}
                  state={showPassword}
                  errors={errors}
                  field="currentpassword"
                />
                <Form.Control.Feedback type="invalid">
                  {errors.currentpassword?.message?.toString()}
                </Form.Control.Feedback>
              </FormGroup>
            </div>

            <div className="col-md-4 mb-3 mt-0">
              <FormLabel htmlFor="newpassword">New Password:</FormLabel>
              <FormGroup className="form-group">
                <CustomFormControl
                  state={showNewPassword}
                  errors={errors}
                  register={register}
                  id="newpassword"
                  placeHolder="Enter new password"
                />
                <PasswordVisibilityImage
                  alt="newpassword"
                  setState={setNewShowPassword}
                  state={showNewPassword}
                  errors={errors}
                  field="newpassword"
                />
                <Form.Control.Feedback type="invalid">
                  {errors.newpassword?.message?.toString()}
                </Form.Control.Feedback>
              </FormGroup>
            </div>

            <div className="col-md-4 mb-3 mt-0">
              <FormLabel htmlFor="confirmpassword">Confirm password:</FormLabel>
              <FormGroup className="form-group">
                <CustomFormControl
                  state={showConfirmPassword}
                  errors={errors}
                  register={register}
                  id="confirmpassword"
                  placeHolder="Enter confirm password"
                />
                <PasswordVisibilityImage
                  alt="confirmpassword"
                  setState={setShowConfirmPassword}
                  state={showConfirmPassword}
                  errors={errors}
                  field="confirmpassword"
                />
                <Form.Control.Feedback type="invalid">
                  {errors.confirmpassword?.message?.toString()}
                </Form.Control.Feedback>
              </FormGroup>
            </div>
            {userData?.EditPersonalDetailstab ?
              <div className="col-12 but-center">
                <button
                  disabled={buttonDisable}
                  type="submit"
                  className="btn btn-primary"
                >
                  Save
                </button>
              </div>
              : ""}
          </form>
        </div>
      </div>
    </div>
  );
}

export default CustomerPersonalDetails;

interface PropTypes {
  type?: string;
  id: string;
  placeHolder: string;
  register: any;
  errors: any;
  onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void; // Add this line
}

interface CustomPropType extends PropTypes {
  state: boolean;
}

function billingClass(selectedbillingDestination: string, errors, customeAddressError: string): string | undefined {
  return ((selectedbillingDestination === "" &&
    errors.billing_address) ||
    customeAddressError) &&
    "is-invalid";
}

function suggestionError(selectedOriginDestination: string, errors, customeAddressError: string): React.ReactNode {
  return selectedOriginDestination === "" &&
    (errors.current_address?.message?.toString() ??
      customeAddressError);
}

function suggestionClass(searchedSuggestions: never[]): string | undefined {
  return searchedSuggestions.length < 1 ? "d-none" : "";
}

function addressClass(selectedOriginDestination: string, errors, customeAddressError: string): string | undefined {
  return ((selectedOriginDestination === "" &&
    errors.current_address) ||
    customeAddressError) &&
    "is-invalid";
}

function phoneClassName(errors): string | undefined {
  return errors.phone_number && "is-invalid";
}

function phonenumDisable(data): boolean | undefined {
  return data?.user?.role_id === 3 || data?.user?.role_id === 5 ? true : false;
}

function FormControlComponent({
  type,
  id,
  placeHolder,
  register,
  errors,
}: PropTypes) {
  return (
    <FormControl
      type={type}
      {...register(id)}
      id={id}
      autoComplete="off"
      placeholder={placeHolder}
      className={errors[id] && "is-invalid"}
    />
  );
}

function CustomFormControl({
  state,
  id,
  register,
  placeHolder,
  errors,
  onChange,
}: CustomPropType) {
  return (
    <FormControl
      type={state ? "text" : "password"}
      {...register(id)}
      id={id}
      autoComplete="off"
      placeholder={placeHolder}
      onChange={onChange}
      className={errors[id] ? "is-invalid" : ""}
    />
  );
}

interface ImgProps {
  field: string;
  errors: any;
  state: boolean;
  setState: any;
  alt: string;
}

function PasswordVisibilityImage(props: ImgProps) {
  const { field, errors, state, setState, alt } = { ...props };
  return (
    <span
      className={`icon_input`}
      style={{
        position: "absolute",
        top: "6px",
        right: `${errors[field] ? "20px" : "0px"}`,
      }}
    >
      <Image
        className="passwordIcon  show-hide-icon"
        onClick={() => setState(!state)}
        alt={alt}
        width={20}
        height={20}
        src={state ? "/images/pass.png" : "/images/hidepassword.png"}
      />
    </span>
  );
}
