// ADM-PROC-02 · Requirement list (AMOMS Module 1)
// Admin Web · Procurement Manager / Officer · P0 · 1440×900
// Components: C-201 Data table · C-014 Status pill · C-012 Search bar · C-001 Button
//             C-007 Date-range picker · C-105 Empty state block
// Registered as window.Pages.requirements

const Ic2 = window.Icons;
const KESf = (n) => "KSh " + n.toLocaleString("en-US");
const PROC_TODAY_02 = new Date(2026, 4, 12);
const daysUntil02 = (iso) => Math.round((new Date(iso) - PROC_TODAY_02) / 864e5);
const deadlineLabel02 = (iso) => {
  const d = daysUntil02(iso);
  if (d < 0) return { text: `${Math.abs(d)}d overdue`, tone: "overdue" };
  if (d === 0) return { text: "Due today", tone: "due" };
  if (d <= 2) return { text: `in ${d}d`, tone: "soon" };
  return { text: `in ${d}d`, tone: "ok" };
};
const PRODUCT_TONE_02 = { Hass: "avocado", Fuerte: "pulp", Pinkerton: "soil", Local: "secondary" };

// Built screens in this prototype — everything else surfaces a toast instead of 404.
const BUILT_02 = window.BUILT_PAGES;

// ── Requirement dataset (richer than the dashboard's — all lifecycle statuses) ──
const CREATORS = {
  DO: { name: "David Onyango", initials: "DO" },
  CW: { name: "Caroline Wanjala", initials: "CW" },
};
const REQ_ROWS = [
  { id: "PR-2026-0190", product: "Hass",      qty: 24_000, rate: 96, type: "ceiling", deadline: "2026-05-22", broadcast: "—",          status: "draft",       responses: 0,  by: "DO", updated: "2026-05-12 10:42" },
  { id: "PR-2026-0189", product: "Fuerte",    qty: 9_000,  rate: 80, type: "ceiling", deadline: "2026-05-21", broadcast: "—",          status: "draft",       responses: 0,  by: "CW", updated: "2026-05-12 09:15" },
  { id: "PR-2026-0188", product: "Hass",      qty: 30_000, rate: 95, type: "ceiling", deadline: "2026-05-20", broadcast: "2026-05-12", status: "broadcasted",  responses: 2,  by: "CW", updated: "2026-05-12 08:30" },
  { id: "PR-2026-0187", product: "Local",     qty: 6_000,  rate: 62, type: "target",  deadline: "2026-05-16", broadcast: "2026-05-11", status: "receiving",    responses: 7,  by: "DO", updated: "2026-05-12 07:55" },
  { id: "PR-2026-0184", product: "Hass",      qty: 28_000, rate: 95, type: "ceiling", deadline: "2026-05-19", broadcast: "2026-05-10", status: "receiving",    responses: 14, by: "CW", updated: "2026-05-12 07:20" },
  { id: "PR-2026-0183", product: "Fuerte",    qty: 12_000, rate: 78, type: "ceiling", deadline: "2026-05-15", broadcast: "2026-05-09", status: "approved",     responses: 9,  by: "DO", updated: "2026-05-11 16:40" },
  { id: "PR-2026-0182", product: "Hass",      qty: 18_500, rate: 92, type: "ceiling", deadline: "2026-05-14", broadcast: "2026-05-08", status: "confirmed",    responses: 22, by: "CW", updated: "2026-05-11 14:05" },
  { id: "PR-2026-0181", product: "Hass",      qty: 22_000, rate: 84, type: "ceiling", deadline: "2026-05-12", broadcast: "2026-05-06", status: "fulfilled",    responses: 18, by: "DO", updated: "2026-05-11 11:22" },
  { id: "PR-2026-0180", product: "Pinkerton", qty: 3_500,  rate: 82, type: "floor",   deadline: "2026-05-13", broadcast: "2026-05-09", status: "receiving",    responses: 4,  by: "DO", updated: "2026-05-10 18:00" },
  { id: "PR-2026-0179", product: "Fuerte",    qty: 14_000, rate: 76, type: "ceiling", deadline: "2026-05-08", broadcast: "2026-04-30", status: "closed",       responses: 11, by: "CW", updated: "2026-05-09 09:10" },
  { id: "PR-2026-0178", product: "Hass",      qty: 16_000, rate: 90, type: "ceiling", deadline: "2026-05-05", broadcast: "2026-04-28", status: "cancelled",    responses: 3,  by: "DO", updated: "2026-05-04 13:45" },
  { id: "PR-2026-0177", product: "Local",     qty: 8_000,  rate: 60, type: "target",  deadline: "2026-05-02", broadcast: "2026-04-24", status: "fulfilled",    responses: 13, by: "CW", updated: "2026-05-03 10:30" },
  { id: "PR-2026-0176", product: "Hass",      qty: 26_000, rate: 93, type: "ceiling", deadline: "2026-04-30", broadcast: "2026-04-22", status: "fulfilled",    responses: 19, by: "CW", updated: "2026-05-01 16:00" },
  { id: "PR-2026-0175", product: "Fuerte",    qty: 10_500, rate: 79, type: "ceiling", deadline: "2026-04-28", broadcast: "2026-04-20", status: "closed",       responses: 8,  by: "DO", updated: "2026-04-29 08:20" },
];

