/* eslint-disable @typescript-eslint/no-explicit-any */
import { DefaultSetupValues } from "@/Constant/enums";
import React, { useState, useEffect } from "react";
import PhoneInput from "react-phone-number-input";
import "react-phone-number-input/style.css"; // Import styles
import { getCountryCallingCode } from "react-phone-number-input/input";
import { getCountries } from "react-phone-number-input/input";
import en from "react-phone-number-input/locale/en.json";
import type { CountryCode } from "libphonenumber-js/core";
import Select from "react-select";
import type { Props as SelectProps } from "react-select";

interface PhoneInputFieldProps {
  value?: string;
  onChange?: (value: string) => void;
  placeholder?: string;
  error?: string;
  className?: string;
  country?: string; // Optional country ISO2 code
  onCountryChange?: (country: string) => void; // Optional handler for country change
}
const isCountryCode = (value?: string): value is CountryCode => {
  return !!value && getCountries().includes(value as CountryCode);
};
const customLabels = getCountries().reduce(
  (acc, country) => {
    const countryName = en[country];
    const callingCode = getCountryCallingCode(country);
    if (countryName && callingCode) {
      acc[country] = `${countryName} (+${callingCode})`;
    }
    return acc;
  },
  { ...en } as Record<string, string>
);

// Add a mapping from country code to flag emoji
const countryFlagEmoji: Record<string, string> = {
  AF: "🇦🇫",
  AX: "🇦🇽",
  AL: "🇦🇱",
  DZ: "🇩🇿",
  AS: "🇦🇸",
  AD: "🇦🇩",
  AO: "🇦🇴",
  AI: "🇦🇮",
  AQ: "🇦🇶",
  AG: "🇦🇬",
  AR: "🇦🇷",
  AM: "🇦🇲",
  AW: "🇦🇼",
  AU: "🇦🇺",
  AT: "🇦🇹",
  AZ: "🇦🇿",
  BS: "🇧🇸",
  BH: "🇧🇭",
  BD: "🇧🇩",
  BB: "🇧🇧",
  BY: "🇧🇾",
  BE: "🇧🇪",
  BZ: "🇧🇿",
  BJ: "🇧🇯",
  BM: "🇧🇲",
  BT: "🇧🇹",
  BO: "🇧🇴",
  BA: "🇧🇦",
  BW: "🇧🇼",
  BR: "🇧🇷",
  IO: "🇮🇴",
  BN: "🇧🇳",
  BG: "🇧🇬",
  BF: "🇧🇫",
  BI: "🇧🇮",
  KH: "🇰🇭",
  CM: "🇨🇲",
  CA: "🇨🇦",
  CV: "🇨🇻",
  KY: "🇰🇾",
  CF: "🇨🇫",
  TD: "🇹🇩",
  CL: "🇨🇱",
  CN: "🇨🇳",
  CX: "🇨🇽",
  CC: "🇨🇨",
  CO: "🇨🇴",
  KM: "🇰🇲",
  CG: "🇨🇬",
  CD: "🇨🇩",
  CK: "🇨🇰",
  CR: "🇨🇷",
  CI: "🇨🇮",
  HR: "🇭🇷",
  CU: "🇨🇺",
  CY: "🇨🇾",
  CZ: "🇨🇿",
  DK: "🇩🇰",
  DJ: "🇩🇯",
  DM: "🇩🇲",
  DO: "🇩🇴",
  EC: "🇪🇨",
  EG: "🇪🇬",
  SV: "🇸🇻",
  GQ: "🇬🇶",
  ER: "🇪🇷",
  EE: "🇪🇪",
  ET: "🇪🇹",
  FK: "🇫🇰",
  FO: "🇫🇴",
  FJ: "🇫🇯",
  FI: "🇫🇮",
  FR: "🇫🇷",
  GF: "🇬🇫",
  PF: "🇵🇫",
  GA: "🇬🇦",
  GM: "🇬🇲",
  GE: "🇬🇪",
  DE: "🇩🇪",
  GH: "🇬🇭",
  GI: "🇬🇮",
  GR: "🇬🇷",
  GL: "🇬🇱",
  GD: "🇬🇩",
  GP: "🇬🇵",
  GU: "🇬🇺",
  GT: "🇬🇹",
  GG: "🇬🇬",
  GN: "🇬🇳",
  GW: "🇬🇼",
  GY: "🇬🇾",
  HT: "🇭🇹",
  VA: "🇻🇦",
  HN: "🇭🇳",
  HK: "🇭🇰",
  HU: "🇭🇺",
  IS: "🇮🇸",
  IN: "🇮🇳",
  ID: "🇮🇩",
  IR: "🇮🇷",
  IQ: "🇮🇶",
  IE: "🇮🇪",
  IM: "🇮🇲",
  IL: "🇮🇱",
  IT: "🇮🇹",
  JM: "🇯🇲",
  JP: "🇯🇵",
  JE: "🇯🇪",
  JO: "🇯🇴",
  KZ: "🇰🇿",
  KE: "🇰🇪",
  KI: "🇰🇮",
  KP: "🇰🇵",
  KR: "🇰🇷",
  KW: "🇰🇼",
  KG: "🇰🇬",
  LA: "🇱🇦",
  LV: "🇱🇻",
  LB: "🇱🇧",
  LS: "🇱🇸",
  LR: "🇱🇷",
  LY: "🇱🇾",
  LI: "🇱🇮",
  LT: "🇱🇹",
  LU: "🇱🇺",
  MO: "🇲🇴",
  MK: "🇲🇰",
  MG: "🇲🇬",
  MW: "🇲🇼",
  MY: "🇲🇾",
  MV: "🇲🇻",
  ML: "🇲🇱",
  MT: "🇲🇹",
  MH: "🇲🇭",
  MQ: "🇲🇶",
  MR: "🇲🇷",
  MU: "🇲🇺",
  YT: "🇾🇹",
  MX: "🇲🇽",
  FM: "🇫🇲",
  MD: "🇲🇩",
  MC: "🇲🇨",
  MN: "🇲🇳",
  ME: "🇲🇪",
  MS: "🇲🇸",
  MA: "🇲🇦",
  MZ: "🇲🇿",
  MM: "🇲🇲",
  NA: "🇳🇦",
  NR: "🇳🇷",
  NP: "🇳🇵",
  NL: "🇳🇱",
  NC: "🇳🇨",
  NZ: "🇳🇿",
  NI: "🇳🇮",
  NE: "🇳🇪",
  NG: "🇳🇬",
  NU: "🇳🇺",
  NF: "🇳🇫",
  MP: "🇲🇵",
  NO: "🇳🇴",
  OM: "🇴🇲",
  PK: "🇵🇰",
  PW: "🇵🇼",
  PS: "🇵🇸",
  PA: "🇵🇦",
  PG: "🇵🇬",
  PY: "🇵🇾",
  PE: "🇵🇪",
  PH: "🇵🇭",
  PN: "🇵🇳",
  PL: "🇵🇱",
  PT: "🇵🇹",
  PR: "🇵🇷",
  QA: "🇶🇦",
  RO: "🇷🇴",
  RU: "🇷🇺",
  RW: "🇷🇼",
  RE: "🇷🇪",
  BL: "🇧🇱",
  SH: "🇸🇭",
  KN: "🇰🇳",
  LC: "🇱🇨",
  MF: "🇲🇫",
  PM: "🇵🇲",
  VC: "🇻🇨",
  WS: "🇼🇸",
  SM: "🇸🇲",
  ST: "🇸🇹",
  SA: "🇸🇦",
  SN: "🇸🇳",
  RS: "🇷🇸",
  SC: "🇸🇨",
  SL: "🇸🇱",
  SG: "🇸🇬",
  SK: "🇸🇰",
  SI: "🇸🇮",
  SB: "🇸🇧",
  SO: "🇸🇴",
  ZA: "🇿🇦",
  SS: "🇸🇸",
  GS: "🇬🇸",
  ES: "🇪🇸",
  LK: "🇱🇰",
  SD: "🇸🇩",
  SR: "🇸🇷",
  SJ: "🇸🇯",
  SZ: "🇸🇿",
  SE: "🇸🇪",
  CH: "🇨🇭",
  SY: "🇸🇾",
  TW: "🇹🇼",
  TJ: "🇹🇯",
  TZ: "🇹🇿",
  TH: "🇹🇭",
  TL: "🇹🇱",
  TG: "🇹🇬",
  TK: "🇹🇰",
  TO: "🇹🇴",
  TT: "🇹🇹",
  TN: "🇹🇳",
  TR: "🇹🇷",
  TM: "🇹🇲",
  TC: "🇹🇨",
  TV: "🇹🇻",
  UG: "🇺🇬",
  UA: "🇺🇦",
  AE: "🇦🇪",
  GB: "🇬🇧",
  US: "🇺🇸",
  UY: "🇺🇾",
  UZ: "🇺🇿",
  VU: "🇻🇺",
  VE: "🇻🇪",
  VN: "🇻🇳",
  VG: "🇻🇬",
  VI: "🇻🇮",
  WF: "🇼🇫",
  YE: "🇾🇪",
  ZM: "🇿🇲",
  ZW: "🇿🇼",
};

