/* ============================================================
   Carzello — Copart inventory tab
   Live snapshot of Copart US sales data served by the Sayarah
   sales-data backend (~138k lots), proxied same-origin via
   /api/copart/* (see server.js). Clearly labeled as Copart data;
   these are sourcing candidates, not Carzello auctions — buyers
   request them and Carzello bids/buys at Copart on their behalf.
   ============================================================ */

const COPART_MAKES = ["TOYOTA", "LEXUS", "HONDA", "NISSAN", "HYUNDAI", "KIA", "FORD", "CHEVROLET", "DODGE", "JEEP", "GMC", "BMW", "MERCEDES-BENZ", "AUDI", "VOLKSWAGEN", "TESLA", "MITSUBISHI", "SUBARU", "MAZDA"];
const copartThumb = (v) => (v.imageThumbnail ? (v.imageThumbnail.startsWith("http") ? v.imageThumbnail : "https://" + v.imageThumbnail) : null);
/* Copart hosts a full-resolution twin of every thumbnail (…_thb.jpg → …_ful.jpg) */
const copartFull = (u) => (u ? u.replace(/_thb(\.[a-z]+)(\?.*)?$/i, "_ful$1$2") : u);
/* Copart's CSV truncates modelGroup at 10 chars ("LAND CRUIS") — prefer the longer field */
const copartModel = (v) => {
  const g = String(v.modelGroup || ""), d = String(v.modelDetail || "");
  return (d.length >= g.length ? d : g) || g || d;
};
const copartTitle = (v) => `${v.year || ""} ${v.make || ""} ${copartModel(v)}`.trim();

/* Copart auction schedule: saleDateMDCy=YYYYMMDD, saleTimeHhmm=HHMM, timeZone */
function copartSale(v) {
  const d = String(v.saleDateMDCy || v.saleDate || "").replace(/\D/g, "");
  if (d.length !== 8) return null;
  const t = String(v.saleTimeHhmm || "").replace(/\D/g, "").padStart(4, "0");
  const dt = new Date(+d.slice(0, 4), +d.slice(4, 6) - 1, +d.slice(6, 8), +t.slice(0, 2) || 0, +t.slice(2, 4) || 0);
  if (isNaN(dt.getTime())) return null;
  const time = v.saleTimeHhmm ? `${t.slice(0, 2)}:${t.slice(2)}${v.timeZone ? " " + v.timeZone : ""}` : "";
  // calendar-day difference (NOT elapsed-ms rounding): an auction later today is
  // "today", never "tomorrow" or "passed", regardless of the hour
  const dayStart = (x) => new Date(x.getFullYear(), x.getMonth(), x.getDate()).getTime();
  const days = Math.round((dayStart(dt) - dayStart(new Date())) / 86400000);
  return {
    dt,
    short: dt.toLocaleDateString(undefined, { month: "short", day: "numeric" }) + (time ? ` · ${time}` : ""),
    long: dt.toLocaleDateString(undefined, { weekday: "long", month: "long", day: "numeric", year: "numeric" }) + (time ? ` · ${time}` : ""),
    inDays: days,
  };
}

/* progressive card image: the ~6 KB thumbnail paints instantly (slightly
   upscaled), then the ~200 KB full-res version swaps in once it's downloaded.
   Feels fast on slow links without giving up sharpness. */
function CopartHeroImg({ v }) {
  const thumb = copartThumb(v);
  const [src, setSrc] = useState(thumb);
  useEffect(() => {
    setSrc(thumb);
    const full = copartFull(thumb);
    if (!full || full === thumb) return;
    let dead = false;
    const img = new Image();
    img.onload = () => { if (!dead) setSrc(full); };
    img.src = full;
    return () => { dead = true; };
  }, [v.lotNumber]);
  if (!src) return <Photo className="photo" hue={((v.lotNumber || 0) % 36) * 10} />;
  return (
    <div className="photo" style={{ background: "#e8ebee" }}>
      <img src={src} alt={copartTitle(v)} loading="lazy" decoding="async"
        style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }} />
    </div>
  );
}

