// HM Veículos — Filter bar + popup (estoque)

const { useState: useStateF, useEffect: useEffectF, useRef: useRefF, useMemo: useMemoF } = React;

// ---------- helpers ----------
const SORT_OPTIONS = [
  { id: "recente",  label: "Mais recentes no estoque" },
  { id: "popular",  label: "Mais populares" },
  { id: "barato",   label: "Preço ↑" },
  { id: "caro",     label: "Preço ↓" },
  { id: "ano",      label: "Ano ↑" },
  { id: "anoDesc",  label: "Ano ↓" },
  { id: "km",       label: "KM ↑" },
  { id: "kmDesc",   label: "KM ↓" },
  { id: "az",       label: "Modelo A → Z" },
  { id: "za",       label: "Modelo Z → A" },
];

const DEFAULT_SORT = "recente";

function roundDown5k(v) { return Math.floor(v / 5000) * 5000; }
function roundUp5k(v)   { return Math.ceil(v / 5000) * 5000; }
function fmtBRLshort(v) {
  if (v >= 1000) return "R$ " + (v / 1000).toLocaleString("pt-BR", { maximumFractionDigits: 0 }) + "k";
  return "R$ " + v;
}

// Filtro aplicado + ordenação
function applyFilters(vehicles, state) {
  const { cambios, combustiveis, precoMin, precoMax, sort } = state;
  let out = vehicles.filter((v) => {
    if (cambios.length && !cambios.includes(v.cambio)) return false;
    if (combustiveis.length && !combustiveis.includes(v.combustivel)) return false;
    if (v.preco < precoMin || v.preco > precoMax) return false;
    return true;
  });

  const cmp = {
    recente: (a, b) => {
      // "Mais recentes no estoque" = ordem de cadastro (createdAt desc)
      const da = a.createdAt ? new Date(a.createdAt).getTime() : 0;
      const db = b.createdAt ? new Date(b.createdAt).getTime() : 0;
      if (db !== da) return db - da;
      // Sem createdAt? Cai num fallback razoável: ano modelo, depois km
      return (b.anoModelo || b.ano) - (a.anoModelo || a.ano) || a.km - b.km;
    },
    popular: (a, b) => (b.views || 0) - (a.views || 0) || a.preco - b.preco,
    barato:  (a, b) => a.preco - b.preco,
    caro:    (a, b) => b.preco - a.preco,
    ano:     (a, b) => (a.anoModelo || a.ano) - (b.anoModelo || b.ano),
    anoDesc: (a, b) => (b.anoModelo || b.ano) - (a.anoModelo || a.ano),
    km:      (a, b) => a.km - b.km,
    kmDesc:  (a, b) => b.km - a.km,
    az:      (a, b) => a.modelo.localeCompare(b.modelo, "pt-BR"),
    za:      (a, b) => b.modelo.localeCompare(a.modelo, "pt-BR"),
  }[sort] || (() => 0);
  out.sort(cmp);
  return out;
}

// ---------- Range slider duplo ----------
function PriceRangeSlider({ min, max, step, value, onChange }) {
  const [lo, hi] = value;
  const trackRef = useRefF(null);
  const draggingRef = useRefF(null); // 'lo' | 'hi' | null

  const pct = (v) => ((v - min) / (max - min)) * 100;

  const computeFromEvent = (clientX) => {
    const rect = trackRef.current.getBoundingClientRect();
    const ratio = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
    const raw = min + ratio * (max - min);
    return Math.round(raw / step) * step;
  };

  const onPointerMove = (e) => {
    if (!draggingRef.current) return;
    const v = computeFromEvent(e.clientX);
    if (draggingRef.current === "lo") {
      onChange([Math.min(v, hi - step), hi]);
    } else {
      onChange([lo, Math.max(v, lo + step)]);
    }
  };

  const onPointerUp = () => {
    if (draggingRef.current) {
      draggingRef.current = null;
      window.removeEventListener("pointermove", onPointerMove);
      window.removeEventListener("pointerup", onPointerUp);
    }
  };

  const startDrag = (which) => (e) => {
    e.preventDefault();
    draggingRef.current = which;
    window.addEventListener("pointermove", onPointerMove);
    window.addEventListener("pointerup", onPointerUp);
  };

  // Click no track salta o thumb mais próximo
  const onTrackClick = (e) => {
    const v = computeFromEvent(e.clientX);
    const distLo = Math.abs(v - lo);
    const distHi = Math.abs(v - hi);
    if (distLo <= distHi) onChange([Math.min(v, hi - step), hi]);
    else onChange([lo, Math.max(v, lo + step)]);
  };

  return (
    <div className="range-slider">
      <div className="range-track" ref={trackRef} onPointerDown={onTrackClick}>
        <div
          className="range-fill"
          style={{ left: pct(lo) + "%", right: 100 - pct(hi) + "%" }}
        ></div>
        <button
          type="button"
          className="range-thumb"
          style={{ left: pct(lo) + "%" }}
          onPointerDown={startDrag("lo")}
          onKeyDown={(e) => {
            if (e.key === "ArrowLeft")  onChange([Math.max(min, lo - step), hi]);
            if (e.key === "ArrowRight") onChange([Math.min(hi - step, lo + step), hi]);
          }}
          aria-label={"Preço mínimo: " + fmtBRLshort(lo)}
        ></button>
        <button
          type="button"
          className="range-thumb"
          style={{ left: pct(hi) + "%" }}
          onPointerDown={startDrag("hi")}
          onKeyDown={(e) => {
            if (e.key === "ArrowLeft")  onChange([lo, Math.max(lo + step, hi - step)]);
            if (e.key === "ArrowRight") onChange([lo, Math.min(max, hi + step)]);
          }}
          aria-label={"Preço máximo: " + fmtBRLshort(hi)}
        ></button>
      </div>
      <div className="range-values">
        <span>{fmtBRLshort(lo)}</span>
        <span>{hi >= max ? fmtBRLshort(hi) + "+" : fmtBRLshort(hi)}</span>
      </div>
    </div>
  );
}

