// ADM-PROC-10 · Responses & gate-ins (AMOMS Module 1)
// Admin Web · Procurement Manager · P0 · 1440×900
// Accept a farmer's offer → creates a gate-in at the farmer's proposed date/time.
// A running total fills toward the requirement target. Registered as window.Pages.responses

const Ic10 = window.Icons;
const KES10 = (n) => "KSh " + (Number(n) || 0).toLocaleString("en-US");
const REQ_10 = { id: "PR-2026-0184", product: "Hass", qty: 28000, ceiling: 95 };

const FARMER_BY_NAME = Object.fromEntries(window.MD.FARMERS.map(f => [f.name, f]));
const tierOf10 = (r) => r >= 4.7 ? "A" : r >= 4.3 ? "B" : "C";

// gate state: new (offer, not yet accepted) · awaiting (gate-in created, farmer not confirmed)
//             · confirmed (farmer accepted, gate pass / QR active) · declined
const initGate = (r) =>
  r.status === "declined" ? "declined"
  : r.status === "shortlist" ? (r.farmer === "F-2731" ? "confirmed" : "awaiting")
  : "new";

const RESP_10 = window.MD.RESPONSES.map(r => {
  const f = FARMER_BY_NAME[r.name] || {};
  return {
    ...r,
    region: (f.village || "").split(",").slice(-1)[0].trim(),
    tier: tierOf10(f.rating || 4),
    init: r.name.split(" ").map(x => x[0]).join(""),
    gate: initGate(r),
  };
});

const rateClass = (rate) => rate <= REQ_10.ceiling ? "ok" : rate <= REQ_10.ceiling * 1.1 ? "warn" : "over";
const fmtDate10 = (d) => new Date(d + "T00:00:00").toLocaleDateString("en-GB", { weekday: "short", day: "numeric", month: "short" });

// Deadline ticker (live state only)
const useDeadline10 = (offsetMs) => {
  const end = useMemo(() => Date.now() + offsetMs, [offsetMs]);
  const [, f] = useState(0);
  useEffect(() => { const t = setInterval(() => f(n => n + 1), 1000); return () => clearInterval(t); }, []);
  const ms = end - Date.now();
  if (ms <= 0) return "0h 0m";
  const h = Math.floor(ms / 36e5), m = Math.floor((ms % 36e5) / 6e4), s = Math.floor((ms % 6e4) / 1e3);
  return `${h}h ${m}m ${s}s`;
};

const Check10 = ({ on }) => <span className={`proc-check${on ? " on" : ""}`}>{on && <Ic10.Check size={11} />}</span>;

// Status pill reflecting the gate-in lifecycle
const GatePill = ({ gate }) => {
  if (gate === "confirmed") return <span className="gi-pill gi-confirmed"><Ic10.CheckCircle size={12} />Gate-in confirmed</span>;
  if (gate === "awaiting")  return <span className="gi-pill gi-awaiting"><Ic10.Clock size={12} />Awaiting farmer</span>;
  if (gate === "declined")  return <span className="gi-pill gi-declined">Declined</span>;
  return <span className="gi-pill gi-new">New offer</span>;
};