function CopartCard({ v, onOpen }) {
  const thumb = copartThumb(v);
  return (
    <div className="lcard" onClick={onOpen} style={{ cursor: "pointer" }} role="button" tabIndex={0}
      onKeyDown={(e) => (e.key === "Enter" || e.key === " ") && onOpen()}>
      <div className="hero">
        <CopartHeroImg v={v} />
        <span style={{ position: "absolute", top: 8, insetInlineStart: 8, zIndex: 2 }}><Pill kind="red" style={{ fontSize: 9.5, padding: "2px 7px" }}>COPART DATA</Pill></span>
      </div>
      <div className="card-pad col gap-6" style={{ padding: 14 }}>
        <b style={{ fontSize: 15, fontFamily: "var(--heading)", textTransform: "uppercase" }}>{copartTitle(v)}</b>
        <div className="muted" style={{ fontSize: 12.5 }}>
          {Number(v.odometer || 0).toLocaleString("en-US")} mi · {v.damageDescription || "—"}{v.secondaryDamage ? ` + ${v.secondaryDamage}` : ""}
        </div>
        <div className="muted" style={{ fontSize: 12 }}>{v.runsDrives || v.saleStatus || ""} · {v.location ? `${v.location.city}, ${v.location.state}` : v.yardName}</div>
        {(() => { const s = copartSale(v); return (
          <div className="row gap-6" style={{ fontSize: 12, fontWeight: 700, color: s && s.inDays <= 2 && s.inDays >= 0 ? "var(--brand)" : "var(--fg-2)" }}>
            <I.clock width="12" height="12" /> {s ? `Auction ${s.short}` : (v.saleStatus === "Future sale" ? "Auction not yet scheduled" : v.saleStatus || "Auction date TBA")}
          </div>
        ); })()}
        <div className="row gap-8" style={{ marginTop: 4 }}>
          <div><div className="muted" style={{ fontSize: 10.5, textTransform: "uppercase", letterSpacing: ".06em" }}>Est. retail</div><b className="tnum" style={{ fontSize: 15 }}>{fmtUSD(Number(v.estRetailValue) || 0)}</b></div>
          {Number(v.buyItNowPrice) > 0 && <div><div className="muted" style={{ fontSize: 10.5, textTransform: "uppercase", letterSpacing: ".06em" }}>Buy now</div><b className="tnum" style={{ fontSize: 15 }}>{fmtUSD(Number(v.buyItNowPrice))}</b></div>}
          <span className="spacer" />
          <span className="mono muted" style={{ fontSize: 11 }}>Lot {v.lotNumber}</span>
        </div>
      </div>
    </div>
  );
}

