/* ============================================================
   Carzello — market screens: Browse, Lot (VDP), Live room
   ============================================================ */

/* ---- fee structure (all disclosed before bid) ----
   Fixed: $345 buyer fee + $170 title & inspection.
   Freight: from the monthly rate sheet uploaded in admin (per destination, and
   per vehicle body type when the sheet includes those columns). */
function buyFeeFor() { return BUYER_FEE; }
function feeBreakdown(lot, amt, shipCode) {
  const dest = SHIP_DEST.find(s => s.code === shipCode) || SHIP_DEST[0];
  const buyFee = BUYER_FEE;
  const titleFee = TITLE_INSPECTION_FEE, inspection = 0; // combined into titleFee
  const freight = Engine.freightQuoted(lot, shipCode); // margin-loaded quote shown to buyer
  const econ = destEcon(shipCode);
  const duty = Math.round(amt * econ.duty);
  const vat = Math.round((amt + duty + freight) * econ.vat);   // VAT on CIF+duty, simplified
  const dutyRate = econ.duty + econ.vat;
  const subtotalUS = amt + buyFee + titleFee + inspection;
  const landed = subtotalUS + freight + duty + vat;
  return { buyFee, titleFee, inspection, freight, duty, vat, econ, dutyRate, subtotalUS, landed, dest };
}

/* ============================================================
   Bid controls (shared by VDP panel + live room)
   ============================================================ */
function BidControls({ lot, compact }) {
  const { t } = useT();
  const minNext = Engine.minNextBid(lot);
  const [amt, setAmt] = useState(minNext);
  const [proxy, setProxy] = useState(true);
  const [fb, setFb] = useState(null);     // { type, msg }
  const [confirm, setConfirm] = useState(null); // { type:'proxy'|'exact'|'buynow', amount }
  const live = lot.status === "live" && lot.endsAt - Date.now() > 0;
  const scheduled = lot.status === "scheduled";

  // keep amount at/above the moving minimum when not actively typing high
  useEffect(() => { setAmt(a => (a < minNext ? minNext : a)); }, [minNext]);

  const valid = (live || scheduled) && amt >= minNext;

  // step 1 — request confirmation (bidding requires a signed-in account)
  function requestBid() { requireAuth(() => setConfirm({ type: proxy ? "proxy" : "exact", amount: amt })); }
  function requestBuyNow() { requireAuth(() => setConfirm({ type: "buynow", amount: lot.buyNow })); }

  // step 2 — actually commit
  function commit() {
    const c = confirm; setConfirm(null);
    if (!c) return;
    if (lot.remote) {
      // real shared auction — the bid is processed by the auction server
      setFb({ type: "info", msg: "Placing bid…" });
      const pr = c.type === "buynow" ? Engine.buyNowRemote(lot.id) : Engine.placeBidRemote(lot.id, c.amount, { proxy: c.type === "proxy" });
      pr.then((r) => {
        if (!r.ok) setFb({ type: "err", msg: r.reason });
        else if (r.status === "won") setFb({ type: "ok", msg: "Purchased! See My Purchases." });
        else if (r.status === "winning") setFb({ type: "ok", msg: c.type === "proxy" ? `Proxy max set. You're winning at ${fmtUSD(r.highBid)}.` : "Bid accepted — you're the high bidder." });
        else setFb({ type: "warn", msg: `Placed — but a higher max exists. Current ${fmtUSD(r.highBid)}.` });
        setTimeout(() => setFb(null), 4200);
      });
      return;
    }
    if (c.type === "buynow") {
      const r = Engine.buyNow(lot.id);
      setFb(r.ok ? { type: "ok", msg: "Purchased with Buy Now!" } : { type: "err", msg: r.reason });
    } else {
      const r = Engine.placeBid(lot.id, c.amount, { proxy: c.type === "proxy" });
      if (!r.ok) { setFb({ type: "err", msg: r.reason }); return; }
      if (r.status === "prebid") setFb({ type: "ok", msg: `Pre-bid armed at ${fmtUSD(c.amount)}. It fires when the lane opens.` });
      else if (r.status === "winning") setFb({ type: "ok", msg: c.type === "proxy" ? `Proxy max set. You're winning at ${fmtUSD(r.highBid)}.` : `Bid accepted — you're the high bidder.` });
      else if (r.status === "won") setFb({ type: "ok", msg: "Purchased! See My Purchases." });
      else setFb({ type: "warn", msg: `Placed — but a higher max exists. Current ${fmtUSD(r.highBid)}.` });
    }
    setTimeout(() => setFb(null), 4200);
  }

  const mine = lot.highBidder === "you";

  return (
    <div className="col gap-12">
      {!compact && (
        <div className="seg" style={{ alignSelf: "stretch" }}>
          <button className={proxy ? "on" : ""} style={{ flex: 1 }} onClick={() => setProxy(true)}>{t("bid.proxyMax")}</button>
          <button className={!proxy ? "on" : ""} style={{ flex: 1 }} onClick={() => setProxy(false)}>{t("bid.exact")}</button>
        </div>
      )}
      <div className="bidinput">
        <span className="cur">$</span>
        <input inputMode="numeric" aria-label="Bid amount in dollars" value={amt.toLocaleString("en-US")} disabled={!live && !scheduled}
          onChange={(e) => setAmt(Number(e.target.value.replace(/[^\d]/g, "")) || 0)} />
        <button className="step" disabled={!live && !scheduled} onClick={() => setAmt(a => Math.max(minNext, a - lot.increment))}>–</button>
        <button className="step" disabled={!live && !scheduled} onClick={() => setAmt(a => a + lot.increment)}>+{lot.increment}</button>
        <button className="step" disabled={!live && !scheduled} onClick={() => setAmt(a => a + lot.increment * 5)}>+{lot.increment * 5}</button>
      </div>
      <div className="muted" style={{ fontSize: 12.5 }}>
        Minimum next {proxy ? "max" : "bid"}: <b className="tnum">{fmtUSD(minNext)}</b> · increment {fmtUSD(lot.increment)}
        {mine && <span style={{ color: "var(--green)" }}> · you currently hold the high bid</span>}
      </div>

      <button className="btn primary lg block" disabled={!valid} onClick={requestBid}>
        <I.gavel width="15" height="15" /> {scheduled ? "Place pre-bid" : proxy ? t("bid.setProxy") : t("bid.place")} · {fmtUSD(amt)}
      </button>
      {lot.buyNow && live && (
        <button className="btn outline block" onClick={requestBuyNow}>
          <I.bolt width="13" height="13" /> {t("bid.buyNow")} · {fmtUSD(lot.buyNow)}
        </button>
      )}

      {fb && <div className={"feedback " + fb.type}>{fb.type === "ok" ? <I.check width="13" height="13" /> : <I.alert width="13" height="13" />}{fb.msg}</div>}
      {!fb && scheduled && <div className="feedback info"><I.clock width="13" height="13" /> Lane opens <Countdown to={lot.startsAt} /> — pre-bids arm automatically when it goes live.</div>}
      {!fb && !live && !scheduled && <div className="feedback info">This auction has ended.</div>}
      {!fb && live && <div className="feedback info"><I.shield width="13" height="13" /> Proxy bids stay hidden. The engine bids the minimum needed to keep you on top, up to your max.</div>}

      {confirm && <BidConfirmModal lot={lot} amount={confirm.amount} type={confirm.type} onConfirm={commit} onClose={() => setConfirm(null)} />}
    </div>
  );
}