const STATUS_OPTS = ["draft","broadcasted","receiving","approved","confirmed","fulfilled","closed","cancelled"];
const STATUS_LABEL = { draft:"Draft", broadcasted:"Broadcasted", receiving:"Receiving responses", approved:"Approved", confirmed:"Confirmed", fulfilled:"Fulfilled", closed:"Closed", cancelled:"Cancelled" };
const PRODUCT_OPTS = ["Hass","Fuerte","Pinkerton","Local"];
const SORT_OPTS = [
  { id: "updated-desc", label: "Last updated · newest" },
  { id: "updated-asc",  label: "Last updated · oldest" },
  { id: "deadline-asc", label: "Deadline · soonest" },
  { id: "qty-desc",     label: "Quantity · largest" },
  { id: "responses-desc", label: "Responses · most" },
];

// ── small Checkbox ──
const Check02 = ({ on, onClick }) => (
  <span className={`proc-check${on ? " on" : ""}`} onClick={onClick} role="checkbox" aria-checked={on}>
    {on && <Ic2.Check size={11} />}
  </span>
);

// ── Row actions kebab ──
const RowKebab = ({ row, onAction }) => {
  const [open, setOpen] = useState(false);
  const isDraft = row.status === "draft";
  const archivable = row.status === "closed" || row.status === "cancelled" || row.status === "fulfilled";
  return (
    <div className="proc-menu-wrap" onClick={(e) => e.stopPropagation()}>
      <button className="btn btn-ghost btn-icon btn-sm" aria-label="Row actions" onClick={() => setOpen(o => !o)}>
        <Ic2.More size={16} />
      </button>
      {open && (
        <>
          <div className="proc-menu-scrim" onClick={() => setOpen(false)} />
          <div className="proc-menu right">
            {isDraft && <button className="proc-menu-item" onClick={() => { setOpen(false); onAction("edit", row); }}><Ic2.Edit size={14} /><span>Edit</span></button>}
            <button className="proc-menu-item" onClick={() => { setOpen(false); onAction("duplicate", row); }}><Ic2.Layers size={14} /><span>Duplicate</span></button>
            {isDraft && <button className="proc-menu-item" onClick={() => { setOpen(false); onAction("broadcast", row); }}><Ic2.Bolt size={14} /><span>Broadcast</span></button>}
            <div className="proc-menu-sep" />
            <button className="proc-menu-item danger" onClick={() => { setOpen(false); onAction("cancel", row); }}><Ic2.XCircle size={14} /><span>Cancel…</span></button>
            <button className="proc-menu-item" onClick={() => { setOpen(false); onAction("archive", row); }} disabled={!archivable} style={!archivable ? { opacity: 0.4, cursor: "default" } : undefined}><Ic2.Box size={14} /><span>Archive</span></button>
          </div>
        </>
      )}
    </div>
  );
};

