// hydor-page-transactions.jsx — Transactions ledger + filters + POS quick-sale.
function TransactionsPage({ initialFilter, onDrill }) {
  const s = useHydor();
  const d = useDerive();
  const push = useToast();
  const role = useRole();
  const canCostProfit = Hydor.can(role, "seeCostProfit");   // cost, profit, margin, purchases
  const [q, setQ] = React.useState("");
  const [typeF, setTypeF] = React.useState(initialFilter && initialFilter.type ? initialFilter.type : "all");
  const [prodF, setProdF] = React.useState(initialFilter && initialFilter.productId ? initialFilter.productId : "all");
  const [empF, setEmpF] = React.useState(initialFilter && initialFilter.employee ? initialFilter.employee : "all");
  const [from, setFrom] = React.useState("");
  const [to, setTo] = React.useState("");
  const [showVoid, setShowVoid] = React.useState(false);
  const [sort, setSort] = React.useState({ key: "date", dir: "desc" });
  const [form, setForm] = React.useState(null);
  const [del, setDel] = React.useState(null);
  const [instTx, setInstTx] = React.useState(null);
  const highlightId = initialFilter && initialFilter.highlight;
  React.useEffect(() => { if (highlightId && onDrill) onDrill({ type: "tx", id: highlightId }); }, [highlightId]);

  const pname = (id) => { const p = s.products.find((x) => x.id === id); return p ? p : { code: "—", name: "" }; };
  const partyName = (id) => { const p = s.parties.find((x) => x.id === id); return p ? p.name : ""; };
  const employees = [...new Set(s.transactions.filter((t) => t.type === "sale" && t.employee).map((t) => t.employee))].sort();
  // employees see only their own sales (team managers see their team's); owner/cofounder/manager see all
  const me = Hydor.currentUser();
  const visibleCodes = Hydor.visibleSalesCodes(me);   // null = all

  let rows = s.transactions.filter((t) => showVoid ? true : !t.deleted)
    .filter((t) => canCostProfit || t.type === "sale")     // employees only see sales (purchases reveal cost)
    .filter((t) => !visibleCodes || t.type !== "sale" || visibleCodes.indexOf(t.employee) >= 0)   // own / team sales only
    .filter((t) => typeF === "all" || t.type === typeF)
    .filter((t) => prodF === "all" || t.productId === prodF)
    .filter((t) => empF === "all" || t.employee === empF)
    .filter((t) => !from || t.date >= from)
    .filter((t) => !to || t.date <= to)
    .filter((t) => {
      if (!q) return true;
      const p = pname(t.productId);
      return (p.code + " " + p.name + " " + t.employee + " " + partyName(t.partyId) + " " + t.notes).toLowerCase().includes(q.toLowerCase());
    });

  const acc = {
    date: (t) => t.date, type: (t) => t.type, product: (t) => pname(t.productId).code,
    qty: (t) => t.qty, value: (t) => { const c = d.txc[t.id] || {}; return t.type === "sale" ? c.subtotal : t.type === "purchase" ? (c.value || 0) : 0; },
    profit: (t) => (d.txc[t.id] || {}).profit || 0, employee: (t) => t.employee,
  };
  const sorted = sortRows(rows, sort, acc);

  // filter summary
  const visSales = rows.filter((t) => t.type === "sale" && !t.deleted);
  const sumSales = visSales.reduce((a, t) => a + ((d.txc[t.id] || {}).subtotal || 0), 0);
  const sumProfit = visSales.reduce((a, t) => a + ((d.txc[t.id] || {}).profit || 0), 0);
  const sumUnits = visSales.reduce((a, t) => a + t.qty, 0);

  const exportCsv = () => {
    const out = [["Date", "Type", "Code", "Product", "Qty", "Unit cost", "Sell price", "COGS", "Subtotal", "Tax", "Total", "Profit", "Employee", "Party", "Paid", "Notes"]];
    sorted.forEach((t) => { const c = d.txc[t.id] || {}; const p = pname(t.productId);
      out.push([t.date, t.type, p.code, p.name, t.qty, t.unitCost ?? "", t.actualSell ?? "", (c.cogs || 0).toFixed(3), (c.subtotal || 0).toFixed(3), (c.tax || 0).toFixed(3), (c.total || c.value || 0).toFixed(3), (c.profit || 0).toFixed(3), t.employee, partyName(t.partyId), t.paid ? "yes" : "no", t.notes]); });
    Hydor.exportCSV("hydor-transactions.csv", out);
    push("Transactions exported.");
  };
  const resetFilters = () => { setTypeF("all"); setProdF("all"); setEmpF("all"); setFrom(""); setTo(""); setQ(""); };
  const hasFilters = typeF !== "all" || prodF !== "all" || empF !== "all" || from || to || q;

  return (
    <div>
      <PendingApprovals />
      {visSales.length > 0 && (
        <div className="stat-strip" style={{ gridTemplateColumns: canCostProfit ? "repeat(4,1fr)" : "repeat(2,1fr)" }}>
          <div className="mini-stat"><div className="ms-label">Matching sales</div><div className="ms-value">{Hydor.fmtQty(visSales.length)}</div><div className="ms-sub">{Hydor.fmtQty(sumUnits)} units</div></div>
          <div className="mini-stat" style={{ borderLeft: "3px solid var(--accent)" }}><div className="ms-label">Sales value</div><div className="ms-value">{Hydor.fmtMoney0(sumSales)}</div><div className="ms-sub">JOD ex-tax</div></div>
          {canCostProfit && <div className="mini-stat" style={{ borderLeft: "3px solid var(--pos)" }}><div className="ms-label">Gross profit</div><div className="ms-value">{Hydor.fmtMoney0(sumProfit)}</div><div className="ms-sub">JOD</div></div>}
          {canCostProfit && <div className="mini-stat"><div className="ms-label">Avg margin</div><div className="ms-value">{sumSales ? (sumProfit / sumSales * 100).toFixed(1) : "0.0"}%</div><div className="ms-sub">on matching sales</div></div>}
        </div>
      )}

      <div className="toolbar">
        <div className="search"><Icon name="search" /><input placeholder="Search ledger…" value={q} onChange={(e) => setQ(e.target.value)} /></div>
        {canCostProfit && (
        <select className="sel" style={{ width: 140 }} value={typeF} onChange={(e) => setTypeF(e.target.value)}>
          <option value="all">All types</option><option value="purchase">Purchases</option><option value="sale">Sales</option><option value="adjustment">Adjustments</option>
        </select>
        )}
        <select className="sel" style={{ width: 170 }} value={prodF} onChange={(e) => setProdF(e.target.value)}>
          <option value="all">All products</option>
          {s.products.map((p) => <option key={p.id} value={p.id}>{p.code}</option>)}
        </select>
        {employees.length > 0 && (
          <select className="sel" style={{ width: 130 }} value={empF} onChange={(e) => setEmpF(e.target.value)}>
            <option value="all">All staff</option>
            {employees.map((e) => <option key={e} value={e}>Emp {e}</option>)}
          </select>
        )}
        <input className="inp" type="date" style={{ width: 150 }} value={from} onChange={(e) => setFrom(e.target.value)} title="From date" />
        <input className="inp" type="date" style={{ width: 150 }} value={to} onChange={(e) => setTo(e.target.value)} title="To date" />
        {hasFilters && <Btn variant="ghost" sm icon="x" onClick={resetFilters}>Clear</Btn>}
        <div className="grow" />
        {canCostProfit && <Btn icon="download" onClick={exportCsv} disabled={!rows.length}>CSV</Btn>}
        <Btn variant="primary" icon="plus" onClick={() => setForm({})}>New transaction</Btn>
      </div>

      <label style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 12.5, color: "var(--text-3)", marginBottom: 12, cursor: "pointer" }}>
        <input type="checkbox" checked={showVoid} onChange={(e) => setShowVoid(e.target.checked)} /> Show voided transactions
      </label>

      <div className="hx-panel" style={{ overflow: "hidden" }}>
        {s.transactions.length === 0 ? (
          <Empty icon="ledger" title="No transactions yet"
            action={s.products.length ? <Btn variant="primary" icon="plus" onClick={() => setForm({})}>Record a transaction</Btn> : <Badge color="amber">Add a product first</Badge>}>
            Record purchases, sales and stock adjustments here. HYDOR computes FIFO cost of goods, profit, tax and live inventory from every line.
          </Empty>
        ) : sorted.length === 0 ? (
          <Empty icon="filter" title="No matching transactions">Try clearing or widening your filters.</Empty>
        ) : (
          <table className="hx-table">
            <thead><tr>
              <SortHeader col="date" label="Date" sort={sort} setSort={setSort} />
              <SortHeader col="type" label="Type" sort={sort} setSort={setSort} />
              <SortHeader col="product" label="Product" sort={sort} setSort={setSort} />
              <SortHeader col="qty" label="Qty" sort={sort} setSort={setSort} r />
              {canCostProfit && <th className="r">Unit</th>}
              <SortHeader col="value" label="Value" sort={sort} setSort={setSort} r />
              {canCostProfit && <SortHeader col="profit" label="Profit" sort={sort} setSort={setSort} r />}
              <SortHeader col="employee" label="Staff" sort={sort} setSort={setSort} />
              <th>Status</th>
              <th></th>
            </tr></thead>
            <tbody>
              {sorted.map((t) => {
                const c = d.txc[t.id] || {};
                const p = pname(t.productId);
                const val = t.type === "sale" ? c.subtotal : t.type === "purchase" ? c.value : 0;
                const unit = t.type === "sale" ? t.actualSell : t.type === "purchase" ? t.unitCost : null;
                return (
                  <tr key={t.id} className={"clickrow" + (t.deleted ? " row-void" : "")} style={highlightId === t.id ? { boxShadow: "inset 3px 0 0 var(--warn)", background: "#ffc24b0e" } : null} onClick={() => onDrill && onDrill({ type: "tx", id: t.id })}>
                    <td className="num" style={{ color: "var(--text-2)", whiteSpace: "nowrap" }}>{Hydor.fmtDate(t.date)}</td>
                    <td><span className={"tag-type tag-" + t.type}>{t.type === "maintenance_contract" ? "contract" : t.type}</span>{t.opening && <Badge color="gray">opening</Badge>}{t.flagged && <Badge color="red">⚑ flag</Badge>}{t.installment && <Badge color="purple">installment</Badge>}{t.type === "maintenance_contract" && <Badge color="blue">{t.contractDurationYears}yr</Badge>}</td>
                    <td><span className="hx-code">{p.code}</span> <span style={{ color: "var(--text-2)", fontSize: 12.5 }}>{p.name}</span></td>
                    <td className="r num" style={t.type === "adjustment" && t.qty < 0 ? { color: "var(--neg)" } : null}>{t.type === "adjustment" && t.qty > 0 ? "+" : ""}{Hydor.fmtQty(t.qty)}</td>
                    {canCostProfit && <td className="r num" style={{ color: "var(--text-3)" }}>{unit != null ? Hydor.fmtMoney(unit) : "—"}</td>}
                    <td className="r num">{val ? Hydor.fmtMoney0(val) : "—"}</td>
                    {canCostProfit && <td className="r num">{t.type === "sale" ? <span className={c.profit >= 0 ? "hx-pos" : "hx-neg"}>{Hydor.fmtMoney0(c.profit)}</span> : "—"}{c.belowRec && <Icon name="alert" size={12} style={{ color: "var(--warn)", marginLeft: 4, verticalAlign: "middle" }} />}</td>}
                    <td>{t.employee ? <EmpBadge code={t.employee} /> : <span style={{ color: "var(--text-3)" }}>—</span>}</td>
                    <td>{t.type !== "adjustment" && (t.paid ? <Badge color="green" dot>paid</Badge> : <Badge color="amber" dot>{t.type === "sale" ? "receivable" : "payable"}</Badge>)}</td>
                    <td className="r no-print" onClick={(e) => e.stopPropagation()}>
                      <div style={{ display: "flex", gap: 2, justifyContent: "flex-end" }}>
                        {t.deleted ? <Btn variant="ghost" sm icon="refresh" onClick={() => { Hydor.restoreTransaction(t.id); push("Transaction restored."); }} />
                          : <>
                            {t.installment && <Btn variant="ghost" sm icon="calendar" title="Manage installments" onClick={() => setInstTx(t)} />}
                            <Btn variant="ghost" sm icon="edit" onClick={() => setForm({ editing: t })} />
                            <Btn variant="ghost" sm icon="trash" onClick={() => setDel(t)} />
                          </>}
                      </div>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        )}
      </div>

      {form && <TxForm editing={form.editing} onClose={() => setForm(null)} />}
      {instTx && <InstallmentModal tx={instTx} onClose={() => setInstTx(null)} />}
      {del && <Confirm title="Void transaction?" danger confirmLabel="Void"
        body="Voiding keeps the record for audit but removes it from inventory, costing and reports. You can restore it later."
        onConfirm={() => { Hydor.deleteTransaction(del.id); push("Transaction voided."); }} onClose={() => setDel(null)} />}
    </div>
  );
}

function InstallmentModal({ tx, onClose }) {
  useHydor();
  const push = useToast();
  const live = Hydor.getState().transactions.find((t) => t.id === tx.id) || tx;
  const inst = live.installment;
  if (!inst) return null;
  const paid = inst.schedule.filter((r) => r.paid).reduce((a, r) => a + r.amount, 0);
  const remaining = inst.total - paid;
  return (
    <Modal title="Installment plan" onClose={onClose} foot={<Btn variant="primary" onClick={onClose}>Done</Btn>}>
      <div style={{ display: "flex", gap: 18, marginBottom: 16 }}>
        <div className="mini-stat" style={{ flex: 1 }}><div className="ms-label">Plan total</div><div className="ms-value">{Hydor.fmtMoney0(inst.total)}</div><div className="ms-sub">JOD</div></div>
        <div className="mini-stat" style={{ flex: 1, borderLeft: "3px solid var(--pos)" }}><div className="ms-label">Paid</div><div className="ms-value">{Hydor.fmtMoney0(paid)}</div><div className="ms-sub">JOD</div></div>
        <div className="mini-stat" style={{ flex: 1, borderLeft: "3px solid var(--warn)" }}><div className="ms-label">Remaining</div><div className="ms-value">{Hydor.fmtMoney0(remaining)}</div><div className="ms-sub">JOD</div></div>
      </div>
      <table className="hx-table">
        <thead><tr><th>Installment</th><th>Due</th><th className="r">Amount</th><th>Status</th><th></th></tr></thead>
        <tbody>
          {inst.schedule.map((r, i) => {
            const overdue = !r.paid && r.due < new Date().toISOString().slice(0, 10);
            return (
              <tr key={i}>
                <td style={{ fontWeight: 500 }}>{r.label}</td>
                <td className="num" style={{ color: overdue ? "var(--neg)" : "var(--text-2)" }}>{Hydor.fmtDate(r.due)}</td>
                <td className="r num">{Hydor.fmtMoney0(r.amount)}</td>
                <td>{r.paid ? <Badge color="green" dot>paid</Badge> : overdue ? <Badge color="red" dot>overdue</Badge> : <Badge color="amber" dot>due</Badge>}</td>
                <td className="r">
                  <Btn variant="ghost" sm icon={r.paid ? "refresh" : "check"} onClick={() => { Hydor.payInstallment(tx.id, i, !r.paid); push(r.paid ? "Reopened." : "Payment recorded."); }}>{r.paid ? "Undo" : "Mark paid"}</Btn>
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </Modal>
  );
}
Object.assign(window, { TransactionsPage });