/* Two-step bid confirmation (bids are binding) */
function BidConfirmModal({ lot, amount, type, onConfirm, onClose }) {
  const { t } = useT();
  const s = useStore();
  const fees = feeBreakdown(lot, amount, s.shipTo);
  const isBuy = type === "buynow";
  const typeLabel = type === "proxy" ? t("confirm.proxy") : type === "buynow" ? t("confirm.buynow") : t("confirm.exact");
  const buyerFees = fees.buyFee + fees.titleFee + fees.inspection;
  return (
    <Modal onClose={onClose}>
      <div className="mhead">
        <span className="iconbtn sm" style={{ background: "var(--brand-soft)", color: "var(--brand)", border: 0 }}>{isBuy ? <I.bolt width="15" height="15" /> : <I.gavel width="15" height="15" />}</span>
        <b style={{ fontSize: 16 }}>{isBuy ? t("confirm.buytitle") : t("confirm.title")}</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-14">
        <div className="muted" style={{ fontSize: 13 }}>{lot.year} {lot.make} {lot.model} · {lot.trim} · {lot.id}</div>

        <div style={{ border: "2px solid var(--brand)", padding: 16, textAlign: "center" }}>
          <div className="l" style={{ fontSize: 11, textTransform: "uppercase", letterSpacing: ".1em", color: "var(--brand)", fontWeight: 800 }}>{typeLabel}</div>
          <div className="big-price tnum" style={{ marginTop: 4 }}>{fmtUSD(amount)}</div>
        </div>

        <div>
          <div className="l" style={{ fontSize: 11, textTransform: "uppercase", letterSpacing: ".08em", color: "var(--fg-3)", fontWeight: 700, marginBottom: 6 }}>{t("confirm.ifwin")}</div>
          <div className="feerow"><span>{typeLabel}</span><span className="tnum">{fmtUSD(amount)}</span></div>
          <div className="feerow"><span>{t("confirm.fees")} <span className="dim">(buy + title + insp.)</span></span><span className="tnum">{fmtUSD(buyerFees)}</span></div>
          <div className="feerow total"><span>{t("confirm.total")}</span><span className="tnum">{fmtUSD(amount + buyerFees)}</span></div>
        </div>

        <div className="feedback warn"><I.shield width="13" height="13" /> {t("confirm.binding")}</div>
      </div>
      <div className="mfoot">
        <button className="btn outline" style={{ flex: 1 }} onClick={onClose}>{t("confirm.cancel")}</button>
        <button className="btn primary" style={{ flex: 2 }} onClick={onConfirm}><I.check width="14" height="14" /> {isBuy ? t("confirm.buy") : t("confirm.place")}</button>
      </div>
    </Modal>
  );
}

/* ============================================================
   Bid panel (VDP right column)
   ============================================================ */