function CopartDetailModal({ v, onClose }) {
  const [images, setImages] = useState(null);
  const [imgIdx, setImgIdx] = useState(0);
  useEffect(() => {
    if (!v.imageUrl) { setImages([]); return; }
    fetch("/api/copart/images", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ url: v.imageUrl }) })
      .then((r) => r.json())
      .then((d) => setImages(d.success && Array.isArray(d.images) ? d.images.slice(0, 12) : []))
      .catch(() => setImages([]));
  }, [v.lotNumber]);
  const gallery = images && images.length ? images : (copartThumb(v) ? [copartFull(copartThumb(v)) || copartThumb(v)] : []);
  const row = (l, val) => (val || val === 0) && String(val).trim() !== "" ? <div className="row gap-8" style={{ padding: "5px 0", borderTop: "1px solid var(--border)", fontSize: 13 }}><span className="muted" style={{ minWidth: 130 }}>{l}</span><span style={{ fontWeight: 600 }}>{val}</span></div> : null;
  const wa = `https://wa.me/18576055533?text=${encodeURIComponent(`Carzello sourcing request — Copart lot ${v.lotNumber}: ${copartTitle(v)}, VIN ${v.vin || "n/a"}. Please quote landed cost.`)}`;
  return (
    <Modal onClose={onClose} label={copartTitle(v)}>
      <div className="mhead">
        <Pill kind="red" style={{ fontSize: 10 }}>COPART DATA</Pill>
        <b style={{ fontSize: 15 }}>{copartTitle(v)}</b>
        <button className="iconbtn sm" aria-label="Close" style={{ marginInlineStart: "auto" }} onClick={onClose}><I.x width="14" height="14" /></button>
      </div>
      <div className="mbody col gap-12" style={{ maxHeight: "62vh", overflowY: "auto" }}>
        {(() => { const s = copartSale(v); return (
          <div className={"feedback " + (s && s.inDays <= 2 && s.inDays >= 0 ? "warn" : "info")} style={{ fontWeight: 700 }}>
            <I.clock width="14" height="14" />
            {s
              ? <>Auction: {s.long}{s.inDays >= 0 ? ` (${s.inDays === 0 ? "today" : s.inDays === 1 ? "tomorrow" : `in ${s.inDays} days`})` : " (sale date passed — may be relisted)"}</>
              : <>Auction not yet scheduled{v.saleStatus ? ` · ${v.saleStatus}` : ""}</>}
          </div>
        ); })()}
        {gallery.length > 0 && (
          <div>
            <div style={{ position: "relative" }}>
              <Photo className="main" src={gallery[imgIdx]} style={{ aspectRatio: "16/9", width: "100%", maxHeight: 300 }} />
              <a className="btn outline sm" href={gallery[imgIdx]} target="_blank" rel="noreferrer"
                style={{ position: "absolute", bottom: 8, insetInlineEnd: 8, background: "rgba(255,255,255,.92)" }}>
                <I.eye width="12" height="12" /> Full size
              </a>
            </div>
            {gallery.length > 1 && (
              <div className="row gap-6" style={{ marginTop: 6, overflowX: "auto" }}>
                {gallery.map((u, i) => <img key={u} src={u} alt="" onClick={() => setImgIdx(i)} style={{ width: 62, height: 46, objectFit: "cover", cursor: "pointer", border: i === imgIdx ? "2px solid var(--brand)" : "1px solid var(--border)" }} />)}
              </div>
            )}
            {images === null && <div className="muted" style={{ fontSize: 11.5, marginTop: 4 }}>Loading photos…</div>}
          </div>
        )}
        <div className="col">
          {row("Lot number", v.lotNumber)}
          {row("VIN", v.vin)}
          {row("Odometer", `${Number(v.odometer || 0).toLocaleString("en-US")} mi (${v.odometerBrand || "—"})`)}
          {row("Primary damage", v.damageDescription)}
          {row("Secondary damage", v.secondaryDamage)}
          {row("Condition", v.runsDrives)}
          {row("Title", v.saleTitleType ? `${v.saleTitleType} (${v.saleTitleState || ""})` : null)}
          {row("Keys", v.hasKeys)}
          {row("Engine", v.engine)}
          {row("Drive", v.drive)}
          {row("Fuel", v.fuelType)}
          {row("Color", v.color)}
          {row("Est. retail value", fmtUSD(Number(v.estRetailValue) || 0))}
          {row("Est. repair cost", Number(v.repairCost) > 0 ? fmtUSD(Number(v.repairCost)) : null)}
          {Number(v.buyItNowPrice) > 0 && row("Copart Buy It Now", fmtUSD(Number(v.buyItNowPrice)))}
          {row("Sale status", v.saleStatus)}
          {row("Sale day", v.dayOfWeek)}
          {row("Yard", v.yardName)}
          {row("Location", v.location ? `${v.location.city}, ${v.location.state} ${v.location.zip}` : null)}
          {row("Seller", v.sellerName)}
          {row("Note", v.specialNote)}
        </div>
        <div className="feedback info" style={{ fontSize: 12 }}><I.shield width="13" height="13" /> Copart sales-data snapshot — not a Carzello auction. Carzello sources this vehicle for you: we inspect, bid or buy at Copart on your behalf, and quote the full landed cost to your port.</div>
      </div>
      <div className="mfoot">
        <button className="btn outline lg" onClick={onClose}>Close</button>
        <a className="btn primary lg" style={{ flex: 1, minWidth: 0, whiteSpace: "nowrap" }} href={wa} target="_blank" rel="noreferrer"><I.offer width="14" height="14" /> Request quote · WhatsApp</a>
      </div>
    </Modal>
  );
}

