"use client";

import { useEffect, useRef, useState } from "react";
import { apiRequest } from "@/lib/api";
import { useI18n } from "@/lib/i18n";

export type Country = {
  id: number;
  name: string;
  key: string;
  flag: string;
};

type CountriesPayload = {
  items?: Country[];
  pagination?: { last_page?: number };
};

const countriesCache = new Map<string, Promise<Country[]>>();

function loadCountries(lang: string) {
  const cached = countriesCache.get(lang);
  if (cached) return cached;

  const request = (async () => {
    const first = await apiRequest<CountriesPayload>("general/countries", { lang });
    let items = first.data?.items || [];
    const lastPage = first.data?.pagination?.last_page || 1;
    for (let page = 2; page <= lastPage; page += 1) {
      const next = await apiRequest<CountriesPayload>(`general/countries?page=${page}`, { lang });
      items = items.concat(next.data?.items || []);
    }
    return items;
  })().catch((error) => {
    countriesCache.delete(lang);
    throw error;
  });

  countriesCache.set(lang, request);
  return request;
}

export default function CountryCodeSelect({
  value,
  onChange,
}: {
  value: string;
  onChange: (code: string) => void;
}) {
  const { lang, t } = useI18n();
  const [countries, setCountries] = useState<Country[]>([]);
  const [open, setOpen] = useState(false);
  const rootRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    let cancelled = false;
    loadCountries(lang)
      .then((items) => {
        if (cancelled) return;
        setCountries(items);
        if (!value) {
          const preferred = items.find((country) => country.key === "966") || items[0];
          if (preferred) onChange(preferred.key);
        }
      })
      .catch(() => {
        if (!cancelled) setCountries([]);
      });
    return () => {
      cancelled = true;
    };
  }, [lang]);

  useEffect(() => {
    if (!open) return;
    const onDoc = (event: MouseEvent) => {
      if (!rootRef.current?.contains(event.target as Node)) setOpen(false);
    };
    const onKey = (event: KeyboardEvent) => {
      if (event.key === "Escape") setOpen(false);
    };
    document.addEventListener("mousedown", onDoc);
    document.addEventListener("keydown", onKey);
    return () => {
      document.removeEventListener("mousedown", onDoc);
      document.removeEventListener("keydown", onKey);
    };
  }, [open]);

  const selected = countries.find((country) => country.key === value);

  return (
    <div ref={rootRef} className="relative h-full shrink-0">
      <button
        type="button"
        onClick={() => setOpen((current) => !current)}
        aria-label={t("selectCountry")}
        aria-expanded={open}
        className="flex h-full items-center gap-1 rounded-e-lg border-s border-[#E8E4D9] bg-[#FAFAF8] pe-3 ps-[13px]"
      >
        {selected?.flag ? (
          <img src={selected.flag} alt="" width={18} height={18} className="h-[18px] w-[18px] shrink-0 object-contain" />
        ) : null}
        <span className="text-sm leading-5 text-[#4A4A6A]">{selected ? `+${selected.key}` : t("selectCountry")}</span>
      </button>
      {open && countries.length > 0 && (
        <div className="absolute end-0 top-full z-20 mt-1 max-h-60 w-64 overflow-auto rounded-xl border border-[#E8E4D9] bg-white py-1 shadow-[0px_10px_15px_-3px_rgba(0,0,0,0.1)]">
          {countries.map((country) => (
            <button
              key={country.id}
              type="button"
              onClick={() => {
                onChange(country.key);
                setOpen(false);
              }}
              className="flex w-full items-center gap-2 px-3 py-2 text-start text-sm text-[#1A1A2E] hover:bg-[#FAFAF8]"
            >
              {country.flag ? (
                <img src={country.flag} alt="" width={18} height={18} className="h-[18px] w-[18px] shrink-0 object-contain" />
              ) : null}
              <span className="min-w-0 flex-1 truncate">{country.name}</span>
              <span className="text-[#4A4A6A]">+{country.key}</span>
            </button>
          ))}
        </div>
      )}
    </div>
  );
}