function BidPanel({ lot }) {
  const s = useStore();
  const { t } = useT();
  const fees = feeBreakdown(lot, lot.highBid, s.shipTo);
  const mine = lot.highBidder === "you";
  const live = lot.status === "live";
  const ms = marketSignal(lot.highBid, lot.marketValue);
  return (
    <div className="bidpanel" id="bidpanel">
      <div className="card card-pad col gap-16">
        <div className="row gap-8">
          {live ? <Pill kind="live" dot>{lot.saleType === "live" ? "LIVE AUCTION" : "TIMED AUCTION"}</Pill> : lot.status === "scheduled" ? <Pill kind="blue">SCHEDULED · LANE {lot.lane} · RUN {lot.run}</Pill> : <Pill>{t("c.ended")}</Pill>}
          <span className="spacer" />
          <span className="muted" style={{ fontSize: 12.5 }}><I.eye width="12" height="12" /> {lot.remote ? `${lot.bidCount || 0} ${t("bid.bids")}` : `${lot.competitors.length + (mine ? 1 : 0)} ${t("bid.bidders")}`}</span>
        </div>

        <div className="statline">
          <div>
            <div className="l">{t("bid.current")} · {lot.bidCount} {t("bid.bids")}</div>
            <div className={"big-price tnum " + (mine ? "winning" : "")}>{fmtUSD(lot.highBid)}</div>
          </div>
          <div style={{ textAlign: "right" }}>
            <div className="l">{live ? t("bid.ends") : lot.status === "scheduled" ? "Opens in" : "Result"}</div>
            {live
              ? <Countdown to={lot.endsAt} className="big-price" />
              : lot.status === "scheduled"
                ? <Countdown to={lot.startsAt} className="big-price" />
                : <div className="big-price">{lot.result === "won" ? t("c.won") : lot.result === "lost" ? t("c.lost") : "Closed"}</div>}
          </div>
        </div>

        {/* Market value / good-buy signal (estimate + sold comps) */}
        {lot.marketValue && <MarketEstimate lot={lot} />}

        <div className="row gap-8 wrap">
          {lot.reserve == null
            ? <Pill kind="green"><I.check width="11" height="11" /> {t("bid.noReserve")}</Pill>
            : <Pill kind={lot.reserveMet ? "green" : "amber"}>{lot.reserveMet ? t("bid.reserveMet") : t("bid.reserveNotMet")}</Pill>}
          {mine && <Pill kind="green">{t("bid.winning")}</Pill>}
          {!mine && lot.yourMax && live && <Pill kind="amber">{t("bid.outbid")}</Pill>}
          {lot.extensions > 0 && <Pill kind="live">+{lot.extensions * 2}:00 anti-snipe</Pill>}
        </div>

        {(live || lot.status === "scheduled") && <BidControls lot={lot} />}

        <OfferSection lot={lot} />

        {lot.saleType === "live" && live && (
          <button className="btn sayarah block" onClick={() => navigate(`/live/${lot.id}`)}>
            <I.bolt width="14" height="14" /> {t("bid.enterLive")}
          </button>
        )}
      </div>

      {/* Landed-cost calculator */}
      <div className="card card-pad col gap-10">
        <div className="row gap-8">
          <I.truck width="15" height="15" style={{ color: "var(--brand)" }} />
          <b style={{ fontSize: 14 }}>Landed cost</b>
          <select className="select" aria-label="Shipping destination" style={{ width: "auto", marginLeft: "auto", padding: "6px 28px 6px 10px", fontSize: 12.5 }}
            value={s.shipTo} onChange={(e) => Engine.setShipTo(e.target.value)}>
            {SHIP_DEST.map(d => <option key={d.code} value={d.code}>{d.label}</option>)}
          </select>
        </div>
        <div>
          <div className="feerow"><span>Winning bid (est.)</span><span className="tnum">{fmtUSD(lot.highBid)}</span></div>
          <div className="feerow"><span>Buy fee <span className="dim">disclosed</span></span><span className="tnum">{fmtUSD(fees.buyFee)}</span></div>
          <div className="feerow"><span>Title + inspection</span><span className="tnum">{fmtUSD(fees.titleFee + fees.inspection)}</span></div>
          <div className="feerow"><span>Ocean freight → {fees.dest.code} <span className="dim">{t("fee.approx")}</span></span><span className="tnum">~{fmtUSD(fees.freight)}</span></div>
          <div className="feerow"><span>Import duty <span className="dim">{Math.round(fees.econ.duty * 100)}%</span></span><span className="tnum">{fmtUSD(fees.duty)}</span></div>
          {fees.vat > 0 && <div className="feerow"><span>VAT <span className="dim">{Math.round(fees.econ.vat * 100)}%</span></span><span className="tnum">{fmtUSD(fees.vat)}</span></div>}
          <div className="feerow total"><span>Landed in {fees.dest.code} <span className="dim" style={{ fontWeight: 600 }}>{t("fee.approx")}</span></span><span className="tnum" style={{ textAlign: "end" }}>~{fmtUSD(fees.landed)}{s.buyer.currency !== "USD" && <div style={{ fontSize: 12, color: "var(--fg-3)", fontWeight: 600 }}>≈ {fmtLocal(fees.landed, s.shipTo)}</div>}</span></div>
        </div>
        <div className="row gap-8">
          <span className="muted" style={{ fontSize: 11.5 }}>Show in:</span>
          <div className="seg">
            <button className={s.buyer.currency === "USD" ? "on" : ""} onClick={() => Engine.setBuyerCurrency("USD")} style={{ padding: "4px 10px", fontSize: 10.5 }}>USD</button>
            <button className={s.buyer.currency !== "USD" ? "on" : ""} onClick={() => Engine.setBuyerCurrency(fees.econ.cur)} style={{ padding: "4px 10px", fontSize: 10.5 }}>{fees.econ.cur}</button>
          </div>
        </div>
        {/* Destination eligibility check for the selected lane */}
        {(() => {
          const e = eligibleFor(lot, s.shipTo);
          if (e.ok && !e.warn) return null;
          return e.ok
            ? <div className="feedback warn"><I.alert width="13" height="13" /> {e.warn}.</div>
            : <div className="feedback err"><I.alert width="13" height="13" /> Not eligible for {fees.econ.city}: {e.reason}. Choose another destination.</div>;
        })()}
        {/* Destination margin estimator — the number no US platform can give */}
        {lot.marketValue && eligibleFor(lot, s.shipTo).ok && (() => {
          const retailUSD = Math.round(lot.marketValue * fees.econ.retailFactor);
          const margin = retailUSD - fees.landed;
          return (
            <div style={{ border: "2px solid " + (margin > 0 ? "var(--green)" : "var(--border-2)"), background: margin > 0 ? "var(--green-soft)" : "var(--surface-2)", padding: 12 }}>
              <div className="l" style={{ fontSize: 10.5, textTransform: "uppercase", letterSpacing: ".1em", fontWeight: 800, color: margin > 0 ? "var(--green)" : "var(--fg-3)" }}><I.trend width="11" height="11" /> Est. margin in {fees.econ.city}</div>
              <div className="row gap-10" style={{ marginTop: 4 }}>
                <span style={{ fontSize: 12.5 }}>Retail ≈ <b className="tnum">{fmtUSD(retailUSD)}</b> <span className="muted">({fmtLocal(retailUSD, s.shipTo)})</span></span>
                <span className="spacer" />
                <b className="tnum" style={{ fontSize: 17, color: margin > 0 ? "var(--green)" : "var(--red)" }}>{margin > 0 ? "+" : ""}{fmtUSD(margin)}</b>
              </div>
              <div className="muted" style={{ fontSize: 10.5, marginTop: 4 }}>Local retail estimate from Sayarah destination comps. Not a guarantee.</div>
            </div>
          );
        })()}
        <div className="muted" style={{ fontSize: 11.5, display: "flex", gap: 6 }}><I.info width="12" height="12" style={{ flexShrink: 0, marginTop: 1, color: "var(--amber)" }} /><span>{t("fee.freightNote")} The $345 buyer fee and $170 title &amp; inspection are fixed.</span></div>
      </div>
    </div>
  );
}