const COPART_DEFAULT_F = () => ({
  search: "", make: "", model: "", yearMin: "", yearMax: "", odoMax: "", damage: "",
  runs: "", saleStatus: "", state: "", priceMin: "", priceMax: "", buyNowOnly: false,
  saleWithinDays: "", sort: "year",
});
const YEAR_OPTS = Array.from({ length: 28 }, (_, i) => String(2027 - i));

function CopartFilterSelect({ label, value, onChange, children, width = 150 }) {
  return (
    <label className="col" style={{ gap: 3, minWidth: width, flex: 1 }}>
      <span className="muted" style={{ fontSize: 10.5, fontWeight: 700, textTransform: "uppercase", letterSpacing: ".06em" }}>{label}</span>
      <select className="select" value={value} onChange={(e) => onChange(e.target.value)}>{children}</select>
    </label>
  );
}

/* ---- deep-linkable lot modal: ?lot=<lotNumber> (Back button closes) ----
   One global host renders the modal for every grid; opening pushes history. */
let __copartLotCache = null;
function openCopartLot(v) {
  __copartLotCache = v;
  const u = new URL(location.href);
  u.searchParams.set("lot", v.lotNumber);
  history.pushState({ copartLot: String(v.lotNumber) }, "", u);
  window.dispatchEvent(new Event("carzello:lotparam"));
}

function CopartLotModalHost() {
  const [lot, setLot] = useState(null);
  const pushedRef = useRef(false);
  useEffect(() => {
    const sync = () => {
      const p = new URLSearchParams(location.search).get("lot");
      if (!p) { setLot(null); return; }
      pushedRef.current = !!(history.state && history.state.copartLot);
      if (__copartLotCache && String(__copartLotCache.lotNumber) === p) { setLot(__copartLotCache); return; }
      fetch(`/api/copart/sales-data?search=${encodeURIComponent(p)}&limit=1`)
        .then((r) => r.json())
        .then((d) => {
          const v = d.success && d.data.find((x) => String(x.lotNumber) === p);
          setLot(v || null);
          if (!v) closeQuiet();
        })
        .catch(() => setLot(null));
    };
    const closeQuiet = () => {
      const u = new URL(location.href);
      u.searchParams.delete("lot");
      history.replaceState(history.state, "", u);
    };
    sync();
    window.addEventListener("popstate", sync);
    window.addEventListener("carzello:lotparam", sync);
    return () => { window.removeEventListener("popstate", sync); window.removeEventListener("carzello:lotparam", sync); };
  }, []);
  if (!lot) return null;
  const close = () => {
    if (pushedRef.current) history.back(); // we pushed on open → Back closes and restores the list URL
    else {
      const u = new URL(location.href);
      u.searchParams.delete("lot");
      history.replaceState(history.state, "", u);
      setLot(null);
    }
  };
  return <CopartDetailModal v={lot} onClose={close} />;
}

