/* ============================================================
   Carzello — buyer desk: Watchlist, Activity, Purchases,
   Account, Notifications, Sell
   ============================================================ */

/* ---- Watchlist ---- */
function Watchlist() {
  const s = useStore();
  const lots = Object.values(s.lots).filter(L => s.watchlist.has(L.id));
  return (
    <div className="fadein">
      <div className="pagehead"><span className="eyebrow">Buyer desk</span><h1 className="h1">My <span className="accent">Watchlist</span></h1><div className="sub">Vehicles you're tracking. You'll be alerted before they close.</div></div>
      {lots.length === 0
        ? <Empty icon={<I.star width="26" height="26" />} title="Nothing on your watchlist yet" sub="Tap the star on any vehicle to track it here and get closing alerts." action={<button className="btn primary" onClick={() => navigate("/browse")}>Browse inventory</button>} />
        : <div className="inv-grid">{lots.map(L => <ListingCard key={L.id} lot={L} />)}</div>}
    </div>
  );
}

/* ---- Activity (my bids) ---- */
function Activity() {
  const s = useStore();
  const mine = Object.values(s.lots).filter(L => L.yourMax != null);
  const winning = mine.filter(L => L.status === "live" && L.highBidder === "you");
  const outbid = mine.filter(L => L.status === "live" && L.highBidder !== "you");
  const won = mine.filter(L => L.result === "won");
  const lost = mine.filter(L => L.result === "lost");

  return (
    <div className="fadein">
      <div className="pagehead"><span className="eyebrow">Buyer desk</span><h1 className="h1">My <span className="accent">bids</span></h1><div className="sub">Every lane you're active in, live.</div></div>

      <div className="stat-grid" style={{ marginBottom: 22 }}>
        <div className="stat"><div className="l"><I.gavel width="13" height="13" /> Active bids</div><div className="v">{winning.length + outbid.length}</div></div>
        <div className="stat"><div className="l" style={{ color: "var(--green)" }}><I.check width="13" height="13" /> Winning</div><div className="v" style={{ color: "var(--green)" }}>{winning.length}</div></div>
        <div className="stat"><div className="l" style={{ color: "var(--amber)" }}><I.alert width="13" height="13" /> Outbid</div><div className="v" style={{ color: "var(--amber)" }}>{outbid.length}</div></div>
        <div className="stat"><div className="l"><I.tag width="13" height="13" /> Won</div><div className="v">{won.length}</div></div>
      </div>

      {mine.length === 0
        ? <Empty icon={<I.gavel width="24" height="24" />} title="You haven't bid yet" sub="Place a bid or set a proxy max on any lot — it'll show up here with live status." action={<button className="btn primary" onClick={() => navigate("/browse")}>Find a vehicle</button>} />
        : (
          <div className="col gap-20">
            {outbid.length > 0 && <BidSection title="Action needed · outbid" lots={outbid} tone="amber" />}
            {winning.length > 0 && <BidSection title="Winning" lots={winning} tone="green" />}
            {won.length > 0 && <BidSection title="Won" lots={won} tone="green" />}
            {lost.length > 0 && <BidSection title="Lost" lots={lost} tone="muted" />}
          </div>
        )}
    </div>
  );
}