// ── Sort dropdown ──
const SortMenu = ({ value, onChange }) => {
  const [open, setOpen] = useState(false);
  const cur = SORT_OPTS.find(o => o.id === value) || SORT_OPTS[0];
  return (
    <div className="proc-menu-wrap">
      <button className="btn btn-outline" onClick={() => setOpen(o => !o)}>
        <Ic2.Filter size={14} style={{ opacity: 0.6 }} />Sort<Ic2.ChevronDown size={14} style={{ opacity: 0.6 }} />
      </button>
      {open && (
        <>
          <div className="proc-menu-scrim" onClick={() => setOpen(false)} />
          <div className="proc-menu right" style={{ minWidth: 210 }}>
            {SORT_OPTS.map(o => (
              <button key={o.id} className={`proc-menu-item${o.id === value ? " active" : ""}`} onClick={() => { onChange(o.id); setOpen(false); }}>
                {o.id === value ? <Ic2.Check size={14} /> : <span style={{ width: 14 }} />}<span>{o.label}</span>
              </button>
            ))}
          </div>
        </>
      )}
    </div>
  );
};

// ── Filter modal ──
const FilterModal = ({ open, onClose, draft, setDraft, onApply, onClear }) => {
  if (!open) return null;
  const toggle = (key, val) => {
    const set = new Set(draft[key]);
    set.has(val) ? set.delete(val) : set.add(val);
    setDraft({ ...draft, [key]: [...set] });
  };
  return (
    <Modal open={open} onClose={onClose} title="Filter requirements" sub="Narrow the list by status, product and more"
      footer={<>
        <Button variant="ghost" onClick={onClear}>Clear all</Button>
        <div style={{ flex: 1 }} />
        <Button variant="outline" onClick={onClose}>Cancel</Button>
        <Button variant="primary" onClick={onApply}>Apply filters</Button>
      </>}>
      <div className="col" style={{ gap: 18 }}>
        <div className="field">
          <div className="label">Status</div>
          <div className="proc-chips">
            {STATUS_OPTS.map(s => (
              <button key={s} className={`proc-chip${draft.status.includes(s) ? " on" : ""}`} onClick={() => toggle("status", s)}>
                {STATUS_LABEL[s]}
              </button>
            ))}
          </div>
        </div>
        <div className="field">
          <div className="label">Product</div>
          <div className="proc-chips">
            {PRODUCT_OPTS.map(p => (
              <button key={p} className={`proc-chip${draft.product.includes(p) ? " on" : ""}`} onClick={() => toggle("product", p)}>
                {p}
              </button>
            ))}
          </div>
        </div>
        <div className="grid-2" style={{ gap: 14 }}>
          <div className="field">
            <label className="label">Broadcast date</label>
            <select className="select" value={draft.range} onChange={(e) => setDraft({ ...draft, range: e.target.value })}>
              <option>Last 30 days</option>
              <option>Last 90 days</option>
              <option>This quarter</option>
              <option>All time</option>
            </select>
          </div>
          <div className="field">
            <label className="label">Created by</label>
            <select className="select" value={draft.by} onChange={(e) => setDraft({ ...draft, by: e.target.value })}>
              <option value="any">Anyone</option>
              <option value="DO">David Onyango (me)</option>
              <option value="CW">Caroline Wanjala</option>
            </select>
          </div>
        </div>
      </div>
    </Modal>
  );
};

// ── Cancel-with-reason modal ──
const CancelModal = ({ open, row, onClose, onConfirm }) => {
  const [reason, setReason] = useState("");
  useEffect(() => { if (open) setReason(""); }, [open]);
  if (!open) return null;
  return (
    <Modal open={open} onClose={onClose} title={`Cancel ${row?.id}?`} sub="Farmers with open responses will be notified."
      footer={<>
        <Button variant="outline" onClick={onClose}>Keep requirement</Button>
        <Button variant="destructive" onClick={() => onConfirm(reason)} disabled={!reason.trim()}>Cancel requirement</Button>
      </>}>
      <div className="field">
        <label className="label">Reason for cancellation <span className="req">*</span></label>
        <textarea className="textarea" placeholder="e.g. Demand covered by PR-2026-0182 — no longer needed." value={reason} onChange={(e) => setReason(e.target.value)} />
        <div className="field-hint">Recorded on the requirement's activity log.</div>
      </div>
    </Modal>
  );
};