function CopartBrowse() {
  const [f, setF] = useState(COPART_DEFAULT_F);
  const [facets, setFacets] = useState(null);
  const [page, setPage] = useState(1);
  const [resp, setResp] = useState(null);
  const [err, setErr] = useState(null);
  const [busy, setBusy] = useState(true);
  const set = (k) => (v) => setF((p) => ({ ...p, [k]: v }));
  const activeCount = Object.entries(f).filter(([k, v]) => k !== "sort" && v !== "" && v !== false).length;

  useEffect(() => { fetch("/api/copart/facets").then((r) => r.json()).then((d) => d.success && setFacets(d)).catch(() => {}); }, []);

  useEffect(() => {
    const ctrl = { dead: false };
    setBusy(true); setErr(null);
    const params = new URLSearchParams({ page: String(page), limit: "24", sort: f.sort });
    Object.entries(f).forEach(([k, v]) => {
      if (k === "sort" || v === "" || v === false) return;
      params.set(k, v === true ? "1" : String(v).trim());
    });
    if (f.buyNowOnly) params.set("buyNowOnly", "1");
    const t = setTimeout(() => {
      fetch("/api/copart/sales-data?" + params.toString())
        .then((r) => r.json())
        .then((d) => { if (ctrl.dead) return; if (!d.success) throw new Error(d.message || "Failed"); setResp(d); setBusy(false); })
        .catch(() => { if (!ctrl.dead) { setErr("Copart data is temporarily unavailable — try again in a minute."); setBusy(false); } });
    }, f.search || f.model ? 400 : 0);
    return () => { ctrl.dead = true; clearTimeout(t); };
  }, [f, page]);

  useEffect(() => { setPage(1); }, [f]);
  const pg = resp && resp.pagination;
  const fac = (name) => (facets && facets[name]) || [];

  return (
    <div className="fadein col gap-14">
      <div className="card card-pad row gap-10 wrap">
        <Pill kind="red">COPART DATA</Pill>
        <div className="muted" style={{ fontSize: 12.5, flex: 1, minWidth: 260 }}>
          Live snapshot of Copart US listings ({pg ? pg.total.toLocaleString("en-US") : "…"} lots{activeCount ? " matching" : ""}). Sourcing candidates — Carzello inspects and bids at Copart on your behalf, then ships to your port.
        </div>
      </div>

      <div className="card card-pad col gap-10">
        <div className="row gap-8 wrap">
          <div className="topsearch" style={{ flex: 2, minWidth: 220, maxWidth: "none", margin: 0 }}>
            <I.search width="15" height="15" />
            <input placeholder="Search make, model, VIN, lot…" value={f.search} onChange={(e) => set("search")(e.target.value)} aria-label="Search Copart inventory" />
          </div>
          <input className="input" style={{ flex: 1, minWidth: 130 }} placeholder="Model (e.g. CAMRY)" value={f.model} onChange={(e) => set("model")(e.target.value)} aria-label="Model" />
          <CopartFilterSelect label="Sort" value={f.sort} onChange={set("sort")} width={170}>
            <option value="year">Newest year</option>
            <option value="sale">Auction soonest</option>
            <option value="priceAsc">Est. retail: low → high</option>
            <option value="priceDesc">Est. retail: high → low</option>
            <option value="odo">Lowest miles</option>
          </CopartFilterSelect>
        </div>
        <div className="row gap-8 wrap">
          <CopartFilterSelect label="Make" value={f.make} onChange={set("make")}>
            <option value="">All makes</option>
            {fac("makes").map((m) => <option key={m.v} value={m.v}>{m.v} ({m.c.toLocaleString("en-US")})</option>)}
          </CopartFilterSelect>
          <CopartFilterSelect label="Year from" value={f.yearMin} onChange={set("yearMin")} width={110}>
            <option value="">Any</option>{YEAR_OPTS.map((y) => <option key={y}>{y}</option>)}
          </CopartFilterSelect>
          <CopartFilterSelect label="Year to" value={f.yearMax} onChange={set("yearMax")} width={110}>
            <option value="">Any</option>{YEAR_OPTS.map((y) => <option key={y}>{y}</option>)}
          </CopartFilterSelect>
          <CopartFilterSelect label="Max odometer" value={f.odoMax} onChange={set("odoMax")} width={130}>
            <option value="">Any</option>
            {[25000, 50000, 75000, 100000, 150000, 200000].map((o) => <option key={o} value={o}>≤ {o.toLocaleString("en-US")} mi</option>)}
          </CopartFilterSelect>
          <CopartFilterSelect label="Condition" value={f.runs} onChange={set("runs")} width={150}>
            <option value="">Any condition</option>
            <option value="drive">Run & Drive verified</option>
            <option value="starts">Starts (or better)</option>
          </CopartFilterSelect>
        </div>
        <div className="row gap-8 wrap">
          <CopartFilterSelect label="Primary damage" value={f.damage} onChange={set("damage")} width={170}>
            <option value="">Any damage</option>
            {fac("damages").map((d) => <option key={d.v} value={d.v}>{d.v} ({d.c.toLocaleString("en-US")})</option>)}
          </CopartFilterSelect>
          <CopartFilterSelect label="Sale status" value={f.saleStatus} onChange={set("saleStatus")} width={140}>
            <option value="">Any status</option>
            {fac("saleStatuses").map((s) => <option key={s.v} value={s.v}>{s.v}</option>)}
          </CopartFilterSelect>
          <CopartFilterSelect label="State" value={f.state} onChange={set("state")} width={100}>
            <option value="">All states</option>
            {fac("states").map((s) => <option key={s.v} value={s.v}>{s.v} ({s.c.toLocaleString("en-US")})</option>)}
          </CopartFilterSelect>
          <CopartFilterSelect label="Est. retail min" value={f.priceMin} onChange={set("priceMin")} width={120}>
            <option value="">Any</option>
            {[5000, 10000, 20000, 30000, 50000, 75000].map((p) => <option key={p} value={p}>{fmtUSD(p)}+</option>)}
          </CopartFilterSelect>
          <CopartFilterSelect label="Est. retail max" value={f.priceMax} onChange={set("priceMax")} width={120}>
            <option value="">Any</option>
            {[10000, 20000, 30000, 50000, 75000, 100000, 150000].map((p) => <option key={p} value={p}>≤ {fmtUSD(p)}</option>)}
          </CopartFilterSelect>
          <CopartFilterSelect label="Auction within" value={f.saleWithinDays} onChange={set("saleWithinDays")} width={130}>
            <option value="">Any time</option>
            <option value="3">Next 3 days</option>
            <option value="7">Next 7 days</option>
            <option value="14">Next 14 days</option>
            <option value="30">Next 30 days</option>
          </CopartFilterSelect>
        </div>
        <div className="row gap-10 wrap">
          <label className="checkline" style={{ padding: 0 }}>
            <input type="checkbox" checked={f.buyNowOnly} onChange={(e) => set("buyNowOnly")(e.target.checked)} />
            <span style={{ fontSize: 13 }}><b>Buy It Now available</b> — lots Carzello can buy immediately, no auction wait</span>
          </label>
          <span className="spacer" />
          {activeCount > 0 && <button className="btn ghost sm" onClick={() => setF(COPART_DEFAULT_F())}>Clear all filters ({activeCount})</button>}
        </div>
      </div>

      {err && <div className="feedback err"><I.alert width="13" height="13" /> {err}</div>}
      {busy && !resp && <div className="muted" style={{ padding: "40px 0", textAlign: "center" }}>Loading Copart inventory…</div>}
      {resp && (
        <>
          <div style={{ opacity: busy ? 0.5 : 1, transition: "opacity .15s" }} className="inv-grid">
            {resp.data.map((v) => <CopartCard key={v._id || v.lotNumber} v={v} onOpen={() => openCopartLot(v)} />)}
          </div>
          {resp.data.length === 0 && <Empty title="No Copart lots match" sub="Try a different make, year, or search term." />}
          {pg && pg.totalPages > 1 && (
            <div className="row gap-10" style={{ justifyContent: "center", marginTop: 6 }}>
              <button className="btn outline sm" disabled={!pg.hasPrevPage || busy} onClick={() => { setPage(pg.prevPage); window.scrollTo({ top: 0, behavior: "smooth" }); }}>← Prev</button>
              <span className="muted tnum" style={{ fontSize: 13 }}>Page {pg.page.toLocaleString("en-US")} of {pg.totalPages.toLocaleString("en-US")}</span>
              <button className="btn outline sm" disabled={!pg.hasNextPage || busy} onClick={() => { setPage(pg.nextPage); window.scrollTo({ top: 0, behavior: "smooth" }); }}>Next →</button>
            </div>
          )}
        </>
      )}
    </div>
  );
}