/* ============================================================
   Filters (sidebar on desktop, sheet on mobile)
   ============================================================ */
function FiltersBody({ f, set, lots }) {
  const count = (pred) => lots.filter(pred).length;
  const toggleSet = (key, val) => set(p => {
    const next = new Set(p[key]); next.has(val) ? next.delete(val) : next.add(val);
    return { ...p, [key]: next };
  });
  return (
    <>
      <div className="filter-group">
        <div className="filter-h">Quick</div>
        <label className="checkline"><input type="checkbox" checked={f.endingSoon} onChange={() => set(p => ({ ...p, endingSoon: !p.endingSoon }))} />Ending within 1 hour<span className="ct">{count(L => L.status === "live" && L.endsAt - Date.now() < 3600000)}</span></label>
        <label className="checkline"><input type="checkbox" checked={f.noReserve} onChange={() => set(p => ({ ...p, noReserve: !p.noReserve }))} />No reserve<span className="ct">{count(L => L.reserve == null)}</span></label>
        <label className="checkline"><input type="checkbox" checked={f.liveOnly} onChange={() => set(p => ({ ...p, liveOnly: !p.liveOnly }))} />Live lanes only<span className="ct">{count(L => L.saleType === "live")}</span></label>
      </div>
      <div className="filter-group">
        <div className="filter-h">Make</div>
        {MAKES.map(m => <label key={m} className="checkline"><input type="checkbox" checked={f.make.has(m)} onChange={() => toggleSet("make", m)} />{m}<span className="ct">{count(L => L.make === m) || "—"}</span></label>)}
      </div>
      <div className="filter-group">
        <div className="filter-h">Body</div>
        {BODIES.map(b => <label key={b} className="checkline"><input type="checkbox" checked={f.body.has(b)} onChange={() => toggleSet("body", b)} />{b}<span className="ct">{count(L => L.body === b) || "—"}</span></label>)}
      </div>
      <div className="filter-group">
        <div className="filter-h">Year</div>
        <div className="range">
          <input className="input" placeholder="Min" inputMode="numeric" value={f.minYear || ""} onChange={(e) => set(p => ({ ...p, minYear: Number(e.target.value.replace(/\D/g, "")) || 0 }))} />
          <input className="input" placeholder="Max" inputMode="numeric" value={f.maxYear || ""} onChange={(e) => set(p => ({ ...p, maxYear: Number(e.target.value.replace(/\D/g, "")) || 0 }))} />
        </div>
      </div>
      <div className="filter-group">
        <div className="filter-h">Max mileage</div>
        <input type="range" aria-label="Maximum mileage" min="10000" max="150000" step="5000" value={f.maxMiles} style={{ width: "100%", accentColor: "var(--brand)" }} onChange={(e) => set(p => ({ ...p, maxMiles: Number(e.target.value) }))} />
        <div className="row" style={{ justifyContent: "space-between", fontSize: 12 }}><span className="muted">10k</span><b>≤ {Number(f.maxMiles).toLocaleString()} mi</b><span className="muted">150k</span></div>
      </div>
      <div className="filter-group">
        <div className="filter-h">AutoGrade (min)</div>
        <input type="range" aria-label="Minimum AutoGrade" min="0" max="5" step="0.5" value={f.minGrade} style={{ width: "100%", accentColor: "var(--brand)" }} onChange={(e) => set(p => ({ ...p, minGrade: Number(e.target.value) }))} />
        <div className="row" style={{ justifyContent: "space-between", fontSize: 12 }}><span className="muted">Any</span><b>{f.minGrade.toFixed(1)}+</b><span className="muted">5.0</span></div>
      </div>
      <div className="filter-group">
        <div className="filter-h">Max price · USD</div>
        <input type="range" aria-label="Maximum price" min="15000" max="80000" step="2500" value={f.maxPrice} style={{ width: "100%", accentColor: "var(--brand)" }} onChange={(e) => set(p => ({ ...p, maxPrice: Number(e.target.value) }))} />
        <div className="row" style={{ justifyContent: "space-between", fontSize: 12 }}><span className="muted">$15k</span><b>≤ {fmtUSD(f.maxPrice)}</b><span className="muted">$80k</span></div>
      </div>
      <div className="filter-group">
        <div className="filter-h">Title</div>
        {TITLES.map(t => <label key={t} className="checkline"><input type="checkbox" checked={f.title.has(t)} onChange={() => toggleSet("title", t)} />{t}<span className="ct">{count(L => L.title === t) || "—"}</span></label>)}
      </div>
    </>
  );
}