// ---------- Sort dropdown (custom select) ----------
function SortDropdown({ value, onChange }) {
  const [open, setOpen] = useStateF(false);
  const ref = useRefF(null);

  useEffectF(() => {
    if (!open) return;
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", onDoc);
    document.addEventListener("keydown", (e) => e.key === "Escape" && setOpen(false));
    return () => document.removeEventListener("mousedown", onDoc);
  }, [open]);

  const current = SORT_OPTIONS.find((o) => o.id === value) || SORT_OPTIONS[0];

  return (
    <div className={"sort-select" + (open ? " open" : "")} ref={ref}>
      <button
        type="button"
        className="sort-trigger"
        onClick={() => setOpen((o) => !o)}
        aria-haspopup="listbox"
        aria-expanded={open}
      >
        <span className="sort-label">Ordenar</span>
        <span className="sort-current">{current.label}</span>
        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" className="sort-chev" aria-hidden="true">
          <path d="M6 9l6 6 6-6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
        </svg>
      </button>
      {open && (
        <div className="sort-menu" role="listbox">
          {SORT_OPTIONS.map((o) => (
            <button
              key={o.id}
              type="button"
              role="option"
              aria-selected={o.id === value}
              className={"sort-option" + (o.id === value ? " active" : "")}
              onClick={() => { onChange(o.id); setOpen(false); }}
            >
              {o.label}
              {o.id === value && (
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" aria-hidden="true">
                  <path d="M5 13l4 4L19 7" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" />
                </svg>
              )}
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

// ---------- Filter popup ----------
function FilterPopup({ priceBounds, state, onChange, onClear, onClose, anchorRef, count }) {
  const popRef = useRefF(null);
  const [pos, setPos] = useStateF({ top: 0, left: 0 });

  // Posiciona o popup abaixo do botão, alinhado à direita
  useEffectF(() => {
    if (!anchorRef.current) return;
    const r = anchorRef.current.getBoundingClientRect();
    const popW = 380;
    let left = r.right - popW;
    if (left < 16) left = 16;
    if (left + popW > window.innerWidth - 16) left = window.innerWidth - popW - 16;
    const popH = popRef.current ? popRef.current.offsetHeight : 520;
    const vh = window.innerHeight;
    let top = r.bottom + 12;
    if (top + popH > vh - 12) {
      top = r.top - popH - 12;
    }
    // Garante que sempre fica dentro do viewport mesmo se o trigger estiver fora dele
    top = Math.max(12, Math.min(vh - popH - 12, top));
    setPos({ top, left });
  }, []);

  // Fecha em click fora / ESC
  useEffectF(() => {
    const onDoc = (e) => {
      if (popRef.current && popRef.current.contains(e.target)) return;
      if (anchorRef.current && anchorRef.current.contains(e.target)) return;
      onClose();
    };
    const onKey = (e) => e.key === "Escape" && onClose();
    document.addEventListener("mousedown", onDoc);
    document.addEventListener("keydown", onKey);
    return () => {
      document.removeEventListener("mousedown", onDoc);
      document.removeEventListener("keydown", onKey);
    };
  }, []);

  const toggleFromList = (key, val) => {
    onChange((s) => {
      const cur = s[key];
      const next = cur.includes(val) ? cur.filter((x) => x !== val) : [...cur, val];
      return { ...s, [key]: next };
    });
  };

  return (
    <div
      ref={popRef}
      className="filter-popup"
      style={{ top: pos.top, left: pos.left }}
      role="dialog"
      aria-label="Filtros do estoque"
    >
      <div className="filter-popup-head">
        <span className="filter-popup-title">Filtros</span>
        <button className="filter-popup-close" onClick={onClose} aria-label="Fechar">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
            <path d="M6 6l12 12M18 6L6 18" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
          </svg>
        </button>
      </div>

      <div className="filter-group">
        <div className="filter-group-label">Câmbio</div>
        <div className="filter-chips">
          {["Automático", "Manual", "CVT", "Automatizado"].map((c) => {
            const active = state.cambios.includes(c);
            return (
              <button
                key={c}
                type="button"
                className={"filter-chip" + (active ? " active" : "")}
                onClick={() => toggleFromList("cambios", c)}
              >
                {c}
              </button>
            );
          })}
        </div>
      </div>

      <div className="filter-group">
        <div className="filter-group-label">Combustível</div>
        <div className="filter-chips">
          {["Flex", "Gasolina", "Diesel", "Etanol", "Híbrido", "Elétrico"].map((c) => {
            const active = state.combustiveis.includes(c);
            return (
              <button
                key={c}
                type="button"
                className={"filter-chip" + (active ? " active" : "")}
                onClick={() => toggleFromList("combustiveis", c)}
              >
                {c}
              </button>
            );
          })}
        </div>
      </div>

      <div className="filter-group">
        <div className="filter-group-label">Faixa de preço</div>
        <PriceRangeSlider
          min={priceBounds.min}
          max={priceBounds.max}
          step={5000}
          value={[state.precoMin, state.precoMax]}
          onChange={([a, b]) => onChange((s) => ({ ...s, precoMin: a, precoMax: b }))}
        />
      </div>

      <div className="filter-popup-foot">
        <button className="filter-clear" onClick={onClear}>Limpar filtros</button>
        <span className="filter-count">
          <strong>{count}</strong> {count === 1 ? "veículo" : "veículos"}
        </span>
      </div>
    </div>
  );
}

// ---------- Main bar (replaces the old "Ver estoque completo" link) ----------
function FilterBar({ vehicles, onChange }) {
  const priceBounds = useMemoF(() => {
    if (!vehicles.length) return { min: 0, max: 200000 };
    const prices = vehicles.map((v) => v.preco);
    return {
      min: roundDown5k(Math.min(...prices)),
      max: roundUp5k(Math.max(...prices)),
    };
  }, [vehicles]);

  const initial = () => ({
    cambios: [],
    combustiveis: [],
    precoMin: priceBounds.min,
    precoMax: priceBounds.max,
    sort: DEFAULT_SORT,
  });
  const [state, setState] = useStateF(initial);
  const [open, setOpen] = useStateF(false);
  const triggerRef = useRefF(null);

  // Quando bounds mudam (carga inicial), re-sincroniza
  useEffectF(() => {
    setState((s) => ({ ...s, precoMin: priceBounds.min, precoMax: priceBounds.max }));
  }, [priceBounds.min, priceBounds.max]);

  // Resultado computado
  const filtered = useMemoF(() => applyFilters(vehicles, state), [vehicles, state]);

  // Avisa o parent
  useEffectF(() => { onChange(filtered); }, [filtered]);

  // Conta filtros ativos pra badge
  const activeCount =
    state.cambios.length +
    state.combustiveis.length +
    (state.precoMin > priceBounds.min ? 1 : 0) +
    (state.precoMax < priceBounds.max ? 1 : 0);

  const clear = () => setState(initial());

  return (
    <div className="filter-bar">
      <button
        ref={triggerRef}
        type="button"
        className={"filter-trigger" + (activeCount ? " has-active" : "") + (open ? " is-open" : "")}
        onClick={() => setOpen((o) => !o)}
        aria-haspopup="dialog"
        aria-expanded={open}
      >
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden="true">
          <path d="M3 5h18M6 12h12M10 19h4" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
        </svg>
        Filtros
        {activeCount > 0 && <span className="filter-badge">{activeCount}</span>}
      </button>

      <SortDropdown value={state.sort} onChange={(sort) => setState((s) => ({ ...s, sort }))} />

      {open && ReactDOM.createPortal(
        <FilterPopup
          priceBounds={priceBounds}
          state={state}
          onChange={setState}
          onClear={clear}
          onClose={() => setOpen(false)}
          anchorRef={triggerRef}
          count={filtered.length}
        />,
        document.body
      )}
    </div>
  );
}

window.FilterBar = FilterBar;