/* ============================================================
   Curated Copart picks on the ALL tab — temporary merchandising
   while Carzello's own lanes fill up: Lexus LX 570 (2015+) and
   Toyota Land Cruiser (2015+), straight from the Copart dataset.
   Auto-hides after CURATED_UNTIL — extend or remove then.
   ============================================================ */
const CURATED_UNTIL = new Date("2026-09-12T23:59:59Z").getTime(); // 30 days from 2026-08-13
const CURATED_MODELS = [
  { id: "", label: "All models" },
  { id: "lx", label: "Lexus LX 570" },
  { id: "lc", label: "Toyota Land Cruiser" },
  { id: "g", label: "Mercedes-Benz G-Class" },
];
const CURATED_YEARS = ["2015", "2018", "2020", "2022", "2024"];

function CuratedCopart() {
  const [model, setModel] = useState("");
  const [q, setQ] = useState("");
  const [yearMin, setYearMin] = useState("2015");
  const [page, setPage] = useState(1);
  const [resp, setResp] = useState(null);
  const [busy, setBusy] = useState(true);
  const active = Date.now() < CURATED_UNTIL;

  useEffect(() => {
    if (!active) return;
    const ctrl = { dead: false };
    setBusy(true);
    const params = new URLSearchParams({ curated: "1", page: String(page), limit: "12", yearMin });
    if (model) params.set("model", model);
    if (q.trim()) params.set("search", q.trim());
    const t = setTimeout(() => {
      fetch("/api/copart/sales-data?" + params.toString())
        .then((r) => r.json())
        .then((d) => { if (!ctrl.dead && d.success) setResp(d); })
        .catch(() => {})
        .finally(() => { if (!ctrl.dead) setBusy(false); });
    }, q ? 400 : 0);
    return () => { ctrl.dead = true; clearTimeout(t); };
  }, [active, model, q, yearMin, page]);
  useEffect(() => { setPage(1); }, [model, q, yearMin]);

  if (!active || (resp && resp.pagination.total === 0 && !q && !model)) return null;
  const pg = resp && resp.pagination;
  return (
    <div className="col gap-10" style={{ marginBottom: 22 }}>
      <div className="row gap-8 wrap">
        <Pill kind="red">COPART DATA</Pill>
        <b style={{ fontSize: 14.5 }}>LX 570 · Land Cruiser · G-Class — {yearMin} and newer</b>
        <span className="muted" style={{ fontSize: 12 }}>· {pg ? `${pg.total} lots` : "…"} · sourced on request — Carzello bids at Copart for you</span>
      </div>
      <div className="row gap-8 wrap">
        <div className="chips">
          {CURATED_MODELS.map((m) => (
            <button key={m.id} className={"chip " + (model === m.id ? "on" : "")} onClick={() => setModel(m.id)}>{m.label}</button>
          ))}
        </div>
        <span className="spacer" />
        <div className="topsearch" style={{ flex: 1, minWidth: 180, maxWidth: 300, margin: 0 }}>
          <I.search width="14" height="14" />
          <input placeholder="VIN, lot, trim…" value={q} onChange={(e) => setQ(e.target.value)} aria-label="Search curated lots" />
        </div>
        <select className="select" style={{ width: "auto" }} value={yearMin} onChange={(e) => setYearMin(e.target.value)} aria-label="Minimum year">
          {CURATED_YEARS.map((y) => <option key={y} value={y}>{y}+</option>)}
        </select>
      </div>
      {resp && (
        <>
          <div className="inv-grid" style={{ opacity: busy ? 0.5 : 1, transition: "opacity .15s" }}>
            {resp.data.map((v) => <CopartCard key={v.lotNumber} v={v} onOpen={() => openCopartLot(v)} />)}
          </div>
          {resp.data.length === 0 && <Empty title="No lots match" sub="Try a different model, year, or search." />}
          {pg && pg.totalPages > 1 && (
            <div className="row gap-10" style={{ justifyContent: "center" }}>
              <button className="btn outline sm" disabled={!pg.hasPrevPage || busy} onClick={() => setPage(pg.prevPage)}>← Prev</button>
              <span className="muted tnum" style={{ fontSize: 13 }}>Page {pg.page} of {pg.totalPages}</span>
              <button className="btn outline sm" disabled={!pg.hasNextPage || busy} onClick={() => setPage(pg.nextPage)}>Next →</button>
            </div>
          )}
        </>
      )}
    </div>
  );
}

Object.assign(window, { CopartBrowse, CuratedCopart, CopartLotModalHost });
