/* global React */
const { useState, useEffect, useRef, useMemo } = React;

// ============================================================
// IBGE autocomplete: state first → city dependent.
// ============================================================
window.LocationFields = function LocationFields({ uf, setUf, city, setCity, errors, onTabFromCity }) {
  const [states, setStates] = useState([]);
  const [cities, setCities] = useState([]);

  const [ufQuery, setUfQuery] = useState(uf?.label || "");
  const [ufOpen, setUfOpen] = useState(false);
  const [ufActive, setUfActive] = useState(0);

  const [cityQuery, setCityQuery] = useState(city || "");
  const [cityOpen, setCityOpen] = useState(false);
  const [cityActive, setCityActive] = useState(0);
  const [loadingCities, setLoadingCities] = useState(false);

  const ufInputRef = useRef(null);
  const cityInputRef = useRef(null);

  // Load states once
  useEffect(() => {
    fetch("https://servicodosestados.ibge.gov.br/api/v1/localidades/estados?orderBy=nome")
      .catch(() =>
        fetch("https://servicodados.ibge.gov.br/api/v1/localidades/estados?orderBy=nome")
      )
      .then((r) => r.json())
      .then((data) => setStates(data))
      .catch(() => {
        // Fallback: hardcoded UF list
        setStates(FALLBACK_UFS);
      });
  }, []);

  // Load cities when UF changes
  useEffect(() => {
    if (!uf?.id) {
      setCities([]);
      return;
    }
    setLoadingCities(true);
    fetch(`https://servicodados.ibge.gov.br/api/v1/localidades/estados/${uf.id}/municipios?orderBy=nome`)
      .then((r) => r.json())
      .then((data) => setCities(data.map((c) => c.nome)))
      .catch(() => setCities([]))
      .finally(() => setLoadingCities(false));
  }, [uf?.id]);

  // ----- UF filter
  const ufMatches = useMemo(() => {
    const q = ufQuery.trim().toLowerCase();
    if (!q) return states.slice(0, 12);
    return states
      .filter(
        (s) =>
          s.nome.toLowerCase().includes(q) ||
          s.sigla.toLowerCase().includes(q)
      )
      .slice(0, 8);
  }, [ufQuery, states]);

  // ----- City filter
  const cityMatches = useMemo(() => {
    const q = cityQuery.trim().toLowerCase();
    if (!q) return cities.slice(0, 8);
    return cities.filter((c) => c.toLowerCase().includes(q)).slice(0, 8);
  }, [cityQuery, cities]);

  function pickUf(s) {
    setUf({ id: s.id, sigla: s.sigla, nome: s.nome, label: `${s.nome} (${s.sigla})` });
    setUfQuery(`${s.nome} (${s.sigla})`);
    setUfOpen(false);
    setCity("");
    setCityQuery("");
    // jump to city
    setTimeout(() => cityInputRef.current?.focus(), 30);
  }

  function pickCity(name) {
    setCity(name);
    setCityQuery(name);
    setCityOpen(false);
    setTimeout(() => onTabFromCity?.(), 30);
  }

  function ufKeyDown(e) {
    if (!ufOpen && (e.key === "ArrowDown" || e.key === "Enter")) {
      setUfOpen(true);
      return;
    }
    if (e.key === "ArrowDown") {
      e.preventDefault();
      setUfActive((i) => Math.min(i + 1, ufMatches.length - 1));
    } else if (e.key === "ArrowUp") {
      e.preventDefault();
      setUfActive((i) => Math.max(i - 1, 0));
    } else if (e.key === "Enter") {
      e.preventDefault();
      const pick = ufMatches[ufActive];
      if (pick) pickUf(pick);
    } else if (e.key === "Escape") {
      setUfOpen(false);
    } else if (e.key === "Tab" && ufOpen && ufMatches[ufActive]) {
      // soft autocomplete on Tab
      pickUf(ufMatches[ufActive]);
    }
  }

  function cityKeyDown(e) {
    if (!cityOpen && (e.key === "ArrowDown" || e.key === "Enter")) {
      setCityOpen(true);
      return;
    }
    if (e.key === "ArrowDown") {
      e.preventDefault();
      setCityActive((i) => Math.min(i + 1, cityMatches.length - 1));
    } else if (e.key === "ArrowUp") {
      e.preventDefault();
      setCityActive((i) => Math.max(i - 1, 0));
    } else if (e.key === "Enter") {
      e.preventDefault();
      const pick = cityMatches[cityActive];
      if (pick) pickCity(pick);
    } else if (e.key === "Escape") {
      setCityOpen(false);
    } else if (e.key === "Tab" && cityOpen && cityMatches[cityActive]) {
      pickCity(cityMatches[cityActive]);
    }
  }

  return (
    <div className="row cols-2">
      <div className="field combo">
        <label>
          Estado <span className="req">*</span>
          <span className="key-hint">↓ para listar</span>
        </label>
        <input
          ref={ufInputRef}
          className={`input ${errors.uf ? "error" : ""}`}
          placeholder="Digite ou escolha o estado"
          value={ufQuery}
          onChange={(e) => {
            setUfQuery(e.target.value);
            setUfOpen(true);
            setUfActive(0);
            if (uf) setUf(null);
          }}
          onFocus={() => setUfOpen(true)}
          onBlur={() => setTimeout(() => setUfOpen(false), 120)}
          onKeyDown={ufKeyDown}
          autoComplete="off"
        />
        {ufOpen && ufMatches.length > 0 && (
          <div className="combo-list">
            {ufMatches.map((s, i) => (
              <div
                key={s.id}
                className={`combo-item ${i === ufActive ? "active" : ""}`}
                onMouseDown={(e) => e.preventDefault()}
                onClick={() => pickUf(s)}
                onMouseEnter={() => setUfActive(i)}
              >
                {s.nome} <span style={{ color: "#8a8278", marginLeft: 6 }}>({s.sigla})</span>
              </div>
            ))}
          </div>
        )}
        {ufOpen && ufQuery && ufMatches.length === 0 && (
          <div className="combo-list">
            <div className="combo-empty">Nenhum estado encontrado.</div>
          </div>
        )}
        <div className="field-msg">{errors.uf || ""}</div>
      </div>

      <div className="field combo">
        <label>
          Cidade <span className="req">*</span>
          <span className="key-hint">{loadingCities ? "carregando…" : ""}</span>
        </label>
        <input
          ref={cityInputRef}
          className={`input ${errors.city ? "error" : ""}`}
          placeholder={uf ? "Digite o nome da cidade" : "Escolha o estado primeiro"}
          value={cityQuery}
          disabled={!uf}
          onChange={(e) => {
            setCityQuery(e.target.value);
            setCityOpen(true);
            setCityActive(0);
            setCity(e.target.value);
          }}
          onFocus={() => setCityOpen(true)}
          onBlur={() => setTimeout(() => setCityOpen(false), 120)}
          onKeyDown={cityKeyDown}
          autoComplete="off"
        />
        {cityOpen && cityMatches.length > 0 && (
          <div className="combo-list">
            {cityMatches.map((name, i) => (
              <div
                key={name}
                className={`combo-item ${i === cityActive ? "active" : ""}`}
                onMouseDown={(e) => e.preventDefault()}
                onClick={() => pickCity(name)}
                onMouseEnter={() => setCityActive(i)}
              >
                {name}
              </div>
            ))}
          </div>
        )}
        {cityOpen && uf && cityQuery && cityMatches.length === 0 && !loadingCities && (
          <div className="combo-list">
            <div className="combo-empty">Nenhuma cidade encontrada.</div>
          </div>
        )}
        <div className="field-msg">{errors.city || ""}</div>
      </div>
    </div>
  );
};