const DEFAULT_FILTERS = () => ({
  make: new Set(), body: new Set(), title: new Set(),
  minGrade: 0, maxPrice: 80000, minYear: 0, maxYear: 0, maxMiles: 150000,
  endingSoon: false, noReserve: false, liveOnly: false,
});

function Browse() {
  const s = useStore();
  const { t } = useT();
  const lots = useMemo(() => Object.values(s.lots).filter(L => !L.hidden), [s]);
  const [q, setQ] = useState("");
  const [sort, setSort] = useState("ending");
  const [chip, setChip] = useState(() => (new URLSearchParams(location.search).get("tab") === "copart" ? "Copart" : "All")); // deep link: /?tab=copart
  const [f, setF] = useState(DEFAULT_FILTERS);
  const [showFilters, setShowFilters] = useState(false);
  const [view, setView] = useState("grid");
  const [laneFilter, setLaneFilter] = useState(null);
  const [limit, setLimit] = useState(48);
  useEffect(() => { setLimit(48); }, [q, chip, laneFilter]); // reset paging when the query changes

  const filtered = useMemo(() => {
    let rows = lots.slice();
    if (q) {
      const t = q.toLowerCase();
      rows = rows.filter(L => `${L.year} ${L.make} ${L.model} ${L.trim} ${L.vin} ${L.id}`.toLowerCase().includes(t));
    }
    if (f.make.size) rows = rows.filter(L => f.make.has(L.make));
    if (f.body.size) rows = rows.filter(L => f.body.has(L.body));
    if (f.title.size) rows = rows.filter(L => f.title.has(L.title));
    if (f.minGrade) rows = rows.filter(L => L.autograde >= f.minGrade);
    if (f.minYear) rows = rows.filter(L => L.year >= f.minYear);
    if (f.maxYear) rows = rows.filter(L => L.year <= f.maxYear);
    if (f.maxMiles < 150000) rows = rows.filter(L => L.mileage <= f.maxMiles);
    rows = rows.filter(L => L.highBid <= f.maxPrice);
    if (f.endingSoon) rows = rows.filter(L => L.status === "live" && L.endsAt - Date.now() < 3600000);
    if (f.noReserve) rows = rows.filter(L => L.reserve == null);
    if (f.liveOnly) rows = rows.filter(L => L.saleType === "live");

    if (laneFilter) rows = rows.filter(L => L.lane === laneFilter && (L.status === "scheduled" || L.status === "live"));
    if (chip === "Ending soon") rows = rows.filter(L => L.endsAt - Date.now() < 3600000);
    else if (chip === "Watching") rows = rows.filter(L => s.watchlist.has(L.id));
    else if (chip === "No reserve") rows = rows.filter(L => L.reserve == null);
    else if (chip === "Sayarah stock") rows = rows.filter(L => L.owned);
    else if (MAKES.includes(chip)) rows = rows.filter(L => L.make === chip);
    else if (BODIES.includes(chip)) rows = rows.filter(L => L.body === chip);

    const cmp = {
      ending: (a, b) => a.endsAt - b.endsAt,
      grade: (a, b) => b.autograde - a.autograde,
      lowprice: (a, b) => a.highBid - b.highBid,
      highprice: (a, b) => b.highBid - a.highBid,
      lowmiles: (a, b) => a.mileage - b.mileage,
    }[sort];
    return rows.sort(cmp);
  }, [lots, q, sort, chip, f, s.watchlist]);

  const activeFilterCount = f.make.size + f.body.size + f.title.size + (f.minGrade ? 1 : 0) + (f.endingSoon ? 1 : 0) + (f.noReserve ? 1 : 0) + (f.liveOnly ? 1 : 0) + (f.maxPrice < 80000 ? 1 : 0);

  function currentSearchQuery() {
    const out = {};
    if (q) out.q = q;
    if (f.make.size === 1) out.make = [...f.make][0];
    if (f.body.size === 1) out.body = [...f.body][0];
    if (f.title.size === 1) out.title = [...f.title][0];
    if (f.minGrade > 0) out.minGrade = f.minGrade;
    if (f.maxPrice < 80000) out.maxPrice = f.maxPrice;
    return out;
  }
  function searchName(qy) {
    const p = [];
    if (qy.make) p.push(qy.make); if (qy.body) p.push(qy.body);
    if (qy.minGrade) p.push("≥" + qy.minGrade.toFixed(1)); if (qy.maxPrice) p.push("≤" + fmtUSD(qy.maxPrice));
    if (qy.title) p.push(qy.title); if (qy.q) p.push(`"${qy.q}"`);
    return p.join(" · ") || "All vehicles";
  }
  function saveCurrentSearch() { const built = currentSearchQuery(); Engine.saveSearch(searchName(built), built); }
  function applyQuery(query) {
    setQ(query.q || "");
    setF({ ...DEFAULT_FILTERS(), make: new Set(query.make ? [query.make] : []), body: new Set(query.body ? [query.body] : []), title: new Set(query.title ? [query.title] : []), minGrade: query.minGrade || 0, maxPrice: query.maxPrice || 80000 });
    setChip("All"); window.scrollTo({ top: 0, behavior: "smooth" });
  }
  function applySavedSearch(ss) { applyQuery(ss.query); }
  // honor a saved-search "View" handed off from the Account page
  useEffect(() => {
    try { const raw = sessionStorage.getItem("sayarah.applySearch"); if (raw) { sessionStorage.removeItem("sayarah.applySearch"); applyQuery(JSON.parse(raw)); } } catch (e) {}
  }, []);

  return (
    <div className="fadein">
      <div className="hero">
        <div className="inner">
          <div className="trust"><span className="d" /><span>{t("hero.trust")}</span></div>
          <span className="eyebrow">{t("hero.eyebrow")}</span>
          <h1 className="h1" style={{ marginTop: 8 }}>{t("hero.title1")} <span className="accent">{t("hero.title2")}</span></h1>
          <div className="sub">{t("hero.sub")}</div>
          <div className="stats">
            <div><div className="n tnum">{lots.length}</div><div className="k">{t("hero.liveLots")}</div></div>
            <div><div className="n tnum">{lots.filter(L => L.saleType === "live").length}</div><div className="k">{t("hero.liveLanes")}</div></div>
            <div><div className="n tnum">{SHIP_DEST.length}</div><div className="k">{t("hero.carsSold")}</div></div>
            <div><div className="n">48h</div><div className="k">{t("hero.arbitration")}</div></div>
          </div>
        </div>
      </div>

      {/* Upcoming lanes (sale calendar rail) */}
      {(() => {
        const upcoming = {};
        lots.forEach(L => { if (L.status === "scheduled") { (upcoming[L.lane] = upcoming[L.lane] || []).push(L); } });
        const lanes = Object.entries(upcoming).sort((a, b) => Math.min(...a[1].map(x => x.startsAt)) - Math.min(...b[1].map(x => x.startsAt)));
        if (!lanes.length && !laneFilter) return null;
        return (
          <div className="card card-pad" style={{ marginBottom: 16 }}>
            <div className="row gap-8" style={{ marginBottom: 10 }}><I.clock width="15" height="15" style={{ color: "var(--brand)" }} /><b>Upcoming lanes</b><span className="spacer" />{laneFilter && <button className="btn ghost sm" onClick={() => setLaneFilter(null)}>Show all inventory</button>}</div>
            {lanes.length === 0
              ? <div className="muted" style={{ fontSize: 12.5 }}>No scheduled lanes right now — timed lots below close on their own clocks.</div>
              : <div className="chips">
                {lanes.map(([lane, ls]) => {
                  const opens = Math.min(...ls.map(x => x.startsAt));
                  return (
                    <button key={lane} className={"lanecard" + (laneFilter === lane ? " on" : "")} onClick={() => setLaneFilter(laneFilter === lane ? null : lane)}>
                      <b>Lane {lane}</b>
                      <span className="muted" style={{ fontSize: 11.5 }}>{ls.length} lots · opens <Countdown to={opens} /></span>
                      <span className="muted" style={{ fontSize: 10.5 }}>{new Date(opens).toLocaleString(undefined, { weekday: "short", hour: "2-digit", minute: "2-digit" })}</span>
                    </button>
                  );
                })}
              </div>}
          </div>
        );
      })()}

      {/* Recently viewed */}
      {(() => {
        let ids = []; try { ids = JSON.parse(localStorage.getItem("sayarah.recent") || "[]"); } catch (e) {}
        const recent = ids.map(id => s.lots[id]).filter(L => L && !L.hidden).slice(0, 6);
        if (!recent.length) return null;
        return (
          <div style={{ marginBottom: 16 }}>
            <div className="row gap-8" style={{ marginBottom: 8 }}><I.eye width="14" height="14" style={{ color: "var(--fg-3)" }} /><b style={{ fontSize: 13.5 }}>Recently viewed</b></div>
            <div className="chips">
              {recent.map(L => (
                <button key={L.id} className="lanecard" onClick={() => navigate(`/lot/${L.id}`)}>
                  <b style={{ fontSize: 12.5 }}>{L.year} {L.make} {L.model}</b>
                  <span className="tnum" style={{ fontSize: 12, fontWeight: 700 }}>{fmtUSD(L.highBid)}</span>
                </button>
              ))}
            </div>
          </div>
        );
      })()}

      {/* chips + sort */}
      <div className="toolbar">
        <div className="chips">
          {["All", "Sayarah stock", "Copart", "Ending soon", "Watching", "No reserve", ...MAKES.slice(0, 4), "SUV", "Pickup"].map(c => {
            const lbl = { "All": t("chip.all"), "Sayarah stock": t("chip.sayarah"), "Ending soon": t("browse.endingSoon"), "Watching": t("chip.watching"), "No reserve": t("chip.noReserve") }[c] || c;
            return <button key={c} className={"chip " + (chip === c ? "on" : "")} onClick={() => setChip(c)}>{lbl}</button>;
          })}
        </div>
        <span className="spacer" />
        <button className="btn outline sm mob-only" onClick={() => setShowFilters(true)}>
          <I.sliders width="14" height="14" /> {t("browse.filters")}{activeFilterCount ? ` · ${activeFilterCount}` : ""}
        </button>
        <select className="select" aria-label="Sort inventory" style={{ width: "auto", paddingRight: 30 }} value={sort} onChange={(e) => setSort(e.target.value)}>
          <option value="ending">{t("sort.ending")}</option>
          <option value="grade">{t("sort.grade")}</option>
          <option value="lowprice">{t("sort.low")}</option>
          <option value="highprice">{t("sort.high")}</option>
          <option value="lowmiles">{t("sort.miles")}</option>
        </select>
      </div>

      {chip === "Copart" ? <CopartBrowse /> : (
      <div className="browse-layout">
        <aside className="card card-pad filters filters-desktop">
          <div className="row gap-8" style={{ marginBottom: 4 }}>
            <I.sliders width="15" height="15" /><b>Filters</b>
            <span className="spacer" />
            {activeFilterCount > 0 && <button className="btn ghost sm" onClick={() => setF(DEFAULT_FILTERS())}>Clear</button>}
          </div>
          <FiltersBody f={f} set={setF} lots={lots} />
        </aside>

        <div>
          {/* count row only when there is Carzello inventory to count — the Copart
              sections carry their own counts, so "0 vehicles" above them reads as broken */}
          {lots.length > 0 && (
          <div className="row" style={{ marginBottom: 14 }}>
            <div><b className="tnum" style={{ fontSize: 18 }}>{filtered.length}</b> <span className="muted">Carzello {t("browse.vehicles")}</span>
              {filtered.filter(L => L.endsAt - Date.now() < 3600000 && L.status === "live").length > 0 &&
                <span style={{ color: "var(--sayarah)", marginLeft: 10, fontWeight: 700, fontSize: 13 }}>· {filtered.filter(L => L.endsAt - Date.now() < 3600000 && L.status === "live").length} ending soon</span>}
            </div>
            <span className="spacer" />
            <div className="seg hide-sm">
              <button className={view === "grid" ? "on" : ""} aria-label="Grid view" aria-pressed={view === "grid"} onClick={() => setView("grid")}><I.grid width="14" height="14" /></button>
              <button className={view === "list" ? "on" : ""} aria-label="List view" aria-pressed={view === "list"} onClick={() => setView("list")}><I.list width="14" height="14" /></button>
            </div>
          </div>
          )}

          {chip === "All" && <CuratedCopart />}
          {filtered.length === 0
            ? (lots.length === 0
              ? <Empty title="More lanes opening soon" sub="Carzello-graded inventory is being inspected now. Create an account and wire your security deposit so you're ready to bid the moment lots go live." action={<button className="btn primary" onClick={() => requireAuth()}>Create your account</button>} />
              : <Empty title="No matching vehicles" sub="Try widening your filters or clearing the search." action={<button className="btn" onClick={() => { setF(DEFAULT_FILTERS()); setQ(""); setChip("All"); }}>Reset filters</button>} />)
            : view === "grid"
              ? <div className="inv-grid">{filtered.slice(0, limit).map(L => <ListingCard key={L.id} lot={L} />)}</div>
              : <div className="col gap-10">{filtered.slice(0, limit).map(L => <RunRow key={L.id} lot={L} />)}</div>}

          {filtered.length > limit && (
            <div style={{ textAlign: "center", marginTop: 18 }}>
              <button className="btn outline" onClick={() => setLimit(l => l + 48)}>Show more · {filtered.length - limit} remaining</button>
            </div>
          )}

          {/* saved searches (real, persistent, with match alerts) */}
          <div className="card card-pad" style={{ marginTop: 20 }}>
            <div className="row gap-8" style={{ marginBottom: 10 }}><I.bell width="15" height="15" style={{ color: "var(--sayarah)" }} /><b>Saved searches</b><span className="spacer" />
              <button className="btn outline sm" onClick={saveCurrentSearch}><I.plus width="13" height="13" /> Save this search</button>
            </div>
            {s.savedSearches.length === 0
              ? <div className="muted" style={{ fontSize: 12.5 }}>Save a search to get an alert (in-app + WhatsApp) the moment a matching car is listed.</div>
              : <div className="col gap-8">
                {s.savedSearches.map(ss => (
                  <div key={ss.id} className="row gap-10" style={{ padding: "8px 0", borderTop: "1px solid var(--border)" }}>
                    <I.search width="13" height="13" style={{ color: "var(--fg-3)" }} />
                    <span style={{ fontWeight: 600, fontSize: 13.5 }}>{ss.name}</span>
                    <span className="muted" style={{ fontSize: 12.5 }}>· {Engine.savedMatchCount(ss.query)} matches</span>
                    <span className="spacer" />
                    <button className="iconbtn sm" title={ss.alerts ? "Alerts on" : "Alerts off"} onClick={() => Engine.toggleSearchAlerts(ss.id)} style={{ color: ss.alerts ? "var(--brand)" : "var(--fg-4)" }}><I.bell width="13" height="13" /></button>
                    <button className="btn ghost sm" onClick={() => applySavedSearch(ss)}>View</button>
                    <button className="iconbtn sm" title="Remove" onClick={() => Engine.removeSearch(ss.id)}><I.x width="12" height="12" /></button>
                  </div>
                ))}
              </div>}
          </div>
        </div>
      </div>
      )}

      {showFilters && (
        <Sheet title="Filters" onClose={() => setShowFilters(false)}>
          <div className="sbody"><FiltersBody f={f} set={setF} lots={lots} /></div>
          <div className="sfoot">
            <button className="btn outline" style={{ flex: 1 }} onClick={() => setF(DEFAULT_FILTERS())}>Clear</button>
            <button className="btn primary" style={{ flex: 2 }} onClick={() => setShowFilters(false)}>Show {filtered.length} vehicles</button>
          </div>
        </Sheet>
      )}
    </div>
  );
}