function BidSection({ title, lots, tone }) {
  return (
    <div>
      <div className="section-h"><h2 className="h2" style={{ fontSize: 16 }}>{title}</h2><span className="muted">{lots.length}</span></div>
      <div className="tablewrap">
        <table className="ltable">
          <thead><tr><th>Vehicle</th><th className="hide-sm">AutoGrade</th><th>{lots[0]?.status === "live" ? "Current" : "Final"}</th><th className="hide-sm">Your max</th><th>Status</th><th></th></tr></thead>
          <tbody>
            {lots.map(L => {
              const mine = L.highBidder === "you";
              const status = L.result === "won" ? <Pill kind="green">Won</Pill> : L.result === "lost" ? <Pill kind="red">Lost</Pill> : mine ? <Pill kind="green">Winning</Pill> : <Pill kind="amber">Outbid</Pill>;
              return (
                <tr key={L.id} style={{ cursor: "pointer" }} {...clickable(() => navigate(`/lot/${L.id}`), `${L.year} ${L.make} ${L.model}`)}>
                  <td><b>{L.year} {L.make} {L.model}</b><div className="muted" style={{ fontSize: 12 }}>{L.trim} · {L.id}</div></td>
                  <td className="hide-sm"><GradeChip score={L.autograde} /></td>
                  <td className="tnum" style={{ fontWeight: 700, color: mine ? "var(--green)" : "inherit" }}>{fmtUSD(L.highBid)}</td>
                  <td className="hide-sm tnum">{fmtUSD(L.yourMax)}</td>
                  <td>{status}{L.status === "live" && <div className="muted" style={{ fontSize: 11, marginTop: 3 }}><Countdown to={L.endsAt} /></div>}</td>
                  <td style={{ textAlign: "right" }}>
                    {L.result === "won"
                      ? <button className="btn primary sm" onClick={(e) => { e.stopPropagation(); navigate("/purchases"); }}>Checkout</button>
                      : L.status === "live"
                        ? <button className="btn outline sm" onClick={(e) => { e.stopPropagation(); navigate(L.saleType === "live" ? `/live/${L.id}` : `/lot/${L.id}`); }}>{mine ? "View" : "Re-bid"}</button>
                        : <I.chevron width="14" height="14" style={{ color: "var(--fg-4)" }} />}
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    </div>
  );
}

/* ---- Purchases + checkout ---- */
const STAGE_INFO = [
  { key: "payment", label: "Payment" },
  { key: "title", label: "Title" },
  { key: "shipping", label: "Shipping" },
  { key: "delivered", label: "Delivered" },
];
function Purchases() {
  const s = useStore();
  useTick(1000); // payment countdowns update without global ticks
  const [open, setOpen] = useState(null);
  const [statement, setStatement] = useState(false);
  return (
    <div className="fadein">
      <div className="pagehead row wrap" style={{ alignItems: "flex-end", gap: 14 }}>
        <div style={{ flex: 1, minWidth: 240 }}><span className="eyebrow">Buyer desk</span><h1 className="h1">My <span className="accent">purchases</span></h1><div className="sub">Pay, track title, and follow each vehicle to your door.</div></div>
        {s.purchases.length > 0 && <button className="btn outline" onClick={() => setStatement(true)}><I.doc width="14" height="14" /> Account statement</button>}
      </div>
      {statement && (
        <PrintDoc title="Account statement" subtitle={s.buyer.name + " · " + new Date().toLocaleDateString()} onClose={() => setStatement(false)}>
          <table className="ltable" style={{ fontSize: 12.5 }}>
            <thead><tr><th>Vehicle</th><th>Won</th><th>Hammer</th><th>Fees</th><th>Extras</th><th>Status</th></tr></thead>
            <tbody>
              {s.purchases.map(p => { const x = Engine.paymentStatus(p); const extras = x.lateFee + x.penalty + x.storageFee + Engine.addonCosts(p).total; return (
                <tr key={p.id}><td>{p.title}<div className="muted" style={{ fontSize: 10.5 }}>{p.lotId || p.id}</div></td><td>{new Date(p.wonTs).toLocaleDateString()}</td><td className="tnum">{fmtUSD(p.final)}</td><td className="tnum">{fmtUSD(p.fees || 0)}</td><td className="tnum">{extras ? fmtUSD(extras) : "—"}</td><td>{x.defaulted ? "Defaulted" : x.paid ? "Paid" : "Due"}</td></tr>
              ); })}
            </tbody>
          </table>
          <div className="feerow total" style={{ marginTop: 10 }}><span>Total paid</span><span className="tnum">{fmtUSD(s.purchases.filter(p => p.paidTs).reduce((a, p) => a + Engine.paymentStatus(p).amountDue + (p.lateFeePaid || 0), 0))}</span></div>
        </PrintDoc>
      )}
      {s.purchases.length === 0
        ? <Empty icon={<I.truck width="24" height="24" />} title="No purchases yet" sub="Win an auction or use Buy Now and it'll appear here with full checkout tracking." />
        : <div className="col gap-14">{s.purchases.map(p => <PurchaseCard key={p.id} p={p} open={open === p.id} onToggle={() => setOpen(open === p.id ? null : p.id)} />)}</div>}
    </div>
  );
}
function GatePass({ p }) {
  const { t } = useT();
  return (
    <div style={{ border: "2px solid var(--brand)", background: "var(--brand-soft)", padding: 14 }}>
      <div className="row gap-8" style={{ marginBottom: 8 }}><I.doc width="15" height="15" style={{ color: "var(--brand)" }} /><b style={{ fontSize: 13.5, textTransform: "uppercase" }}>{t("pay.gatePass")}</b></div>
      <div className="row gap-16 wrap">
        <div><div className="l" style={{ fontSize: 10, textTransform: "uppercase", letterSpacing: ".1em", color: "var(--brand)", fontWeight: 800 }}>{t("pay.passCode")}</div><div className="mono" style={{ fontSize: 18, fontWeight: 700, letterSpacing: ".04em" }}>{p.gatePass.code}</div></div>
        <span className="spacer" />
        <div style={{ textAlign: "right" }}><div className="muted" style={{ fontSize: 11 }}>{t("pay.issued")} {timeAgo(p.gatePass.issuedTs)}</div><div className="muted mono" style={{ fontSize: 11 }}>{p.lotId || p.id} · {p.vin}</div></div>
      </div>
      <div className="muted" style={{ fontSize: 11.5, marginTop: 8 }}>Present this pass at the yard to release {p.title} for {p.dest}.</div>
    </div>
  );
}

function ShipmentTracker({ p }) {
  const vessel = VESSELS[(p.lotId || p.id).charCodeAt(5) % VESSELS.length];
  const base = p.pickedUpTs || p.paidTs || Date.now();
  const eta = base + 26 * 86400000;
  const steps = [
    { l: "Gate released", ts: p.pickedUpTs, done: !!p.pickedUpTs },
    { l: "At port (Houston)", ts: p.pickedUpTs ? p.pickedUpTs + 2 * 86400000 : null, done: p.stage === "shipping" || p.stage === "delivered" },
    { l: `On vessel · ${vessel}`, ts: p.pickedUpTs ? p.pickedUpTs + 5 * 86400000 : null, done: p.stage === "shipping" || p.stage === "delivered" },
    { l: `ETA ${p.dest}`, ts: eta, done: p.stage === "delivered" },
    { l: "Customs cleared · delivered", ts: null, done: p.stage === "delivered" },
  ];
  return (
    <div style={{ border: "1px solid var(--border)", padding: 12 }}>
      <div className="row gap-8" style={{ marginBottom: 8 }}><I.truck width="14" height="14" style={{ color: "var(--brand)" }} /><b style={{ fontSize: 13 }}>Shipment</b><span className="spacer" /><span className="muted mono" style={{ fontSize: 11 }}>ETA {new Date(eta).toLocaleDateString()}</span></div>
      {steps.map((st, i) => (
        <div key={i} className="row gap-8" style={{ padding: "5px 0", fontSize: 12.5 }}>
          <span style={{ width: 16, height: 16, borderRadius: "50%", display: "grid", placeItems: "center", background: st.done ? "var(--green)" : "var(--surface-2)", color: st.done ? "#fff" : "var(--fg-4)", border: st.done ? "0" : "1px solid var(--border-2)", flexShrink: 0 }}>{st.done ? <I.check width="9" height="9" /> : ""}</span>
          <span style={{ color: st.done ? "var(--fg)" : "var(--fg-3)" }}>{st.l}</span>
          <span className="spacer" />
          {st.ts && <span className="muted mono" style={{ fontSize: 10.5 }}>{new Date(st.ts).toLocaleDateString()}</span>}
        </div>
      ))}
      <div style={{ marginTop: 10, borderTop: "1px dashed var(--border)", paddingTop: 8 }}>
        <div className="l" style={{ fontSize: 10, textTransform: "uppercase", letterSpacing: ".1em", color: "var(--fg-3)", fontWeight: 700, marginBottom: 5 }}>Export compliance</div>
        {[
          { l: "AES / EEI filed", v: "ITN X2026" + String((p.lotId || p.id)).replace(/\D/g, "").slice(-6), done: !!p.pickedUpTs },
          { l: "Title to CBP (≥72 working hrs pre-export)", v: "presented", done: p.stage === "shipping" || p.stage === "delivered" },
          { l: "Commercial invoice + certificate of origin", v: "", done: p.stage === "shipping" || p.stage === "delivered" },
          { l: p.region === "KSA" ? "SABER/SASO conformity" : p.region === "UAE" ? "ECAS/MoIAT conformity" : "Destination conformity", v: "", done: p.stage === "delivered" },
        ].map((d, i) => (
          <div key={i} className="row gap-8" style={{ padding: "3px 0", fontSize: 11.5 }}>
            {d.done ? <I.check width="11" height="11" style={{ color: "var(--green)", flexShrink: 0 }} /> : <I.clock width="11" height="11" style={{ color: "var(--fg-4)", flexShrink: 0 }} />}
            <span style={{ color: d.done ? "var(--fg)" : "var(--fg-3)" }}>{d.l}</span>
            {d.v && d.done && <span className="mono muted" style={{ fontSize: 10 }}>{d.v}</span>}
          </div>
        ))}
        <div className="row gap-6" style={{ marginTop: 6, flexWrap: "wrap" }}>
          {["Title scan", "Bill of Lading", "Certificate of origin"].map(d => <Pill key={d} kind="blue" style={{ cursor: "default" }}><I.doc width="10" height="10" /> {d}</Pill>)}
        </div>
      </div>
    </div>
  );
}

function PurchaseCard({ p, open, onToggle }) {
  const { t } = useT();
  const ps = Engine.paymentStatus(p);
  const [claim, setClaim] = useState(false);
  const [printDoc, setPrintDoc] = useState(null); // 'invoice' | 'gatepass'
  const addons = Engine.addonCosts(p);
  const lotRef = p.lotId || p.id;   // defaulted orders are renamed DEF-…; show the real lot id
  const stageIdx = STAGE_INFO.findIndex(x => x.key === p.stage);
  const statePill = ps.defaulted ? <Pill kind="red">{t("pay.defaulted")}</Pill>
    : !ps.paid ? <Pill kind={ps.lateFee > 0 ? "red" : "amber"}>{ps.lateFee > 0 ? t("pay.overdue") : t("pay.due")}</Pill>
      : ps.storageFee > 0 ? <Pill kind="amber">{t("pay.storageAccruing")}</Pill>
        : p.stage === "delivered" ? <Pill kind="green">{t("pay.delivered")}</Pill> : <Pill kind="blue">{t("pay.paid")}</Pill>;
  const headRight = ps.defaulted ? { l: t("pay.penalty"), v: fmtUSD(ps.owedNow) }
    : !ps.paid ? { l: t("pay.totalDue"), v: fmtUSD(ps.owedNow) }
      : ps.storageFee > 0 ? { l: t("pay.storageDue"), v: fmtUSD(ps.storageFee) }
        : { l: t("pay.paid"), v: fmtUSD(ps.amountDue + (ps.lateFee || 0)) };
  return (
    <div className="card card-pad">
      <div className="row gap-12" {...clickable(onToggle, p.title + " — details")} style={{ cursor: "pointer" }}>
        <Photo style={{ width: 88 }} hue={lotRef.charCodeAt(5) * 6} />
        <div style={{ flex: 1 }}>
          <div className="row gap-8"><b style={{ fontSize: 15 }}>{p.title}</b>{statePill}</div>
          <div className="muted" style={{ fontSize: 12.5 }}>{lotRef} · won {timeAgo(p.wonTs)}</div>
          <div className="muted" style={{ fontSize: 12.5 }}><I.truck width="11" height="11" /> {p.dest}</div>
          {/* live payment status line */}
          {!ps.paid && !ps.defaulted && (ps.msToDue > 0
            ? <div style={{ fontSize: 12, color: "var(--amber)", fontWeight: 700, marginTop: 3 }}><I.clock width="11" height="11" /> Pay within {fmtRemaining(ps.msToDue)} · then ${Engine.getState().config.lateFeePerDay}/day late</div>
            : <div style={{ fontSize: 12, color: "var(--red)", fontWeight: 700, marginTop: 3 }}><I.alert width="11" height="11" /> {ps.daysLate}d late · +{fmtUSD(ps.lateFee)} · defaults in {fmtRemaining(ps.msToDefault)}</div>)}
          {ps.defaulted && <div style={{ fontSize: 12, color: "var(--red)", fontWeight: 700, marginTop: 3 }}><I.alert width="11" height="11" /> Vehicle relisted · penalty charged</div>}
          {ps.paid && ps.storageDaysLate > 0 && <div style={{ fontSize: 12, color: "var(--amber)", fontWeight: 700, marginTop: 3 }}><I.alert width="11" height="11" /> {ps.storageDaysLate}d storage · +{fmtUSD(ps.storageFee)}</div>}
        </div>
        <div style={{ textAlign: "right" }}>
          <div className="muted" style={{ fontSize: 11 }}>{headRight.l}</div>
          <div className="tnum" style={{ fontWeight: 800, fontSize: 18, color: ps.owedNow > 0 && !ps.paid ? "var(--red)" : "inherit" }}>{headRight.v}</div>
        </div>
        <I.chevD width="16" height="16" style={{ color: "var(--fg-4)", transform: open ? "rotate(180deg)" : "none", transition: ".2s" }} />
      </div>

      {open && (
        <div className="fadein" style={{ marginTop: 16, borderTop: "1px solid var(--border)", paddingTop: 16 }}>
          <div className="stepper">
            {STAGE_INFO.map((st, i) => (
              <div key={st.key} className={"st " + (i < stageIdx || p.stage === "delivered" ? "done " : "") + (i === stageIdx ? "cur" : "")}>
                <span className="dot">{i < stageIdx || p.stage === "delivered" ? <I.check width="11" height="11" /> : i + 1}</span>{st.label}
              </div>
            ))}
          </div>
          <div className="row gap-20 wrap" style={{ marginTop: 8 }}>
            <div style={{ flex: 1, minWidth: 230 }}>
              <div className="feerow"><span>{t("pay.winningBid")}</span><span className="tnum">{fmtUSD(p.final)}</span></div>
              <div className="feerow"><span>{t("pay.buyerFees")}</span><span className="tnum">{fmtUSD(p.fees || 0)}</span></div>
              {addons.assurance > 0 && <div className="feerow"><span>Sayarah Assurance <span className="dim">buyback</span></span><span className="tnum">{fmtUSD(addons.assurance)}</span></div>}
              {addons.psi > 0 && <div className="feerow"><span>Post-sale inspection</span><span className="tnum">{fmtUSD(addons.psi)}</span></div>}
              {ps.lateFee > 0 && <div className="feerow" style={{ color: "var(--red)" }}><span>{t("pay.lateFee")} ({ps.daysLate}d × ${Engine.getState().config.lateFeePerDay})</span><span className="tnum">{fmtUSD(ps.lateFee)}</span></div>}
              {ps.penalty > 0 && <div className="feerow" style={{ color: "var(--red)" }}><span>{t("pay.defaultPenalty")}</span><span className="tnum">{fmtUSD(ps.penalty)}</span></div>}
              {ps.storageFee > 0 && <div className="feerow" style={{ color: "var(--amber)" }}><span>{t("pay.storage")} ({ps.storageDaysLate}d × ${Engine.getState().config.storagePerDay})</span><span className="tnum">{fmtUSD(ps.storageFee)}</span></div>}
              <div className="feerow total"><span>{ps.defaulted ? t("pay.penalty") : ps.paid ? t("pay.paid") : t("pay.totalDue")}</span><span className="tnum">{fmtUSD(ps.defaulted ? ps.owedNow : ps.paid ? ps.amountDue + ps.lateFee : ps.owedNow)}</span></div>
            </div>
            <div style={{ flex: 1, minWidth: 230 }} className="col gap-10">
              {/* PAYMENT STATE */}
              {ps.defaulted
                ? <div className="feedback err"><I.alert width="13" height="13" /> Payment wasn't cleared within {Engine.getState().config.defaultDays} days. The vehicle has been relisted and a {fmtUSD(ps.penalty)} penalty applied.</div>
                : !ps.paid
                  ? <>
                    <div className={"feedback " + (ps.lateFee > 0 ? "err" : "warn")}>{ps.lateFee > 0
                      ? <><I.alert width="13" height="13" /> {ps.daysLate} day(s) late — ${Engine.getState().config.lateFeePerDay}/day applies. Defaults (relist + penalty) in {fmtRemaining(ps.msToDefault)}.</>
                      : <><I.clock width="13" height="13" /> Pay in full within {fmtRemaining(ps.msToDue)}. After that, ${Engine.getState().config.lateFeePerDay}/day late fee.</>}</div>
                    <div style={{ border: "1px solid var(--border)", padding: 10 }} className="col gap-6">
                      <label className="checkline" style={{ padding: 4 }}><input type="checkbox" checked={!!(p.addons && p.addons.assurance)} onChange={e => Engine.setPurchaseAddon(p.id, "assurance", e.target.checked)} /><span><b>Sayarah Assurance</b> · buyback if the CR was materially wrong <span className="muted">({fmtUSD(Math.max(250, Math.round(p.final * 0.015)))})</span></span></label>
                      <label className="checkline" style={{ padding: 4 }}><input type="checkbox" checked={!!(p.addons && p.addons.psi)} onChange={e => Engine.setPurchaseAddon(p.id, "psi", e.target.checked)} /><span><b>Post-sale inspection</b> · independent re-check before ship, extends arbitration +7 days <span className="muted">($150)</span></span></label>
                    </div>
                    {p.paymentClaimedTs
                      ? <div className="feedback info"><I.clock width="13" height="13" /> Wire transfer reported {timeAgo(p.paymentClaimedTs)} — Carzello is confirming receipt. Your gate pass is issued the moment funds clear.</div>
                      : <>
                        <div className="muted" style={{ fontSize: 12.5 }}>Pay by wire transfer to the account on your invoice, then confirm below.</div>
                        <button className="btn primary lg block" onClick={() => Engine.claimPaymentSent(p.id)}><I.check width="14" height="14" /> I've sent the wire · {fmtUSD(ps.owedNow)}</button>
                      </>}
                  </>
                  : <>
                    <GatePass p={p} />
                    <div className="row gap-6">
                      <button className="btn outline sm" onClick={() => setPrintDoc("invoice")}><I.doc width="12" height="12" /> Invoice</button>
                      <button className="btn outline sm" onClick={() => setPrintDoc("gatepass")}><I.doc width="12" height="12" /> Print gate pass</button>
                    </div>
                    {(ps.pickedUp || p.stage === "shipping" || p.stage === "delivered") && <ShipmentTracker p={p} />}
                    {!ps.pickedUp
                      ? <>
                        <div className={"feedback " + (ps.storageFee > 0 ? "warn" : "info")}>{ps.storageFee > 0
                          ? <><I.alert width="13" height="13" /> {ps.storageDaysLate} day(s) over the {Engine.getState().config.pickupDays}-day pickup grace — ${Engine.getState().config.storagePerDay}/day storage ({fmtUSD(ps.storageFee)}).</>
                          : <><I.clock width="13" height="13" /> Pick up within {fmtRemaining(ps.pickupDueAt - Date.now())} to avoid ${Engine.getState().config.storagePerDay}/day storage.</>}</div>
                        <button className="btn primary block" onClick={() => Engine.pickupPurchase(p.id)}><I.truck width="13" height="13" /> {t("pay.pickup")}</button>
                      </>
                      : p.stage !== "delivered"
                        ? <button className="btn primary block" onClick={() => Engine.advancePurchase(p.id)}><I.check width="13" height="13" /> {{ title: "Confirm title", shipping: "Mark shipped", delivered: "Delivered" }[p.stage]}</button>
                        : <Pill kind="green"><I.check width="12" height="12" /> Delivered to {p.dest}</Pill>}
                  </>}
              {!ps.defaulted && <button className="btn ghost sm" onClick={() => setClaim(true)}>{t("pay.fileArb")}</button>}
            </div>
          </div>
        </div>
      )}
      {claim && <FileClaimModal p={p} onClose={() => setClaim(false)} />}
      {printDoc === "invoice" && (
        <PrintDoc title="Invoice" subtitle={(p.lotId || p.id) + " · " + new Date(p.wonTs).toLocaleDateString()} onClose={() => setPrintDoc(null)}>
          <dl className="kv" style={{ gridTemplateColumns: "auto 1fr", marginBottom: 12 }}>
            <dt>Buyer</dt><dd>{Engine.getState().buyer.name}</dd>
            <dt>Vehicle</dt><dd>{p.title}</dd>
            <dt>VIN</dt><dd className="mono">{p.vin}</dd>
            <dt>Destination</dt><dd>{p.dest}</dd>
          </dl>
          <div className="feerow"><span>Hammer price</span><span className="tnum">{fmtUSD(p.final)}</span></div>
          <div className="feerow"><span>Buyer fees</span><span className="tnum">{fmtUSD(p.fees || 0)}</span></div>
          {addons.total > 0 && <div className="feerow"><span>Add-ons</span><span className="tnum">{fmtUSD(addons.total)}</span></div>}
          {(p.lateFeePaid || 0) > 0 && <div className="feerow"><span>Late fee</span><span className="tnum">{fmtUSD(p.lateFeePaid)}</span></div>}
          <div className="feerow total"><span>Total {ps.paid ? "paid" : "due"}</span><span className="tnum">{fmtUSD(ps.amountDue + (p.lateFeePaid || ps.lateFee || 0))}</span></div>
          {ps.paid && <Pill kind="green" style={{ marginTop: 10 }}><I.check width="11" height="11" /> Paid {new Date(p.paidTs).toLocaleDateString()}</Pill>}
          <div style={{ marginTop: 16, border: "1px solid var(--border-2)", padding: 12 }}>
            <b style={{ fontSize: 12, textTransform: "uppercase", letterSpacing: ".06em" }}>Federal odometer disclosure (49 CFR Part 580)</b>
            <div className="muted" style={{ fontSize: 11.5, marginTop: 6, lineHeight: 1.55 }}>
              Federal law requires the seller to disclose the mileage upon transfer of ownership. Failure to complete or providing a false statement may result in fines and/or imprisonment.
              Seller certifies that the odometer reading is <b>{(Engine.getState().lots[p.lotId || p.id] || {}).odometerCheck || "Actual"}</b>{((Engine.getState().lots[p.lotId || p.id] || {}).odometerCheck || "Actual") === "Actual" ? " mileage" : ""}.
            </div>
            <div className="row gap-20" style={{ marginTop: 14 }}>
              <div style={{ flex: 1, borderTop: "1px solid var(--fg-3)", paddingTop: 4, fontSize: 10.5 }}>Seller signature · date</div>
              <div style={{ flex: 1, borderTop: "1px solid var(--fg-3)", paddingTop: 4, fontSize: 10.5 }}>Buyer signature · date</div>
            </div>
          </div>
        </PrintDoc>
      )}
      {printDoc === "gatepass" && p.gatePass && (
        <PrintDoc title="Gate pass" subtitle={p.gatePass.code} onClose={() => setPrintDoc(null)}>
          <div style={{ textAlign: "center", padding: "10px 0 16px" }}>
            <div className="mono" style={{ fontSize: 30, fontWeight: 700, letterSpacing: ".06em" }}>{p.gatePass.code}</div>
            <div className="muted" style={{ fontSize: 12 }}>Present at the yard gate · one release per pass</div>
          </div>
          <dl className="kv" style={{ gridTemplateColumns: "auto 1fr" }}>
            <dt>Vehicle</dt><dd>{p.title}</dd>
            <dt>VIN</dt><dd className="mono">{p.vin}</dd>
            <dt>Lot</dt><dd>{p.lotId || p.id}</dd>
            <dt>Authorized buyer</dt><dd>{Engine.getState().buyer.name}</dd>
            <dt>Issued</dt><dd>{new Date(p.gatePass.issuedTs).toLocaleString()}</dd>
            <dt>Destination</dt><dd>{p.dest}</dd>
          </dl>
        </PrintDoc>
      )}
    </div>
  );
}

const CLAIM_TYPES = ["Undisclosed defect", "Structural", "Flood / fire", "Odometer", "Title / VIN", "Condition-grade opinion"];
function FileClaimModal({ p, onClose }) {
  const { t } = useT();
  const [reason, setReason] = useState("");
  const [amount, setAmount] = useState("");
  const [type, setType] = useState(CLAIM_TYPES[0]);
  const [err, setErr] = useState(null);
  const [sent, setSent] = useState(false);
  const cfg = Engine.getState().config;
  function submit() {
    if (reason.trim().length < 4) return;
    const r = Engine.addClaim({ lot: p.lotId || p.id, title: p.title, type, reason: reason.trim().slice(0, 500), amount: Number(String(amount).replace(/[^\d]/g, "")) || 0 });
    if (!r.ok) { setErr(r.reason); return; }
    setSent(true);
  }
  return (
    <Modal onClose={onClose} label={t("claim.title")}>
      <div className="mhead"><span className="iconbtn sm" style={{ background: "var(--amber-soft)", color: "var(--amber)", border: 0 }}><I.shield width="15" height="15" /></span><b style={{ fontSize: 16 }}>{t("claim.title")}</b><button className="iconbtn sm" aria-label="Close" style={{ marginInlineStart: "auto" }} onClick={onClose}><I.x width="14" height="14" /></button></div>
      {sent
        ? <><div className="mbody"><div className="feedback ok"><I.check width="13" height="13" /> Claim filed for {p.title}. Our arbitration team responds within the 48-hour SLA.</div></div><div className="mfoot"><button className="btn primary block" onClick={onClose}>Done</button></div></>
        : <>
          <div className="mbody col gap-12">
            <div className="muted" style={{ fontSize: 13 }}>{p.title} · {p.lotId || p.id} · {Math.round((cfg.arbitrationWindowH + ((p.addons && p.addons.psi) ? cfg.psiExtensionH : 0)) / 24)}-day window from delivery{p.addons && p.addons.psi ? " (extended by PSI)" : ""} · min defect {fmtUSD(cfg.claimMinAmount)}{(p.final || 0) >= 50000 ? ` (2% on $50k+ vehicles)` : ""}.</div>
            <div className="field"><label>Claim type</label><select className="select" value={type} onChange={e => { setErr(null); setType(e.target.value); }}>{CLAIM_TYPES.map(x => <option key={x}>{x}</option>)}</select></div>
            <div className="field"><label>{t("claim.issue")}</label><textarea className="input" rows={3} maxLength={500} value={reason} onChange={e => setReason(e.target.value)} placeholder="e.g. Undisclosed transmission slip — cite the specific defect and repair estimate" /></div>
            <div className="field"><label>{t("claim.amount")}</label><input className="input" value={amount} onChange={e => { setErr(null); setAmount(e.target.value); }} inputMode="numeric" placeholder="0" /></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("confirm.cancel")}</button><button className="btn primary" style={{ flex: 2 }} disabled={reason.trim().length < 4} onClick={submit}><I.shield width="13" height="13" /> {t("claim.submit")}</button></div>
        </>}
    </Modal>
  );
}

/* ---- Notifications ---- */
function Notifications() {
  const s = useStore();
  useEffect(() => { Engine.markNotifsRead(); }, []);
  const ic = (k) => k === "win" || k === "buynow" ? <I.check width="15" height="15" /> : k === "outbid" ? <I.alert width="15" height="15" /> : k === "lost" ? <I.x width="15" height="15" /> : k === "snipe" ? <I.clock width="15" height="15" /> : <I.gavel width="15" height="15" />;
  const tone = (k) => k === "win" || k === "buynow" ? "green" : k === "outbid" || k === "snipe" ? "amber" : k === "lost" ? "red" : "blue";
  return (
    <div className="fadein">
      <div className="pagehead"><span className="eyebrow">Buyer desk</span><h1 className="h1"><span className="accent">Notifications</span></h1></div>
      {s.notifications.length === 0
        ? <Empty icon={<I.bell width="24" height="24" />} title="No notifications yet" sub="Bid activity, outbids, wins, and shipping updates will appear here." />
        : <div className="tablewrap">{s.notifications.map(n => (
          <div key={n.id} className="row gap-12" style={{ padding: "13px 16px", borderBottom: "1px solid var(--border)", cursor: n.lotId ? "pointer" : "default" }} {...(n.lotId ? clickable(() => navigate(`/lot/${n.lotId}`), n.title) : {})}>
            <span className={"tic"} style={{ background: `var(--${tone(n.kind)}-soft, var(--surface-2))`, color: `var(--${tone(n.kind) === "blue" ? "brand" : tone(n.kind)})`, width: 34, height: 34, borderRadius: 9, display: "grid", placeItems: "center", flexShrink: 0 }}>{ic(n.kind)}</span>
            <div style={{ flex: 1 }}><b style={{ fontSize: 13.5 }}>{n.title}</b><div className="muted" style={{ fontSize: 12.5 }}>{n.body}</div>
              {(n.channels || []).length > 1 && <div className="row gap-6" style={{ marginTop: 5 }}>{n.channels.filter(c => c !== "app").map(c => <Pill key={c} kind="green" style={{ fontSize: 9.5, padding: "1px 7px" }}><I.check width="9" height="9" /> {c === "whatsapp" ? "WhatsApp" : "Email"}</Pill>)}<span className="muted" style={{ fontSize: 10.5 }}>delivered</span></div>}
            </div>
            <span className="muted mono" style={{ fontSize: 11 }}>{timeAgo(n.ts)}</span>
          </div>
        ))}</div>}
    </div>
  );
}

/* ---- Account ---- */
function Account() {
  const s = useStore();
  const user = useAuthUser();
  const activeBids = Object.values(s.lots).filter(L => L.yourMax != null && L.status === "live").length;
  const displayName = (user && (user.displayName || user.email)) || s.buyer.name || "Guest";
  const initials = displayName.trim().split(/[\s@.]+/).filter(Boolean).slice(0, 2).map(w => w[0]).join("").toUpperCase() || "?";
  return (
    <div className="fadein">
      <div className="pagehead"><span className="eyebrow">Buyer desk</span><h1 className="h1">My <span className="accent">account</span></h1></div>
      <div className="row gap-16 wrap">
        <div className="card card-pad row gap-12" style={{ flex: 1, minWidth: 260 }}>
          <div className="avatar" style={{ width: 52, height: 52, fontSize: 19 }}>{initials}</div>
          {user
            ? <div><b style={{ fontSize: 16 }}>{displayName}</b><div className="muted" style={{ fontSize: 13 }}>{user.email}</div><Pill kind="green" style={{ marginTop: 6 }}><I.shield width="11" height="11" /> Registered buyer</Pill></div>
            : <div><b style={{ fontSize: 16 }}>Guest</b><div className="muted" style={{ fontSize: 13 }}>Sign in to bid, watch, and buy.</div><button className="btn primary sm" style={{ marginTop: 8 }} onClick={() => requireAuth()}>Sign in</button></div>}
        </div>
        <div className="stat" style={{ flex: 1, minWidth: 220 }}>
          <div className="l"><I.bolt width="13" height="13" /> Buying power</div>
          <div className="v">{fmtUSD(Engine.availablePower())}</div>
          <div className="s">{s.wallet.deposit > 0
            ? <>{fmtUSD(s.wallet.deposit)} confirmed deposit × {s.wallet.multiplier} = {fmtUSD(s.buyingPower)} · {fmtUSD(Engine.committed())} committed</>
            : "No confirmed deposit yet."}</div>
          <div className="muted" style={{ fontSize: 12, marginTop: 8 }}>Wire a security deposit to activate bidding — WhatsApp +1 (857) 605-5533 or support@sayarah.io. Buying power is deposit × {s.wallet.multiplier}.</div>
        </div>
        <div className="stat" style={{ flex: 1, minWidth: 160 }}><div className="l"><I.gavel width="13" height="13" /> Active bids</div><div className="v">{activeBids}</div><div className="s">{s.purchases.length} purchases</div></div>
      </div>

      <div className="section-h" style={{ marginTop: 26 }}><h2 className="h2" style={{ fontSize: 17 }}>Preferences</h2></div>
      <div className="card card-pad col gap-14">
        <div className="row gap-12 wrap" style={{ alignItems: "flex-end" }}>
          <div className="field" style={{ flex: 1, minWidth: 220 }}>
            <label>Default shipping destination</label>
            <select className="select" 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>
        <label className="checkline"><input type="checkbox" checked={s.buyer.prefs?.closeAlert !== false} onChange={e => Engine.setBuyerPref("closeAlert", e.target.checked)} />Email me before watched auctions close</label>
        <label className="checkline"><input type="checkbox" checked={s.buyer.prefs?.outbidPush !== false} onChange={e => Engine.setBuyerPref("outbidPush", e.target.checked)} />WhatsApp &amp; push alerts when I'm outbid</label>
        <label className="checkline"><input type="checkbox" checked={!!s.buyer.prefs?.digest} onChange={e => Engine.setBuyerPref("digest", e.target.checked)} />Weekly digest of new matches to my saved searches</label>
        <div className="muted" style={{ fontSize: 11.5 }}>These control which channels high-intent alerts (outbid, closing, new match) fan out to.</div>
      </div>

      <div className="section-h" style={{ marginTop: 26 }}><h2 className="h2" style={{ fontSize: 17 }}>Saved searches</h2></div>
      <div className="card card-pad col gap-8">
        {s.savedSearches.length === 0
          ? <div className="muted" style={{ fontSize: 12.5 }}>No saved searches yet — save one from the Buy page to get match alerts.</div>
          : 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)" }} /><b style={{ fontSize: 13.5 }}>{ss.name}</b>
              <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"} aria-label="Toggle alerts" 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={() => { try { sessionStorage.setItem("sayarah.applySearch", JSON.stringify(ss.query)); } catch (e) {} navigate("/browse"); }}>View</button>
              <button className="iconbtn sm" title="Remove" aria-label="Remove saved search" onClick={() => Engine.removeSearch(ss.id)}><I.x width="12" height="12" /></button>
            </div>
          ))}
      </div>

      <div className="section-h" style={{ marginTop: 26 }}><h2 className="h2" style={{ fontSize: 17 }}>Portals</h2></div>
      <div className="row gap-14 wrap">
        <div className="card card-pad row gap-12" style={{ flex: 1, minWidth: 280, alignItems: "center" }}>
          <div style={{ flex: 1 }}><b style={{ fontSize: 14 }}><I.store width="14" height="14" /> Consignor portal</b><div className="muted" style={{ fontSize: 13 }}>Sell your cars through Sayarah — list, track sales, get paid.</div></div>
          <a className="btn outline" href="#/consignor"><I.store width="14" height="14" /> Open</a>
        </div>
        <div className="card card-pad row gap-12" style={{ flex: 1, minWidth: 280, alignItems: "center" }}>
          <div style={{ flex: 1 }}><b style={{ fontSize: 14 }}><I.shield width="14" height="14" /> Operator console</b><div className="muted" style={{ fontSize: 13 }}>Inventory, auctions, orders, dealers, staff &amp; reports.</div></div>
          <a className="btn primary" href="#/admin"><I.cog width="14" height="14" /> Open</a>
        </div>
      </div>

      <div className="row gap-10" style={{ marginTop: 26 }}>
        {FB.enabled && FB.currentUser() && (
          <button className="btn outline" onClick={() => FB.signOut()}><I.shield width="13" height="13" /> Sign out ({FB.currentUser().email})</button>
        )}
        <button className="btn outline" onClick={() => { if (confirm("Reset all local data (watchlist, bids, purchases)?")) { localStorage.removeItem("sayarah.clear.v1"); location.reload(); } }}>Reset local data</button>
      </div>
    </div>
  );
}