// ── Skeleton rows ──
const ListSkeleton = () => (
  <tbody>
    {Array.from({ length: 8 }).map((_, i) => (
      <tr key={i}>
        <td><span className="proc-check" /></td>
        <td><div className="sk" style={{ width: 130 }} /><div className="sk" style={{ width: 90, marginTop: 6 }} /></td>
        <td><div className="sk" style={{ width: 56 }} /></td>
        <td className="num"><div className="sk" style={{ width: 60, marginLeft: "auto" }} /></td>
        <td className="num"><div className="sk" style={{ width: 50, marginLeft: "auto" }} /></td>
        <td><div className="sk" style={{ width: 70 }} /></td>
        <td><div className="sk" style={{ width: 100 }} /></td>
        <td className="num"><div className="sk" style={{ width: 30, marginLeft: "auto" }} /></td>
        <td><div className="sk" style={{ width: 90 }} /></td>
        <td></td>
      </tr>
    ))}
  </tbody>
);

const PER_PAGE = 10;

// ── Page ──
const RequirementList = ({ tweaks }) => {
  const toast = useToast();
  const state = (tweaks && tweaks.reqState) || "default";
  const loading = state === "loading";
  const firstRun = state === "empty";
  const forceNoResults = state === "noresults";

  const go = (file) => { if (BUILT_02.includes(file)) window.location.href = file; else toast({ title: `${file.replace(".html", "")} isn't part of this prototype`, desc: "This flow is specced but not built here.", tone: "danger" }); };

  const [search, setSearch] = useState("");
  const [statusF, setStatusF] = useState([]);
  const [productF, setProductF] = useState([]);
  const [sort, setSort] = useState("updated-desc");
  const [page, setPage] = useState(1);
  const [sel, setSel] = useState(() => new Set());
  const [filterOpen, setFilterOpen] = useState(false);
  const [filterDraft, setFilterDraft] = useState({ status: [], product: [], range: "Last 90 days", by: "any" });
  const [cancelRow, setCancelRow] = useState(null);
  const [archiveConfirm, setArchiveConfirm] = useState(false);
  const [rows, setRows] = useState(REQ_ROWS);

  const filtered = useMemo(() => {
    if (forceNoResults) return [];
    let r = rows.filter(x => {
      if (search && !(`${x.id} ${x.product}`.toLowerCase().includes(search.toLowerCase()))) return false;
      if (statusF.length && !statusF.includes(x.status)) return false;
      if (productF.length && !productF.includes(x.product)) return false;
      return true;
    });
    const s = sort;
    r = [...r].sort((a, b) => {
      if (s === "updated-desc") return b.updated.localeCompare(a.updated);
      if (s === "updated-asc") return a.updated.localeCompare(b.updated);
      if (s === "deadline-asc") return a.deadline.localeCompare(b.deadline);
      if (s === "qty-desc") return b.qty - a.qty;
      if (s === "responses-desc") return b.responses - a.responses;
      return 0;
    });
    return r;
  }, [rows, search, statusF, productF, sort, forceNoResults]);

  const totalPages = Math.max(1, Math.ceil(filtered.length / PER_PAGE));
  const pageClamped = Math.min(page, totalPages);
  const pageRows = filtered.slice((pageClamped - 1) * PER_PAGE, pageClamped * PER_PAGE);
  useEffect(() => { setPage(1); }, [search, statusF, productF, sort]);

  const activeFilterCount = statusF.length + productF.length;
  const hasFilters = activeFilterCount > 0 || search.trim().length > 0;

  const toggleSel = (id) => { const s = new Set(sel); s.has(id) ? s.delete(id) : s.add(id); setSel(s); };
  const allOnPageSelected = pageRows.length > 0 && pageRows.every(r => sel.has(r.id));
  const toggleAll = () => {
    const s = new Set(sel);
    if (allOnPageSelected) pageRows.forEach(r => s.delete(r.id));
    else pageRows.forEach(r => s.add(r.id));
    setSel(s);
  };

  const onRowAction = (action, row) => {
    if (action === "edit") go("ADM-PROC-06.html");
    else if (action === "broadcast") go("ADM-PROC-07.html");
    else if (action === "duplicate") { toast({ title: "Duplicating into a new draft", desc: `${row.id} → new requirement` }); go("ADM-PROC-03.html"); }
    else if (action === "cancel") setCancelRow(row);
    else if (action === "archive") { setRows(rs => rs.filter(r => r.id !== row.id)); toast({ title: `${row.id} archived`, desc: "Moved to archive — viewable via filters." }); }
  };

  const clearFilters = () => { setSearch(""); setStatusF([]); setProductF([]); };

  // ── First-run empty (no requirements ever) ──
  if (firstRun) {
    return (
      <div className="page">
        <div className="page-head">
          <div>
            <h1 className="page-title">Requirements</h1>
            <div className="page-sub">Browse, search and filter every procurement requirement</div>
          </div>
        </div>
        <Card>
          <div style={{ padding: "64px 24px", textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", gap: 14 }}>
            <div style={{ width: 64, height: 64, borderRadius: 16, background: "var(--avocado-soft)", color: "var(--avocado-fg)", display: "inline-flex", alignItems: "center", justifyContent: "center" }}>
              <Ic2.Procurement size={30} />
            </div>
            <div>
              <div style={{ fontSize: 19, fontWeight: 600, letterSpacing: "-0.02em" }}>No requirements yet</div>
              <div className="muted" style={{ fontSize: 13.5, maxWidth: 440, margin: "6px auto 0", lineHeight: 1.5 }}>
                Create your first sourcing requirement to broadcast to farmer groups, or bulk-import a whole procurement cycle from a spreadsheet.
              </div>
            </div>
            <div className="row" style={{ marginTop: 4 }}>
              <Button variant="primary" icon={Ic2.Plus} onClick={() => go("ADM-PROC-03.html")}>Create requirement</Button>
              <Button variant="outline" icon={Ic2.Layers} onClick={() => go("ADM-PROC-04.html")}>Bulk create</Button>
            </div>
          </div>
        </Card>
      </div>
    );
  }

  const selCount = sel.size;

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1 className="page-title">Requirements</h1>
          <div className="page-sub">Browse, search and filter every procurement requirement</div>
        </div>
        <div className="page-actions">
          <button className="btn btn-outline btn-icon" aria-label="Bulk create" onClick={() => go("ADM-PROC-04.html")} title="Bulk create">
            <Ic2.Layers size={16} />
          </button>
          <Button variant="primary" icon={Ic2.Plus} onClick={() => go("ADM-PROC-03.html")}>Create requirement</Button>
        </div>
      </div>

      {/* Filter chips row */}
      <div className="proc-chips" style={{ marginBottom: 14 }}>
        {STATUS_OPTS.slice(0, 5).map(s => (
          <button key={s} className={`proc-chip${statusF.includes(s) ? " on" : ""}`}
            onClick={() => setStatusF(f => f.includes(s) ? f.filter(x => x !== s) : [...f, s])}>
            {STATUS_LABEL[s]}
          </button>
        ))}
        <button className="proc-chip" onClick={() => { setFilterDraft({ status: statusF, product: productF, range: "Last 90 days", by: "any" }); setFilterOpen(true); }}>
          <Ic2.Plus size={13} />More filters{activeFilterCount > 0 && <span className="chip-count">{activeFilterCount}</span>}
        </button>
        {hasFilters && <button className="proc-chip" onClick={clearFilters}><Ic2.X size={13} className="chip-x" />Clear</button>}
      </div>

      {/* Toolbar */}
      <div className="proc-toolbar">
        <div className="proc-search">
          <Ic2.Search size={15} />
          <input className="input" placeholder="Search by ID, product, notes" value={search} onChange={(e) => setSearch(e.target.value)} />
        </div>
        <Button variant="outline" icon={Ic2.Filter} onClick={() => { setFilterDraft({ status: statusF, product: productF, range: "Last 90 days", by: "any" }); setFilterOpen(true); }}>
          Filters{activeFilterCount > 0 && <span className="chip-count" style={{ marginLeft: 2 }}>{activeFilterCount}</span>}
        </Button>
        <SortMenu value={sort} onChange={setSort} />
        <div className="proc-seg" role="tablist" aria-label="View">
          <button className="active" aria-label="List view" title="List"><Ic2.Dashboard size={15} /></button>
          <button aria-label="Calendar view" title="Calendar" onClick={() => go("ADM-PROC-16.html")}><Ic2.Calendar size={15} /></button>
        </div>
        <Button variant="outline" icon={Ic2.Download} onClick={() => toast({ title: "Export started", desc: `${filtered.length} requirements → CSV` })}>Export</Button>
      </div>

      {/* Bulk action bar */}
      {selCount > 0 && (
        <div className="proc-bulkbar">
          <span className="bb-count">{selCount} selected</span>
          <button className="bb-btn" onClick={() => { toast({ title: "Duplicated", desc: `${selCount} requirements copied to drafts` }); setSel(new Set()); }}><Ic2.Layers size={14} />Duplicate</button>
          <button className="bb-btn" onClick={() => setArchiveConfirm(true)}><Ic2.Box size={14} />Archive</button>
          <button className="bb-btn danger" onClick={() => toast({ title: "Cancel requires a reason per item", desc: "Open each requirement to cancel.", tone: "danger" })}><Ic2.XCircle size={14} />Cancel</button>
          <div className="bb-spacer" />
          <button className="bb-btn" onClick={() => setSel(new Set())}><Ic2.X size={14} />Clear</button>
        </div>
      )}

      {/* Table */}
      <Card>
        <div className="card-body flush">
          <div className="tbl-wrap">
            <table className="tbl">
              <thead>
                <tr>
                  <th style={{ width: 36 }}><Check02 on={allOnPageSelected} onClick={toggleAll} /></th>
                  <th>Requirement</th>
                  <th>Product</th>
                  <th className="num">Qty</th>
                  <th className="num">Rate cap</th>
                  <th>Deadline</th>
                  <th>Status</th>
                  <th className="num">Responses</th>
                  <th>Created by</th>
                  <th>Updated</th>
                  <th className="actions"></th>
                </tr>
              </thead>
              {loading ? <ListSkeleton /> : (
                <tbody>
                  {pageRows.length === 0 ? (
                    <tr>
                      <td colSpan={11}>
                        <div className="proc-inline-empty" style={{ justifyContent: "center" }}>
                          <Ic2.Search size={20} />
                          <div>
                            <div style={{ fontWeight: 600, fontSize: 13.5, color: "var(--foreground)" }}>No requirements match your filters</div>
                            <div className="muted" style={{ fontSize: 12.5 }}>Try broadening the status or product filters.</div>
                          </div>
                          <Button size="sm" variant="outline" onClick={clearFilters} style={{ marginLeft: 8 }}>Clear filters</Button>
                        </div>
                      </td>
                    </tr>
                  ) : pageRows.map(r => {
                    const dl = deadlineLabel02(r.deadline);
                    const c = CREATORS[r.by];
                    const selected = sel.has(r.id);
                    return (
                      <tr key={r.id} className={`proc-row${selected ? " selected" : ""}`} onClick={() => go("ADM-PROC-05.html")}>
                        <td onClick={(e) => { e.stopPropagation(); toggleSel(r.id); }}><Check02 on={selected} onClick={() => {}} /></td>
                        <td>
                          <div className="mono" style={{ fontSize: 12.5, fontWeight: 600 }}>{r.id}</div>
                          <div className="muted" style={{ fontSize: 11.5, marginTop: 2 }}>{r.type === "ceiling" ? "Rate ceiling" : r.type === "target" ? "Target rate" : "Floor rate"}</div>
                        </td>
                        <td><Badge tone={PRODUCT_TONE_02[r.product] || "outline"}>{r.product}</Badge></td>
                        <td className="num" style={{ fontWeight: 600 }}>{r.qty.toLocaleString("en-US")}<span className="muted" style={{ fontWeight: 400 }}> kg</span></td>
                        <td className="num">{KESf(r.rate)}<span className="muted" style={{ fontSize: 11 }}>/kg</span></td>
                        <td>
                          <div style={{ fontSize: 12.5 }}>{r.deadline.slice(5)}</div>
                          {["receiving","broadcasted"].includes(r.status) && <div className={`proc-dl proc-dl-${dl.tone}`}>{dl.text}</div>}
                        </td>
                        <td><StatusBadge status={r.status} /></td>
                        <td className="num">
                          <span style={{ display: "inline-flex", alignItems: "center", gap: 5, justifyContent: "flex-end" }}>
                            <Ic2.User size={12} style={{ color: "var(--muted-foreground)" }} />{r.responses}
                          </span>
                        </td>
                        <td>
                          <span style={{ display: "inline-flex", alignItems: "center", gap: 7 }}>
                            <Avatar initials={c.initials} size="sm" />
                            <span style={{ fontSize: 12.5 }}>{c.name.split(" ")[0]}</span>
                          </span>
                        </td>
                        <td className="muted" style={{ fontSize: 12 }}>{r.updated.slice(5, 10)}</td>
                        <td className="actions"><RowKebab row={r} onAction={onRowAction} /></td>
                      </tr>
                    );
                  })}
                </tbody>
              )}
            </table>
          </div>
        </div>
      </Card>

      {/* Pagination */}
      {!loading && filtered.length > 0 && (
        <div className="proc-pager">
          <div className="pg-info">
            Showing <b>{(pageClamped - 1) * PER_PAGE + 1}–{Math.min(pageClamped * PER_PAGE, filtered.length)}</b> of {filtered.length}
          </div>
          <div className="pg-nav">
            <button className="proc-pg-btn" disabled={pageClamped === 1} onClick={() => setPage(p => Math.max(1, p - 1))}><Ic2.ChevronLeft size={15} /></button>
            {Array.from({ length: totalPages }).map((_, i) => (
              <button key={i} className={`proc-pg-btn${pageClamped === i + 1 ? " active" : ""}`} onClick={() => setPage(i + 1)}>{i + 1}</button>
            ))}
            <button className="proc-pg-btn" disabled={pageClamped === totalPages} onClick={() => setPage(p => Math.min(totalPages, p + 1))}><Ic2.ChevronRight size={15} /></button>
          </div>
        </div>
      )}

      <FilterModal open={filterOpen} onClose={() => setFilterOpen(false)} draft={filterDraft} setDraft={setFilterDraft}
        onApply={() => { setStatusF(filterDraft.status); setProductF(filterDraft.product); setFilterOpen(false); }}
        onClear={() => setFilterDraft({ status: [], product: [], range: "Last 90 days", by: "any" })} />
      <CancelModal open={!!cancelRow} row={cancelRow} onClose={() => setCancelRow(null)}
        onConfirm={(reason) => { setRows(rs => rs.map(r => r.id === cancelRow.id ? { ...r, status: "cancelled" } : r)); toast({ title: `${cancelRow.id} cancelled` }); setCancelRow(null); }} />
      <Modal open={archiveConfirm} onClose={() => setArchiveConfirm(false)} title={`Archive ${selCount} requirements?`} sub="Archiving is non-destructive — items stay viewable via filters."
        footer={<>
          <Button variant="outline" onClick={() => setArchiveConfirm(false)}>Cancel</Button>
          <Button variant="primary" onClick={() => { setRows(rs => rs.filter(r => !sel.has(r.id))); toast({ title: `${selCount} requirements archived` }); setSel(new Set()); setArchiveConfirm(false); }}>Archive</Button>
        </>}>
        <div className="muted" style={{ fontSize: 13 }}>The selected requirements will be moved to the archive and hidden from the default list view.</div>
      </Modal>
    </div>
  );
};

window.Pages = Object.assign(window.Pages || {}, { requirements: RequirementList });