/* compact list-view row */
function RunRow({ lot }) {
  const mine = lot.highBidder === "you";
  return (
    <div className="runrow" {...clickable(() => navigate(`/lot/${lot.id}`), `${lot.year} ${lot.make} ${lot.model}, ${fmtUSD(lot.highBid)}`)}>
      <Photo className="photo" hue={lot.id.charCodeAt(5) * 6} count={lot.photos} />
      <div className="col gap-4">
        <div className="row gap-8"><b style={{ fontSize: 15 }}>{lot.year} {lot.make} {lot.model}</b><GradeChip score={lot.autograde} />{lot.saleType === "live" && <Pill kind="live" dot>LIVE</Pill>}</div>
        <div className="muted" style={{ fontSize: 12.5 }}>{lot.trim} · {fmtMiles(lot.mileage)} · {lot.drivetrain} · {lot.location}</div>
        <div className="row gap-8"><Pill kind={lot.title === "Clean" ? "green" : "amber"} style={{ fontSize: 10.5 }}>{lot.title}</Pill><span className="muted" style={{ fontSize: 12 }}>Lane {lot.lane} · Run {lot.run}</span></div>
      </div>
      <div className="runprice" style={{ textAlign: "right" }}>
        <div className="muted" style={{ fontSize: 11 }}>{mine ? "Winning" : "High bid"}</div>
        <div className={"tnum " + (mine ? "" : "")} style={{ fontWeight: 800, fontSize: 18, color: mine ? "var(--green)" : "inherit" }}>{fmtUSD(lot.highBid)}</div>
        {lot.status === "live" ? <Countdown to={lot.endsAt} className="" /> : <span className="muted">Ended</span>}
      </div>
    </div>
  );
}