// 1. Custom country select component
interface CountrySelectOption {
  value: string | undefined;
  label: string;
}

interface CustomCountrySelectProps
  extends Omit<
    SelectProps<CountrySelectOption, false>,
    "value" | "onChange" | "options"
  > {
  value?: string;
  onChange: (value?: string) => void;
  options: CountrySelectOption[];
}

const CustomCountrySelect: React.FC<CustomCountrySelectProps> = ({
  value,
  onChange,
  options,
  ...rest
}) => {
  // Find the selected option object
  const selectedOption = options.find((opt) => opt.value === value);

  // Custom styles for react-select
  const customStyles = {
    container: (provided: any) => ({
      ...provided,
      width: "65px", // Increased width
      height: "100%",
    }),
    control: (provided: any) => ({
      ...provided,
      height: "100%",
      minHeight: "100%",
      border: "none",
      boxShadow: "none",
      backgroundColor: "transparent",
      cursor: "pointer",
      padding: 0,
    }),
    indicatorsContainer: (provided: any) => ({
      ...provided,
      padding: 0,
      width: "20px",
    }),
    dropdownIndicator: (provided: any) => ({
      ...provided,
      padding: 0,
      color: "#6c757d",
    }),
    indicatorSeparator: () => ({
      display: "none",
    }),
    valueContainer: (provided: any) => ({
      ...provided,
      padding: "0",
      display: "flex",
      justifyContent: "center",
      alignItems: "center",
    }),
    menu: (provided: any) => ({
      ...provided,
      width: "300px", // Wide menu for better visibility
      zIndex: 9999,
    }),
    menuPortal: (base: any) => ({ ...base, zIndex: 9999 }),
    option: (provided: any, state: any) => ({
      ...provided,
      padding: "8px 12px",
      fontSize: "14px",
      backgroundColor: state.isFocused ? "#f0f0f0" : "#fff",
      color: "#222",
      cursor: "pointer",
    }),
  };

  // Custom SingleValue component to show only the flag
  const SingleValue = (props: any) => {
    const countryCode = props.data.value;
    return (
      <div
        style={{
          display: "flex",
          alignItems: "center",
          height: "100%",
          fontSize: "24px",
          lineHeight: 1,
        }}
      >
        {countryCode && countryFlagEmoji[countryCode]
          ? countryFlagEmoji[countryCode]
          : "🌐"}
      </div>
    );
  };

  return (
    <Select
      value={selectedOption}
      onChange={(opt) => onChange(opt?.value)}
      options={options
        .filter((option) => option.value !== undefined)
        .map((option) => ({
          ...option,
          label: `${
            option.value && countryFlagEmoji[option.value]
              ? countryFlagEmoji[option.value] + " "
              : ""
          }${en[option.value as keyof typeof en]} (+${
            option.value
              ? getCountryCallingCode(option.value as CountryCode)
              : ""
          })`,
        }))}
      styles={customStyles}
      components={{ SingleValue }}
      menuPortalTarget={typeof document !== "undefined" ? document.body : null} // Render menu in body to avoid clipping
      isSearchable={true} // Enable search
      placeholder=""
      {...rest}
    />
  );
};