const FALLBACK_UFS = [
  { id: 12, sigla: "AC", nome: "Acre" }, { id: 27, sigla: "AL", nome: "Alagoas" },
  { id: 16, sigla: "AP", nome: "Amapá" }, { id: 13, sigla: "AM", nome: "Amazonas" },
  { id: 29, sigla: "BA", nome: "Bahia" }, { id: 23, sigla: "CE", nome: "Ceará" },
  { id: 53, sigla: "DF", nome: "Distrito Federal" }, { id: 32, sigla: "ES", nome: "Espírito Santo" },
  { id: 52, sigla: "GO", nome: "Goiás" }, { id: 21, sigla: "MA", nome: "Maranhão" },
  { id: 51, sigla: "MT", nome: "Mato Grosso" }, { id: 50, sigla: "MS", nome: "Mato Grosso do Sul" },
  { id: 31, sigla: "MG", nome: "Minas Gerais" }, { id: 15, sigla: "PA", nome: "Pará" },
  { id: 25, sigla: "PB", nome: "Paraíba" }, { id: 41, sigla: "PR", nome: "Paraná" },
  { id: 26, sigla: "PE", nome: "Pernambuco" }, { id: 22, sigla: "PI", nome: "Piauí" },
  { id: 33, sigla: "RJ", nome: "Rio de Janeiro" }, { id: 24, sigla: "RN", nome: "Rio Grande do Norte" },
  { id: 43, sigla: "RS", nome: "Rio Grande do Sul" }, { id: 11, sigla: "RO", nome: "Rondônia" },
  { id: 14, sigla: "RR", nome: "Roraima" }, { id: 42, sigla: "SC", nome: "Santa Catarina" },
  { id: 35, sigla: "SP", nome: "São Paulo" }, { id: 28, sigla: "SE", nome: "Sergipe" },
  { id: 17, sigla: "TO", nome: "Tocantins" },
];