/* ============================================================
   Make Offer / reserve counteroffer
   ============================================================ */
function OfferSection({ lot }) {
  const s = useStore();
  const { t } = useT();
  const [open, setOpen] = useState(false);
  const offer = s.offers.find(o => o.lotId === lot.id && o.status !== "declined");
  const live = lot.status === "live";
  const reserveMiss = lot.status === "ended" && lot.result !== "won" && lot.highBidder === "you" && !lot.reserveMet;

  if (offer && offer.status === "pending")
    return <div className="feedback warn"><I.clock width="13" height="13" /> {t("offer.pending")}</div>;
  if (offer && offer.status === "countered")
    return (
      <div style={{ border: "2px solid var(--amber)", background: "var(--amber-soft)", padding: 14 }} className="col gap-10">
        <div className="row gap-8"><I.offer width="15" height="15" style={{ color: "var(--amber)" }} /><b style={{ fontSize: 14 }}>{t("offer.countered")}</b><span className="spacer" /><span className="tnum" style={{ fontWeight: 800, fontSize: 17 }}>{fmtUSD(offer.counter)}</span></div>
        <div className="row gap-8">
          <button className="btn primary" style={{ flex: 2 }} onClick={() => Engine.acceptCounter(offer.id)}><I.check width="13" height="13" /> {t("offer.acceptCounter")}</button>
          <button className="btn outline" style={{ flex: 1 }} onClick={() => Engine.declineOffer(offer.id)}>{t("offer.decline")}</button>
        </div>
      </div>
    );
  if (offer && offer.status === "accepted")
    return <div className="feedback ok"><I.check width="13" height="13" /> {t("offer.accepted")} · {fmtUSD(offer.amount)} <a href="#/purchases" style={{ marginInlineStart: "auto", fontWeight: 800 }}>{t("c.checkout")} →</a></div>;

  if (reserveMiss)
    return (
      <div className="col gap-10">
        <div className="feedback warn"><I.alert width="13" height="13" /> {t("bid.reserveNotMet")} — {t("offer.sub")}</div>
        <button className="btn primary lg block" onClick={() => requireAuth(() => setOpen(true))}><I.offer width="14" height="14" /> {t("bid.makeOffer")}</button>
        {open && <MakeOfferModal lot={lot} onClose={() => setOpen(false)} />}
      </div>
    );
  if (live)
    return (
      <>
        <button className="btn outline block" onClick={() => requireAuth(() => setOpen(true))}><I.offer width="13" height="13" /> {t("bid.makeOffer")}</button>
        {open && <MakeOfferModal lot={lot} onClose={() => setOpen(false)} />}
      </>
    );
  return null;
}