const InternationalPhoneInput: React.FC<PhoneInputFieldProps> = ({
  value: externalValue,
  onChange: externalOnChange,
  placeholder = "Phone number",
  error,
  className = "",
  country,
  onCountryChange,
}) => {
  const [phoneNumber, setPhoneNumber] = useState(externalValue || "");

  const handlePhoneChange = (value: string | undefined) => {
    const newValue = value || "";
    setPhoneNumber(newValue);

    if (externalOnChange) {
      externalOnChange(newValue);
    }
  };

  // Handler to adapt PhoneInput's onCountryChange signature to our prop
  const handleCountryChange = (countryCode?: CountryCode) => {
    if (onCountryChange) {
      onCountryChange(countryCode || "");
    }
  };

  // Update internal state when external value changes
  useEffect(() => {
    if (externalValue !== undefined) {
      setPhoneNumber(externalValue);
    }
  }, [externalValue]);

  const resolvedDefaultCountry: CountryCode | undefined =
  isCountryCode(country)
    ? country
    : isCountryCode(DefaultSetupValues?.PhoneCode)
    ? DefaultSetupValues.PhoneCode
    : undefined;

  return (
    <>
      <div className="input-outer-box">
        <div
          className={`input-style no-borders has-icon validate-field mb-0 ${
            error ? "is-invalid" : ""
          }`}
          style={{
            border: "1px solid #dee2e6",
            borderRadius: "10px",
            padding: "0 10px",
            display: "flex",
            alignItems: "center",
            height: "45px", // Match standard input height
            backgroundColor: "#fff",
          }}
        >
          <PhoneInput
            international
            // defaultCountry={country || DefaultSetupValues?.PhoneCode}
            defaultCountry={resolvedDefaultCountry}   
            value={phoneNumber}
            onChange={handlePhoneChange}
            labels={customLabels}
            className={`phone-input-container ${className}`}
            placeholder={placeholder}
            countrySelectComponent={CustomCountrySelect}
            {...(country ? { country } : {})}
            {...(onCountryChange
              ? { onCountryChange: handleCountryChange }
              : {})}
            style={{
              display: "flex",
              alignItems: "center",
              width: "100%",
              height: "100%",
            }}
            numberInputProps={{
              className: "form-control border-0 shadow-none", // Remove default input styles
              style: {
                height: "100%",
                paddingLeft: "10px",
              },
            }}
          />
        </div>
      </div>
      {error && <div className="text-danger px-2 font-12 mt-1">{error}</div>}
      <style jsx global>{`
        .phone-input-container .PhoneInputCountry {
          margin-right: 0;
          height: 100%;
          display: flex;
          align-items: center;
        }
        .phone-input-container input {
          background: transparent !important;
        }
        /* Hide default arrow from react-phone-number-input */
        .PhoneInputCountrySelectArrow {
          display: none;
        }
      `}</style>
    </>
  );
};

export default InternationalPhoneInput;
