import React from "react";
import styled from "styled-components";
import Input from "./Input";
import { Country, getCountries } from "../data/countries";

type Props = {
  label?: string;
  name?: string;                 // если нужна интеграция с формой — кладём выбранный code в hidden input
  locale?: string;               // "en" | "ru" | ...
  requiredFromList?: boolean;    // строго из списка (по умолчанию true)
  fullWidth?: boolean;
  onChange?: (country: Country | null) => void;
  initialCode?: string;          // можно предзадать страну ISO-кодом
};

export default function CountrySelect({
  label = "Country",
  name,
  locale = "en",
  requiredFromList = true,
  fullWidth,
  onChange,
  initialCode,
}: Props) {
  const countries = React.useMemo(() => getCountries(locale), [locale]);

  // отображаемое значение в текстовом поле
  const [value, setValue] = React.useState("");
  const [open, setOpen] = React.useState(false);
  const [highlight, setHighlight] = React.useState(0);
  const [error, setError] = React.useState<string | undefined>();
  const [selected, setSelected] = React.useState<Country | null>(null);

  // префилл по коду
  React.useEffect(() => {
    if (!initialCode) return;
    const c = countries.find((x) => x.code === initialCode);
    if (c) {
      setSelected(c);
      setValue(c.name);
    }
  }, [initialCode, countries]);

  // фильтрация по подстроке (без учёта регистра/диакритики)
  const norm = (s: string) => s.normalize("NFKD").replace(/\p{Diacritic}/gu, "").toLowerCase();
  const q = norm(value.trim());
  const filtered = React.useMemo(
    () => (q ? countries.filter((c) => norm(c.name).includes(q)) : countries),
    [countries, q]
  );

  React.useEffect(() => {
    if (!open) setHighlight(0);
  }, [open, q]);

  const pick = (c: Country) => {
    setSelected(c);
    setValue(c.name);
    setOpen(false);
    setError(undefined);
    onChange?.(c);
  };

  const validate = () => {
    const exact = countries.find((c) => norm(c.name) === q);
    if (exact) {
      pick(exact);
      return true;
    }
    if (requiredFromList) {
      setError("Please select from the list");
      onChange?.(null);
      return false;
    }
    // свободный ввод разрешён (если requiredFromList=false)
    setSelected(null);
    setError(undefined);
    onChange?.(null);
    return true;
  };

  // клик вне — закрыть
  const rootRef = React.useRef<HTMLDivElement>(null);
  React.useEffect(() => {
    const onDown = (e: MouseEvent) => {
      if (!rootRef.current?.contains(e.target as Node)) setOpen(false);
    };
    document.addEventListener("mousedown", onDown);
    return () => document.removeEventListener("mousedown", onDown);
  }, []);

  return (
    <Wrap ref={rootRef} $full={!!fullWidth}>
      <Input
        label={label}
        fullWidth
        value={value}
        onFocus={() => { setOpen(true); setError(undefined); }}
        onChange={(e) => { setValue(e.target.value); setOpen(true); setError(undefined); }}
        onKeyDown={(e) => {
          if (!open && (e.key === "ArrowDown" || e.key === "ArrowUp")) {
            setOpen(true);
            return;
          }
          if (!open) return;

          if (e.key === "ArrowDown") {
            e.preventDefault();
            setHighlight((h) => Math.min(filtered.length - 1, h + 1));
          } else if (e.key === "ArrowUp") {
            e.preventDefault();
            setHighlight((h) => Math.max(0, h - 1));
          } else if (e.key === "Enter") {
            e.preventDefault();
            const c = filtered[highlight];
            if (c) pick(c);
            else validate();
          } else if (e.key === "Escape") {
            setOpen(false);
          }
        }}
        onBlur={() => {
          // даём шанс клику по пункту — blur произойдёт раньше
          setTimeout(() => { if (!rootRef.current?.contains(document.activeElement)) validate(); }, 0);
        }}
        errorText={error}
      />

      {name && (
        // для нативной отправки форм можно положить ISO-код в hidden
        <input type="hidden" name={name} value={selected?.code ?? ""} />
      )}

      {open && (
        <Menu role="listbox">
          {filtered.length === 0 && <Empty>No matches</Empty>}
          {filtered.slice(0, 200).map((c, i) => (
            <Item
              key={c.code}
              $active={i === highlight}
              onMouseEnter={() => setHighlight(i)}
              onMouseDown={(e) => e.preventDefault()}
              onClick={() => pick(c)}
            >
              <span>{c.name}</span>
              {selected?.code === c.code && <Tick>✓</Tick>}
            </Item>
          ))}
        </Menu>
      )}
    </Wrap>
  );
}

/* ============ styles ============ */
const Wrap = styled.div<{ $full: boolean }>`
  position: relative;
  width: ${({ $full }) => ($full ? "100%" : "auto")};
`;

const Menu = styled.div`
  position: absolute;
  left: 0; right: 0; top: 100%;
  margin-top: 6px;
  max-height: 280px;
  overflow: auto;
  background: #fff;
  border: 1px solid #14935f;
  border-radius: 8px;
  box-shadow: 0px 8px 24px rgba(39, 100, 105, 0.25);
  z-index: 20;
  padding: 6px 0;

  /* скрыть нативный скроллбар — необязательно */
  scrollbar-width: thin;
`;

const Item = styled.div<{ $active?: boolean }>`
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  cursor: pointer;
  user-select: none;
  font-family: "GTAmerica", sans-serif;
  font-size: 16px;
  line-height: 22px;
  color: #1d2023;

  background: ${({ $active }) => ($active ? "#f0faf5" : "transparent")};

  &:hover { background: #E9E9E9;margin:0px 5px;padding: 10px 9px;border-radius:3px; }
`;

const Empty = styled.div`
  padding: 12px 14px;
  color: #6b7280;
  font-family: "GTAmerica", sans-serif;
  font-size: 14px;
`;

const Tick = styled.span`
  color: #16a34a;
  font-weight: 700;
`;