function MakeOfferModal({ lot, onClose }) {
  const { t } = useT();
  const [amt, setAmt] = useState(() => lot.reserve || Math.round(((lot.marketValue || lot.startPrice) * 0.92) / lot.increment) * lot.increment);
  const [err, setErr] = useState(null);
  function send() { const r = Engine.makeOffer(lot.id, amt); if (!r.ok) { setErr(r.reason); return; } onClose(); }
  return (
    <Modal onClose={onClose}>
      <div className="mhead"><I.offer width="16" height="16" style={{ color: "var(--brand)" }} /><b style={{ fontSize: 16 }}>{t("offer.title")}</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">
        <div className="muted" style={{ fontSize: 13 }}>{lot.year} {lot.make} {lot.model} · {t("offer.sub")}</div>
        <div className="field">
          <label>{t("offer.amount")}</label>
          <div className="bidinput">
            <span className="cur">$</span>
            <input inputMode="numeric" aria-label="Offer amount in dollars" value={amt.toLocaleString("en-US")} onChange={e => { setErr(null); setAmt(Number(e.target.value.replace(/[^\d]/g, "")) || 0); }} />
            <button className="step" onClick={() => setAmt(a => Math.max(0, a - lot.increment))}>–</button>
            <button className="step" onClick={() => setAmt(a => a + lot.increment)}>+{lot.increment}</button>
          </div>
        </div>
        {lot.marketValue && <div className="row gap-8"><span className="muted" style={{ fontSize: 12.5 }}>{t("mkt.value")}: <b className="tnum">{fmtUSD(lot.marketValue)}</b></span><span className="spacer" /><MarketBadge lot={{ ...lot, highBid: amt }} full /></div>}
        {err && <div className="feedback err"><I.alert width="13" height="13" /> {err}</div>}
      </div>
      <div className="mfoot"><button className="btn outline" style={{ flex: 1 }} onClick={onClose}>{t("offer.decline")}</button><button className="btn primary" style={{ flex: 2 }} onClick={send}><I.offer width="13" height="13" /> {t("offer.send")} · {fmtUSD(amt)}</button></div>
    </Modal>
  );
}

Object.assign(window, { BidControls, BidPanel, Browse, RunRow, feeBreakdown, buyFeeFor, OfferSection, MakeOfferModal, BidConfirmModal });