/* ---- Sell (list a vehicle) ---- */
function Sell() {
  const [done, setDone] = useState(false);
  const [form, setForm] = useState({ year: "", make: "", model: "", vin: "", mileage: "", reserve: "" });
  const set = (k) => (e) => setForm(f => ({ ...f, [k]: e.target.value }));
  const ready = form.year && form.make && form.model && form.vin.length >= 11;
  if (done) return (
    <div className="fadein"><Empty icon={<I.check width="26" height="26" />} title="Listing submitted for inspection"
      sub={`Your ${form.year} ${form.make} ${form.model} is queued. An inspector will grade it and it goes live within 24 hours.`}
      action={<div className="row gap-10"><button className="btn primary" onClick={() => navigate("/browse")}>Back to inventory</button><button className="btn outline" onClick={() => { setDone(false); setForm({ year: "", make: "", model: "", vin: "", mileage: "", reserve: "" }); }}>List another</button></div>} />
    </div>
  );
  return (
    <div className="fadein">
      <div className="pagehead"><span className="eyebrow">Seller</span><h1 className="h1">List a <span className="accent">vehicle</span></h1><div className="sub">Reserve equals your floor. An independent inspector assigns the AutoGrade and condition report — no free-text disclosures.</div></div>
      <div className="card card-pad col gap-14" style={{ maxWidth: 620 }}>
        <div className="row gap-12 wrap">
          <div className="field" style={{ flex: 1, minWidth: 100 }}><label>Year</label><input className="input" value={form.year} onChange={set("year")} placeholder="2021" inputMode="numeric" /></div>
          <div className="field" style={{ flex: 2, minWidth: 140 }}><label>Make</label><input className="input" value={form.make} onChange={set("make")} placeholder="Toyota" /></div>
          <div className="field" style={{ flex: 2, minWidth: 140 }}><label>Model</label><input className="input" value={form.model} onChange={set("model")} placeholder="Land Cruiser" /></div>
        </div>
        <div className="field"><label>VIN</label><input className="input mono" value={form.vin} onChange={set("vin")} placeholder="17-character VIN" maxLength={17} /></div>
        <div className="row gap-12 wrap">
          <div className="field" style={{ flex: 1, minWidth: 160 }}><label>Mileage</label><input className="input" value={form.mileage} onChange={set("mileage")} placeholder="56,800" inputMode="numeric" /></div>
          <div className="field" style={{ flex: 1, minWidth: 160 }}><label>Reserve (USD)</label><input className="input" value={form.reserve} onChange={set("reserve")} placeholder="No reserve" inputMode="numeric" /></div>
        </div>
        <div className="feedback info"><I.camera width="13" height="13" /> Photos & condition report are captured by our inspector at intake.</div>
        <button className="btn primary lg block" disabled={!ready} onClick={() => requireAuth(() => {
          const u = FB.currentUser();
          FB.opsPush("listing", {
            id: "LR-" + Date.now().toString(36).toUpperCase(), source: "seller-page",
            email: u.email, contact: u.displayName || u.email, business: "",
            year: form.year, make: form.make, model: form.model, vin: form.vin,
            mileage: form.mileage, reserve: form.reserve, status: "pending", ts: Date.now(),
          });
          Engine.notify("admin", null, "Seller listing request", `${form.year} ${form.make} ${form.model} — review in Admin → Consignors.`);
          setDone(true);
        })}><I.upload width="14" height="14" /> Submit for inspection</button>
      </div>
    </div>
  );
}

Object.assign(window, { Watchlist, Activity, Purchases, Notifications, Account, Sell });
