"use client";
import React, { useEffect, useMemo, useRef, useState } from "react";
import {
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/shared/ui/form";
import { useFormContext } from "react-hook-form";
import PhoneInput, { PhoneInputProps } from "react-phone-input-2";
import "react-phone-input-2/lib/style.css";
import { useTranslations } from "next-intl";
import { cn } from "@/utils/helpers";
import { CountryPhoneCodes } from "@/public/countries/country-phone-code";
import { Skeleton } from "../ui/skeleton";
import axiosInstanceClient from "@/utils/axiosClient";
import UseSession from "../../hooks/UseSession";

interface Country {
  name: string;
  shortName: string;
  dialCode: string;
  phoneLimit: number;
  flag: string;
}
interface FormPhoneNumberProps {
  label?: string;
  showRequired?: boolean;
  country?: string;
  disabled?: boolean;
  className?: string;
  name: string;
  PhoneNumberProps?: PhoneInputProps;
}

const FormPhoneNumber: React.FC<FormPhoneNumberProps> = ({
  label,
  name,
  showRequired = true,
  country = "sa",
  disabled = false,
  className = "",
  PhoneNumberProps,
}) => {
  const form = useFormContext();
  const t = useTranslations("LABELS");
  const inputRef = useRef<HTMLInputElement>(null);
  const session = UseSession();
  const phone_code = name + "_code";
  const phone_limit = name + "_limit";

  const {
    setValue,
    getValues,
    formState: { errors },
    trigger,
  } = form;
  const [countries, setCountries] = useState<Country[]>([]);
  const [loading, setLoading] = useState(false);
  const [defaultCountry, setDefaultCountry] = useState<string>(country);
  const [dialCode, setDialCode] = useState<string>("");
  const [phone, setPhone] = useState(``);
  useEffect(() => {
    const fetchCountries = async () => {
      try {
        setLoading(true);
        const { data } = await axiosInstanceClient.get(
          "guest/countries?paginate=0",
        );

        const filteredCountries = data?.data?.filter((country: any) =>
          CountryPhoneCodes.some(
            (item) =>
              item.dial_code.replace("+", "") === String(country.phone_code),
          ),
        );

        const formattedCountries: Country[] = filteredCountries.map(
          (country: any) => {
            const matched = CountryPhoneCodes.find(
              (item) =>
                item.dial_code.replace("+", "") === String(country.phone_code),
            );
            return {
              name: country.name, // ✅ Your API's country name (can be Arabic/English etc.)
              shortName:
                matched?.code?.toLowerCase() ||
                country.short_name?.toLowerCase(),
              dialCode: String(country.phone_code),
              flag: country.flag?.media,
              phoneLimit: Number(country.phone_length) || 9,
            };
          },
        );

        setCountries(formattedCountries);

        // If form already has a dial code value — sync it
        if (getValues(phone_code)) {
          const foundCountry = formattedCountries.find(
            (c) => c.dialCode === getValues(phone_code),
          );
          if (foundCountry) {
            setDefaultCountry(foundCountry.shortName);
            setDialCode(`+${foundCountry.dialCode}`);
            setPhone(`+${foundCountry.dialCode}${getValues(name) || ""}`);
            setValue(phone_limit, foundCountry.phoneLimit);
          }
        } else {
          // Otherwise pick the first country as default
          const fallback = formattedCountries[0] || {
            shortName: "sa",
            dialCode: "966",
            phoneLimit: 9,
          };
          setDefaultCountry(fallback.shortName);
          setDialCode(`+${fallback.dialCode}`);
          setPhone(`+${fallback.dialCode}${getValues(name) || ""}`);
          setValue(phone_limit, fallback.phoneLimit);
        }
      } catch (error) {
        console.error("Error fetching countries:", error);
        // fallback values
        setDefaultCountry("sa");
        setDialCode("+966");
        setPhone("+966");
        setValue(phone_limit, 9);
      } finally {
        setLoading(false);
      }
    };

    fetchCountries();
  }, [session]);

  // ✅ Build localization map for country names (ISO2 -> name)
  const localization = useMemo(() => {
    const map: Record<string, string> = {};
    for (const c of countries) {
      if (c.shortName) {
        map[c.shortName] = c.name;
      }
    }
    return map;
  }, [countries]);

  // ✅ Handle phone number change
  const handlePhoneChange = (
    value: string,
    countryData: { dialCode: string; countryCode: string },
  ) => {
    const newDial = `${countryData.dialCode}`;
    setDialCode(`+${countryData.dialCode}`);

    let currentValue = value;
    if (!currentValue.startsWith(newDial)) {
      currentValue = newDial + currentValue.replace(/^\+?\d+/, "");
    }

    const numberOnly = currentValue.slice(newDial.length).trim();
    setValue(name, numberOnly, { shouldValidate: true });
    setValue(phone_code, countryData.dialCode, { shouldValidate: true });

    const foundCountry = countries.find(
      (c) => c.dialCode === countryData.dialCode,
    );
    if (foundCountry) {
      setValue(phone_limit, foundCountry.phoneLimit, { shouldValidate: true });
    }
    trigger(name);
  };

  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
    const input = inputRef.current;
    if (!input) return;

    const selectionStart = input.selectionStart ?? 0;
    const selectionEnd = input.selectionEnd ?? 0;
    const codeLength = dialCode.length;

    const isBackspaceAtCode =
      e.key === "Backspace" && selectionStart <= codeLength;
    const isDeleteAtCode = e.key === "Delete" && selectionStart < codeLength;
    const isSelectingCode =
      selectionStart < codeLength || selectionEnd < codeLength;

    if (isBackspaceAtCode || isDeleteAtCode || isSelectingCode) {
      e.preventDefault();
      setTimeout(() => input.setSelectionRange(codeLength, codeLength), 0);
    }
  };

  const handleClick = () => {
    const input = inputRef.current;
    if (input) {
      const cursorPos = input.selectionStart ?? 0;
      if (cursorPos < dialCode.length) {
        input.setSelectionRange(dialCode.length, dialCode.length);
      }
    }
  };

  useEffect(() => {
    if (!phone.startsWith(dialCode)) {
      setPhone(dialCode);
    } else if (phone === dialCode) {
      setPhone(dialCode);
    }
  }, [phone, dialCode]);

  useEffect(() => {
    if (!getValues(name)) setPhone(`+${dialCode}`);
  }, [getValues(name)]);

  useEffect(() => {
    const currentPhone = getValues(name);
    const currentCode = getValues(phone_code);

    if (currentPhone && currentCode) {
      setDialCode(`+${currentCode}`);
      setPhone(`+${currentCode}${currentPhone}`);
    }
  }, [getValues(name), getValues(phone_code)]);

  const onlyCountries = countries
    .map((c) => c.shortName?.toLowerCase())
    .filter(Boolean) as string[];

  return (
    <FormField
      control={form.control}
      name={name}
      render={({ field }) => (
        <FormItem className={cn("w-full", className)}>
          <div className="flex items-center gap-2">
            {label && (
              <FormLabel className=" text-text-primary font-medium text-sm leading-6 px-4 ">
                {t(label)}
                {showRequired && (
                  <span className="text-error mx-1 text-lg translate-y-1 inline-block">
                    *
                  </span>
                )}
              </FormLabel>
            )}
          </div>

          <FormControl>
            <div dir="ltr" className="relative">
              {loading ? (
                <Skeleton className="w-full h-12 rounded-xl" />
              ) : (
                <PhoneInput
                  enableSearch
                  country={defaultCountry}
                  disabled={disabled || loading}
                  onlyCountries={
                    onlyCountries.length > 0 ? onlyCountries : ["sa"]
                  }
                  localization={localization}
                  buttonClass="hover:bg-[green]"
                  containerStyle={{ borderRadius: "12px" }}
                  inputStyle={{
                    width: "100%",
                    borderRadius: "12px",
                    height: "48px",
                    paddingLeft: "60px",
                    borderColor: (errors as any)[name] ? "#ef233c" : "#EAEDF0",
                  }}
                  buttonStyle={{
                    marginLeft: "10px",
                    height: "40px",
                    width: "40px",
                    marginTop: "5px",
                    borderRadius: "50%",
                    border: "none",
                    background: "transparent",
                  }}
                  {...PhoneNumberProps}
                  value={phone}
                  onChange={handlePhoneChange}
                  inputProps={{
                    ref: inputRef,
                    onKeyDown: handleKeyDown,
                    onClick: handleClick,
                    disabled: disabled || loading,
                  }}
                />
              )}
            </div>
          </FormControl>
          <FormMessage />
        </FormItem>
      )}
    />
  );
};

export default FormPhoneNumber;
