/* eslint-disable @typescript-eslint/no-unused-vars */
/* 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 flags from "react-phone-number-input/flags";
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
  noBorder?: boolean;
  hideError?: boolean;
}
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>,
);

// 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 (compact, transparent)
  const customStyles = {
    container: (provided: any) => ({
      ...provided,
      width: "60px", // Compact and consistent
      height: "100%",
    }),
    control: (provided: any) => ({
      ...provided,
      height: "100%",
      minHeight: "100%",
      border: "none",
      borderRadius: 0,
      boxShadow: "none",
      backgroundColor: "transparent",
      display: "flex",
      flexWrap: "nowrap",
      alignItems: "center",
      cursor: "pointer",
    }),
    indicatorsContainer: (provided: any) => ({
      ...provided,
      padding: 0,
    }),
    dropdownIndicator: (provided: any) => ({
      ...provided,
      padding: "0 2px 0 0",
      color: "#6c757d",
    }),
    indicatorSeparator: () => ({
      display: "none",
    }),
    valueContainer: (provided: any) => ({
      ...provided,
      padding: "0 0 0 4px",
      display: "flex",
      alignItems: "center",
      justifyContent: "center",
    }),
    input: (provided: any) => ({
      ...provided,
      margin: 0,
      padding: 0,
    }),
    menu: (provided: any) => ({
      ...provided,
      width: "300px",
      zIndex: 9999,
    }),
    menuPortal: (base: any) => ({ ...base, zIndex: 9999 }),
    option: (provided: any, state: any) => ({
      ...provided,
      padding: "8px 12px",
      fontSize: "14px",
      backgroundColor: state.isFocused ? "#f8f9fa" : "#fff",
      color: "#222",
      cursor: "pointer",
    }),
  };

  // Custom SingleValue component to show only the flag
  const SingleValue = (props: any) => {
    const countryCode = props.data.value as CountryCode;
    const Flag = countryCode ? flags[countryCode] : null;

    if (props.selectProps.inputValue) {
      return null;
    }

    return (
      <div
        style={{
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          height: "100%",
        }}
      >
        <div
          style={{
            width: "20px",
            height: "14px",
            flexShrink: 0,
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            overflow: "hidden",
            borderRadius: "1px",
          }}
        >
          {Flag ? <Flag title={""} /> : "🌐"}
        </div>
      </div>
    );
  };

  return (
    <Select
      classNamePrefix="intl-select"
      value={selectedOption}
      onChange={(opt) => onChange(opt?.value)}
      options={options.filter((option) => option.value !== undefined)}
      formatOptionLabel={(option) => {
        const countryCode = option.value as CountryCode;
        if (!countryCode) {
          return <span>{option.label}</span>;
        }
        const Flag = flags[countryCode];
        let callingCode = "";
        try {
          callingCode = getCountryCallingCode(countryCode);
        } catch (error: any) {
          console.warn(
            `Could not get calling code for country: ${countryCode}`,
          );
        }

        return (
          <div style={{ display: "flex", alignItems: "center", gap: "12px" }}>
            <div
              style={{
                width: "28px",
                height: "20px",
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
                flexShrink: 0,
              }}
            >
              {Flag ? <Flag title={""} /> : "🌐"}
            </div>
            <span style={{ fontSize: "14px", lineHeight: "1.5" }}>
              {en[countryCode as keyof typeof en] || option.label}
              {callingCode && ` (+${callingCode})`}
            </span>
          </div>
        );
      }}
      styles={customStyles}
      components={{ SingleValue }}
      menuPortalTarget={typeof document !== "undefined" ? document.body : null}
      isSearchable={true}
      placeholder=""
      {...rest}
    />
  );
};

const InternationalPhoneInput: React.FC<PhoneInputFieldProps> = ({
  value: externalValue,
  onChange: externalOnChange,
  placeholder = "Phone number",
  error,
  className = "",
  country,
  onCountryChange,
  noBorder = false,
  hideError = false,
}) => {
  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 = (
    isCountryCode(country)
      ? country
      : isCountryCode(DefaultSetupValues?.PhoneCode)
        ? DefaultSetupValues.PhoneCode
        : "BH"
  ) as CountryCode;

  return (
    <>
      <div className={noBorder ? "" : "input-outer-box"}>
        <div
          className={`${noBorder ? "" : "input-style has-icon validate-field mb-0"} ${
            error ? "is-invalid" : ""
          }`}
          style={
            noBorder
              ? {
                  height: "45px",
                  display: "flex",
                  alignItems: "center",
                  backgroundColor: "transparent",
                  overflow: "hidden",
                  width: "100%",
                }
              : {
                  border: "1px solid #dee2e6",
                  borderRadius: "10px",
                  height: "45px",
                  display: "flex",
                  alignItems: "center",
                  backgroundColor: "#fff",
                  overflow: "hidden",
                }
          }
        >
          <PhoneInput
            international
            flags={flags}
            defaultCountry={resolvedDefaultCountry}
            value={phoneNumber}
            onChange={handlePhoneChange}
            labels={customLabels}
            className={`phone-input-container ${className}`}
            placeholder={placeholder}
            countrySelectComponent={CustomCountrySelect}
            {...(country ? { country } : {})}
            {...(onCountryChange
              ? { onCountryChange: handleCountryChange }
              : {})}
            numberInputProps={{
              className: "border-0 shadow-none",
              style: {
                height: "45px",
                paddingLeft: "5px",
                borderRadius: 0,
                width: "calc(100% - 60px)", // fill remaining space next to compact country control
                outline: "none",
                backgroundColor: "transparent",
                fontSize: "14px",
              },
            }}
          />
        </div>
      </div>
      {!hideError && error && (
        <div className="text-danger px-2 font-12 mt-1">{error}</div>
      )}
      <style jsx global>{`
        .phone-input-container {
          width: 100%;
          height: 45px;
          display: flex;
          align-items: center;
        }

        /* compact country area */
        .phone-input-container .PhoneInputCountry {
          width: 60px; /* same as CustomCountrySelect container width */
          min-width: 60px;
          height: 45px;
          display: flex;
          align-items: center;
          justify-content: center;
          background: transparent;
          padding-left: 0;
          box-sizing: border-box;
        }

        /* number input should occupy remaining space and be vertically centered */
        .phone-input-container .PhoneInputInput {
          height: 45px;
          border: none !important;
          background: transparent !important;
          padding-left: 5px; /* small gap from flag */
          box-sizing: border-box;
          width: calc(100% - 60px);
          font-size: 14px;
        }

        /* Ensure react-select inner elements don't introduce white blocks */
        .intl-select__control {
          background: transparent !important;
          box-shadow: none !important;
          border: none !important;
        }
        .intl-select__single-value {
          margin: 0;
          padding: 0;
        }
        .intl-select__value-container {
          padding: 0 !important;
        }
      `}</style>
    </>
  );
};

export default InternationalPhoneInput;