const ResponseDashboard = ({ tweaks }) => {
  const toast = useToast();
  const go = window.makeGo(toast);
  const state = (tweaks && tweaks.respState) || "receiving";

  const [q, setQ] = useState("");
  const [statusFilter, setStatusFilter] = useState("All");
  const [sort, setSort] = useState("score");
  const [sel, setSel] = useState(new Set());
  const [rows, setRows] = useState(RESP_10);
  const ticker = useDeadline10(8 * 36e5 + 12 * 6e4);

  const isClosed = state === "closed" || state === "none";
  const noResponses = state === "waiting" || state === "none";

  const shown = rows
    .filter(r => statusFilter === "All" || r.gate === statusFilter)
    .filter(r => !q || r.name.toLowerCase().includes(q.toLowerCase()) || r.region.toLowerCase().includes(q.toLowerCase()))
    .sort((a, b) => sort === "score" ? b.score - a.score : sort === "rate" ? a.rate - b.rate : sort === "qty" ? b.qty - a.qty : a.tier.localeCompare(b.tier));

  // Running total toward the requirement target (accepted = a gate-in exists)
  const acceptedRows = rows.filter(r => r.gate === "awaiting" || r.gate === "confirmed");
  const acceptedQty = acceptedRows.reduce((s, r) => s + r.qty, 0);
  const pct = Math.min(100, Math.round((acceptedQty / REQ_10.qty) * 100));
  const remaining = Math.max(0, REQ_10.qty - acceptedQty);
  const confirmedCount = rows.filter(r => r.gate === "confirmed").length;
  const awaitingCount = rows.filter(r => r.gate === "awaiting").length;

  const toggle = (id) => setSel(s => { const n = new Set(s); n.has(id) ? n.delete(id) : n.add(id); return n; });
  const selCount = sel.size;
  const selNew = [...sel].filter(id => rows.find(r => r.farmer === id)?.gate === "new");

  const accept = (id) => {
    const r = rows.find(x => x.farmer === id);
    setRows(rs => rs.map(x => x.farmer === id ? { ...x, gate: "awaiting" } : x));
    toast({ title: `Gate-in created for ${r.name}`, desc: `${r.qty.toLocaleString("en-US")} kg · ${fmtDate10(r.earliest)} — awaiting farmer confirmation.` });
  };
  const acceptSelected = () => {
    const names = selNew.map(id => rows.find(r => r.farmer === id)?.name);
    setRows(rs => rs.map(r => selNew.includes(r.farmer) ? { ...r, gate: "awaiting" } : r));
    toast({ title: `${selNew.length} gate-in${selNew.length > 1 ? "s" : ""} created`, desc: names.slice(0, 3).join(", ") + (names.length > 3 ? "…" : "") });
    setSel(new Set());
  };
  const reject = (id) => { setRows(rs => rs.map(r => r.farmer === id ? { ...r, gate: "declined" } : r)); toast({ title: "Offer declined" }); };

  // ── Empty states ──
  if (noResponses) {
    return (
      <div className="page">
        <div className="rs-head">
          <button className="btn btn-ghost btn-icon" aria-label="Back" onClick={() => go("ADM-PROC-05.html")}><Ic10.ChevronLeft size={18} /></button>
          <h1 className="rs-title">Responses — <span className="mono" style={{ fontWeight: 600 }}>{REQ_10.id}</span></h1>
        </div>
        <Card><div style={{ padding: "64px 24px", textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }}>
          <div style={{ width: 60, height: 60, borderRadius: 16, background: "var(--avocado-soft)", color: "var(--avocado-fg)", display: "inline-flex", alignItems: "center", justifyContent: "center" }}><Ic10.User size={28} /></div>
          {state === "waiting" ? (
            <>
              <div style={{ fontSize: 18, fontWeight: 600 }}>Waiting for farmer responses</div>
              <div className="muted" style={{ fontSize: 13.5, maxWidth: 420, lineHeight: 1.5 }}>First responses typically arrive within 2–4 hours of a broadcast. We'll refresh this view automatically as they come in.</div>
              <Button variant="outline" icon={Ic10.Eye} style={{ marginTop: 4 }} onClick={() => go("ADM-PROC-09.html")}>Check broadcast status</Button>
            </>
          ) : (
            <>
              <div style={{ fontSize: 18, fontWeight: 600 }}>No responses received</div>
              <div className="muted" style={{ fontSize: 13.5, maxWidth: 420, lineHeight: 1.5 }}>The deadline passed with no farmer offers. You can extend the deadline to keep the window open, or cancel this requirement.</div>
              <div className="row" style={{ marginTop: 4 }}>
                <Button variant="outline" icon={Ic10.Clock} onClick={() => toast({ title: "Extend deadline", desc: "Pick a new response deadline." })}>Extend deadline</Button>
                <Button variant="destructive" icon={Ic10.XCircle} onClick={() => go("ADM-PROC-05.html")}>Cancel requirement</Button>
              </div>
            </>
          )}
        </div></Card>
      </div>
    );
  }

  return (
    <div className="page rs-page">
      <div className="rs-head">
        <button className="btn btn-ghost btn-icon" aria-label="Back" onClick={() => go("ADM-PROC-05.html")}><Ic10.ChevronLeft size={18} /></button>
        <div>
          <h1 className="rs-title">Responses &amp; gate-ins — <span className="mono" style={{ fontWeight: 600 }}>{REQ_10.id}</span></h1>
          <div className="muted" style={{ fontSize: 12.5, marginTop: 2 }}>{REQ_10.product} · {REQ_10.qty.toLocaleString("en-US")} kg target · accept offers to fill it</div>
        </div>
        <StatusBadge status={isClosed ? "closed" : "receiving"} />
        <div className="rs-head-actions">
          <Button variant="outline" icon={Ic10.Layers} disabled={selCount < 2} onClick={() => go("ADM-PROC-11.html")}>Compare</Button>
          <Button variant="primary" icon={Ic10.Calendar} onClick={() => go("ADM-PROC-16.html")}>Gate-in schedule</Button>
        </div>
      </div>

      <div className={`rs-deadline ${isClosed ? "closed" : "live"}`}>
        <Ic10.Clock size={15} />
        {isClosed ? <span>Response deadline passed — accept from the {rows.length} offers received.</span> : <span>Deadline in <b>{ticker}</b> · auto-refreshing every 30s</span>}
      </div>

      {/* Target progress — running total of accepted offers (gate-ins) */}
      <Card className="gi-target">
        <div className="gi-target-top">
          <div>
            <div className="gi-target-label">Accepted toward target</div>
            <div className="gi-target-val">{acceptedQty.toLocaleString("en-US")}<span className="gi-target-of"> / {REQ_10.qty.toLocaleString("en-US")} kg</span></div>
          </div>
          <div className="gi-target-meta">
            <div className="gi-target-chips">
              <span className="gi-chip gi-confirmed"><Ic10.CheckCircle size={13} />{confirmedCount} confirmed</span>
              <span className="gi-chip gi-awaiting"><Ic10.Clock size={13} />{awaitingCount} awaiting farmer</span>
            </div>
            <div className="muted" style={{ fontSize: 12.5, marginTop: 6, textAlign: "right" }}>{remaining > 0 ? `${remaining.toLocaleString("en-US")} kg still to fill` : "Target reached"}</div>
          </div>
        </div>
        <div className="gi-bar"><div className={`gi-bar-fill${pct >= 100 ? " full" : ""}`} style={{ width: pct + "%" }} /></div>
        <div className="gi-bar-foot"><span>{pct}% of target</span><span className="muted">{acceptedRows.length} gate-in{acceptedRows.length !== 1 ? "s" : ""} created</span></div>
      </Card>

      {/* Toolbar */}
      <div className="proc-toolbar">
        <div className="proc-search"><Ic10.Search size={15} /><input className="input" placeholder="Search farmer or region…" value={q} onChange={(e) => setQ(e.target.value)} /></div>
        <select className="select" style={{ width: "auto" }} value={statusFilter} onChange={(e) => setStatusFilter(e.target.value)}>
          <option value="All">All offers</option><option value="new">New offers</option><option value="awaiting">Awaiting farmer</option><option value="confirmed">Confirmed</option><option value="declined">Declined</option>
        </select>
        <select className="select" style={{ width: "auto" }} value={sort} onChange={(e) => setSort(e.target.value)}>
          <option value="score">Sort: Score</option><option value="rate">Sort: Rate (low→high)</option><option value="qty">Sort: Qty (high→low)</option><option value="tier">Sort: Tier</option>
        </select>
        <div style={{ marginLeft: "auto" }}><Button variant="outline" icon={Ic10.Download} onClick={() => toast({ title: "Exported responses (CSV)" })}>Export</Button></div>
      </div>

      <Card>
        <div className="card-body flush">
          <div className="tbl-wrap">
            <table className="tbl">
              <thead><tr>
                <th style={{ width: 36 }}></th><th>Farmer</th><th>Region</th><th className="num">Offered qty</th><th className="num">Rate</th><th>Proposed gate-in</th><th className="num">Score</th><th>Status</th><th className="actions"></th>
              </tr></thead>
              <tbody>
                {shown.map(r => {
                  const on = sel.has(r.farmer);
                  const accepted = r.gate === "awaiting" || r.gate === "confirmed";
                  return (
                    <tr key={r.farmer} className={accepted ? "gi-row-accepted" : ""}>
                      <td onClick={() => r.gate === "new" && toggle(r.farmer)} style={{ cursor: r.gate === "new" ? "pointer" : "default" }}>{r.gate === "new" ? <Check10 on={on} /> : <span style={{ color: "var(--muted-foreground)" }}>{accepted ? <Ic10.Check size={13} /> : ""}</span>}</td>
                      <td><span style={{ display: "inline-flex", alignItems: "center", gap: 8 }}><Avatar initials={r.init} size="sm" /><span style={{ fontWeight: 500 }}>{r.name}</span><Badge tone={r.tier === "A" ? "avocado" : r.tier === "B" ? "pulp" : "outline"}>Tier {r.tier}</Badge></span></td>
                      <td className="muted">{r.region}</td>
                      <td className="num" style={{ fontWeight: 600 }}>{r.qty.toLocaleString("en-US")}<span className="muted" style={{ fontWeight: 400 }}> kg</span></td>
                      <td className="num"><span className={`rs-rate ${rateClass(r.rate)}`}>{KES10(r.rate)}</span></td>
                      <td>{fmtDate10(r.earliest)}<div className="muted" style={{ fontSize: 11.5 }}>08:00–11:00 · Gate 2</div></td>
                      <td className="num"><b style={{ color: r.score >= 85 ? "var(--success)" : r.score >= 70 ? "var(--foreground)" : "var(--muted-foreground)" }}>{r.score}</b></td>
                      <td><GatePill gate={r.gate} /></td>
                      <td className="actions">
                        {r.gate === "new" ? (
                          <div style={{ display: "inline-flex", gap: 4, justifyContent: "flex-end" }}>
                            <Button size="sm" variant="primary" icon={Ic10.Check} onClick={() => accept(r.farmer)}>Accept</Button>
                            <button className="btn btn-ghost btn-icon btn-sm" aria-label="Decline" title="Decline" onClick={() => reject(r.farmer)}><Ic10.X size={15} /></button>
                          </div>
                        ) : accepted ? (
                          <button className="gi-view" onClick={() => go("ADM-PROC-13.html")}>View gate-in<Ic10.ChevronRight size={14} /></button>
                        ) : (
                          <span className="muted" style={{ fontSize: 12.5 }}>—</span>
                        )}
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </div>
      </Card>

      {/* Sticky multi-select bar */}
      {selCount >= 1 && (
        <div className="rs-stickybar">
          <span className="sb-count">{selCount} selected{selNew.length < selCount ? ` · ${selNew.length} new` : ""}</span>
          <div className="sb-actions">
            <Button variant="outline" icon={Ic10.Layers} disabled={selCount < 2} onClick={() => go("ADM-PROC-11.html")} style={{ background: "transparent", color: "inherit", borderColor: "oklch(1 0 0 / 0.3)" }}>Compare</Button>
            <Button variant="primary" icon={Ic10.Check} disabled={selNew.length === 0} onClick={acceptSelected} style={{ background: "var(--background)", color: "var(--foreground)" }}>Accept selected · create gate-in{selNew.length > 1 ? "s" : ""}</Button>
          </div>
        </div>
      )}
    </div>
  );
};

window.Pages = Object.assign(window.Pages || {}, { responses: ResponseDashboard });
