/* ============================================================
   HALO SMS — Finance part 2: invoices (43/44), fee structure (45),
   discounts (46/47), approvals (48), reports (51) + router.
   ============================================================ */
(function () {
  const { useState, h } = window.HReact;
  const D = window.HALO;
  const F = window.HALO.fmt;
  const nameOf = window.financeNameOf;
  const payChip = window.payChip;

  /* ---------------- INVOICES (43) + DETAIL (44) ---------------- */
  function InvoiceList({ navigate, students }) {
    const [q, setQ] = useState(""); const [st, setSt] = useState("all");
    const list = students.filter((s) => (st === "all" || D.feeStatus(s) === st) && (q === "" || (s.first + " " + s.surname + " " + s.adm).toLowerCase().includes(q.toLowerCase())));
    const body = h("div", { className: "page-pad wide" },
      h(window.PageHead, { eyebrow: "Finance", title: "Invoices", sub: D.STRUCTURE.activeTerm + " · " + students.length + " students" }),
      h("div", { className: "card" },
        h("div", { style: { display: "flex", gap: 12, padding: "14px 16px", borderBottom: "1px solid var(--line)", flexWrap: "wrap" } },
          h("div", { className: "searchbox", style: { flex: 1, minWidth: 200, maxWidth: 320 } }, h(Icon, { name: "search" }), h("input", { placeholder: "Search student", value: q, onChange: (e) => setQ(e.target.value) })),
          h("select", { className: "select", style: { width: "auto", height: 38 }, value: st, onChange: (e) => setSt(e.target.value) }, [["all", "All statuses"], ["paid", "Paid"], ["partial", "Part-paid"], ["owing", "Owing"]].map(([v, l]) => h("option", { key: v, value: v }, l)))),
        h("div", { className: "tablewrap" }, h("table", { className: "data" },
          h("thead", null, h("tr", null, h("th", null, "Student"), h("th", null, "Class"), h("th", { className: "num" }, "Total"), h("th", { className: "num" }, "Paid"), h("th", { className: "num" }, "Balance"), h("th", null, "Status"))),
          h("tbody", null, list.map((s) => { const bal = s.fee.total - s.fee.paid;
            return h("tr", { key: s.id, onClick: () => navigate("invoices:" + s.id), style: { cursor: "pointer" } },
              h("td", null, h("div", { className: "cellname" }, h(Avatar, { name: s.first + " " + s.surname, size: 32 }), h("div", null, h("div", { className: "nm", style: { fontSize: 13.5 } }, s.surname + ", " + s.first), h("div", { className: "sub" }, s.adm)))),
              h("td", null, s.cls),
              h("td", { className: "num naira" }, F(s.fee.total)),
              h("td", { className: "num naira" }, F(s.fee.paid)),
              h("td", { className: "num naira", style: { fontWeight: 600, color: bal > 0 ? "var(--bad-fg)" : "var(--ok-fg)" } }, F(bal)),
              h("td", null, h(StatusChip, { state: D.feeStatus(s) }))); }))))));
    return h(window.DesktopScreen, { title: "Invoices" }, body);
  }

  function InvoiceDetail({ student, navigate, payments, onReverse }) {
    const [rev, setRev] = useState(null);
    const inv = D.invoiceFor(student);
    const stPays = payments.filter((p) => p.studentId === student.id);
    const lineCard = h("div", { className: "card" },
      h("div", { className: "card-h" }, h("h3", null, "Line items"), h(StatusChip, { state: D.feeStatus(student) })),
      h("div", { className: "card-pad" },
        inv.items.map(([n, a], i) => h("div", { key: n, style: { display: "flex", justifyContent: "space-between", padding: "8px 0", borderTop: i ? "1px solid var(--line-soft)" : "none", fontSize: 13.5 } }, h("span", { className: "muted" }, n), h("span", { className: "naira" }, F(a)))),
        h("div", { style: { display: "flex", justifyContent: "space-between", marginTop: 10, paddingTop: 10, borderTop: "2px solid var(--line)", fontWeight: 700 } }, h("span", null, "Total"), h("span", { className: "naira" }, F(inv.total))),
        h("div", { style: { display: "flex", justifyContent: "space-between", marginTop: 6, fontSize: 14 } }, h("span", { className: "muted" }, "Paid"), h("span", { className: "naira", style: { color: "var(--ok-fg)" } }, F(student.fee.paid))),
        h("div", { style: { display: "flex", justifyContent: "space-between", marginTop: 6, fontWeight: 700 } }, h("span", null, "Balance"), h("span", { className: "naira", style: { color: "var(--bad-fg)" } }, F(student.fee.total - student.fee.paid)))));
    const payRow = (p, i) => h("div", { key: p.id, style: { display: "flex", alignItems: "center", gap: 11, padding: "12px 18px", borderTop: i ? "1px solid var(--line-soft)" : "none" } },
      h("div", { style: { flex: 1 } }, h("div", { className: "row", style: { gap: 8 } }, h("span", { className: "naira", style: { fontWeight: 600 } }, F(p.amount)), h("span", { className: "tag" }, p.channel)), h("div", { className: "muted", style: { fontSize: 12, marginTop: 2 } }, p.time + " · " + p.ref)),
      payChip(p.state),
      p.state === "posted" ? h("button", { className: "btn btn-quiet btn-sm", onClick: () => setRev(p), title: "Reverse" }, h(Icon, { name: "swap" })) : null);
    const histInner = stPays.length === 0 ? h("div", { className: "card-pad muted", style: { fontSize: 13.5 } }, "No payments recorded yet.") : stPays.map(payRow);
    const histCard = h("div", { className: "card" },
      h("div", { className: "card-h" }, h("h3", null, "Payment history")),
      h("div", null, histInner));
    const body = h("div", { className: "page-pad", style: { maxWidth: 820 } },
      h(window.PageHead, { back: { label: "All invoices", onClick: () => navigate("invoices") }, eyebrow: inv.id, title: student.first + " " + student.surname,
        sub: student.cls + " · " + D.STRUCTURE.activeTerm, actions: h(React.Fragment, null,
          h(Button, { kind: "ghost", icon: "tag", onClick: () => navigate("discounts:new:" + student.id) }, "Apply discount"),
          h(Button, { kind: "primary", icon: "card", onClick: () => navigate("record:" + student.id) }, "Record payment")) }),
      h("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16, alignItems: "start" }, className: "det-cols" }, lineCard, histCard));
    const revModal = rev ? h(window.ConfirmModal, { icon: "swap", tone: "warn", danger: true, title: "Reverse payment", needReason: true,
      body: "Reverse the " + F(rev.amount) + " " + rev.channel + " payment? This posts a negative ledger entry and increases the balance. It's audit-logged — payments are never hard-deleted.",
      confirmLabel: "Reverse payment", onClose: () => setRev(null), onConfirm: (reason) => { onReverse(rev, student); setRev(null); } }) : null;
    return h(window.DesktopScreen, { title: "Invoice" }, body, revModal);
  }

  /* ---------------- FEE STRUCTURE (45) ---------------- */
  function FeeStructure({ navigate }) {
    const [sel, setSel] = useState(D.FEE_STRUCTURES[1].id);
    const struct = D.FEE_STRUCTURES.find((f) => f.id === sel);
    const [items, setItems] = useState(struct.items.map((it) => [...it]));
    const total = items.reduce((a, i) => a + Number(i[1] || 0), 0);
    function pick(id) { setSel(id); setItems(D.FEE_STRUCTURES.find((f) => f.id === id).items.map((it) => [...it])); }
    function setAmt(i, v) { setItems((p) => p.map((it, j) => j === i ? [it[0], Number(v.replace(/[^0-9]/g, "") || 0)] : it)); }
    const body = h("div", { className: "page-pad wide" },
      h(window.PageHead, { eyebrow: "Settings · finance", title: "Fee structures", sub: "Itemised per level × term. Existing invoices are grandfathered.",
        actions: h(Button, { kind: "primary", icon: "check", onClick: () => toast("Fee structure saved · applies to new invoices") }, "Save structure") }),
      h("div", { style: { display: "grid", gridTemplateColumns: "240px 1fr", gap: 16, alignItems: "start" }, className: "det-cols" },
        h("div", { className: "card" }, h("div", { className: "card-h" }, h("h3", { style: { fontSize: 14 } }, "Levels")),
          h("div", null, D.FEE_STRUCTURES.map((f, i) => h("button", { key: f.id, onClick: () => pick(f.id), style: { display: "flex", justifyContent: "space-between", width: "100%", textAlign: "left", border: "none", borderTop: i ? "1px solid var(--line-soft)" : "none", background: sel === f.id ? "var(--brand-soft)" : "transparent", padding: "12px 16px" } },
            h("span", { style: { fontWeight: 600, fontSize: 13.5, color: sel === f.id ? "var(--brand-strong)" : "inherit" } }, f.level), h("span", { className: "muted naira", style: { fontSize: 12.5 } }, F(f.items.reduce((a, x) => a + x[1], 0))))))),
        h("div", { className: "card" },
          h("div", { className: "card-h" }, h("div", null, h("h3", null, struct.level + " · " + struct.term), h("div", { className: "sub" }, "Edit item amounts")), h("span", { className: "chip chip-info naira" }, "Total " + F(total))),
          h("div", { className: "card-pad" },
            items.map(([n, a], i) => h("div", { key: n, style: { display: "flex", alignItems: "center", gap: 12, padding: "8px 0", borderTop: i ? "1px solid var(--line-soft)" : "none" } },
              h("span", { style: { flex: 1, fontSize: 14 } }, n),
              h(window.Input, { value: String(a), lead: "₦", onChange: (e) => setAmt(i, e.target.value), style: { width: 150 } }),
              h("button", { className: "iconbtn", style: { width: 32, height: 32 }, onClick: () => setItems(items.filter((_, j) => j !== i)) }, h(Icon, { name: "trash" })))),
            h(Button, { kind: "ghost", size: "sm", icon: "plus", style: { marginTop: 12 }, onClick: () => setItems([...items, ["New item", 0]]) }, "Add item")))));
    return h(window.DesktopScreen, { title: "Fee structure" }, body);
  }

  /* ---------------- DISCOUNTS (47) + APPLY (46) ---------------- */
  function ApplyDiscount({ navigate, students, preselect, onApply }) {
    const [sel, setSel] = useState(preselect || "");
    const [type, setType] = useState("Percentage");
    const [value, setValue] = useState("");
    const [cat, setCat] = useState(D.DISCOUNT_CATEGORIES[0]);
    const [reason, setReason] = useState("");
    const student = students.find((s) => s.id === sel);
    const bal = student ? student.fee.total - student.fee.paid : 0;
    const discountAmt = !student ? 0 : type === "Percentage" ? Math.round(student.fee.total * (Number(value || 0) / 100)) : Number(value || 0);
    const newBal = Math.max(0, bal - discountAmt);
    function submit() { if (!student) { toast("Select a student", "bad"); return; } if (!discountAmt) { toast("Enter a discount value", "bad"); return; } if (!reason.trim()) { toast("A reason is required", "bad"); return; } onApply(student, { type, value: type === "Percentage" ? value + "%" : F(Number(value)), amount: discountAmt, category: cat, reason }); }
    const body = h("div", { className: "page-pad", style: { maxWidth: 720 } },
      h(window.PageHead, { back: { label: "Discounts", onClick: () => navigate("discounts") }, eyebrow: "Finance", title: "Apply discount" }),
      h("div", { className: "card", style: { padding: 20 } },
        h("div", { style: { display: "flex", flexDirection: "column", gap: 14 } },
          window.Fld("Student", {}, h(window.Select, { value: sel, onChange: (e) => setSel(e.target.value) }, h("option", { value: "" }, "Select a student…"), students.map((s) => h("option", { key: s.id, value: s.id }, s.surname + ", " + s.first + " · " + s.cls)))),
          h("div", { className: "formgrid" },
            window.Fld("Type", {}, h(window.Segmented, { value: type, onChange: setType, options: [{ value: "Percentage", label: "Percentage" }, { value: "Fixed", label: "Fixed ₦" }] })),
            window.Fld(type === "Percentage" ? "Percent" : "Amount", {}, h(window.Input, { value: value, lead: type === "Percentage" ? "%" : "₦", onChange: (e) => setValue(e.target.value.replace(/[^0-9]/g, "")) }))),
          window.Fld("Category", {}, h(window.Select, { value: cat, onChange: (e) => setCat(e.target.value) }, D.DISCOUNT_CATEGORIES.map((c) => h("option", { key: c }, c)))),
          window.Fld("Reason", { req: true, hint: "Required — audit-stamped" }, h(window.Textarea, { value: reason, onChange: (e) => setReason(e.target.value), placeholder: "Why is this discount being applied?" })),
          student && h("div", { style: { display: "flex", gap: 10, padding: 14, borderRadius: 12, background: "var(--surface-2)", border: "1px solid var(--line)" } },
            previewCell("Original balance", F(bal), null), h(Icon, { name: "chevright", style: { alignSelf: "center", color: "var(--ink-400)" } }),
            previewCell("Discount", "− " + F(discountAmt), "warn"), h(Icon, { name: "chevright", style: { alignSelf: "center", color: "var(--ink-400)" } }),
            previewCell("New payable", F(newBal), "ok")),
          h(Button, { kind: "primary", size: "lg", icon: "check", onClick: submit }, "Apply discount"))));
    return h(window.DesktopScreen, { title: "Apply discount" }, body);
  }
  function previewCell(label, value, tone) {
    return h("div", { style: { flex: 1 } }, h("div", { className: "eyebrow", style: { fontSize: 10 } }, label), h("div", { className: "naira", style: { fontFamily: "var(--fs-display)", fontWeight: 800, fontSize: 18, marginTop: 4, color: tone ? `var(--${tone}-fg)` : "inherit" } }, value));
  }
  function Discounts({ navigate, students, discounts }) {
    const body = h("div", { className: "page-pad wide" },
      h(window.PageHead, { eyebrow: "Finance", title: "Discounts", sub: discounts.length + " applied this term · " + F(discounts.reduce((a, d) => a + d.amount, 0)) + " total",
        actions: h(Button, { kind: "primary", icon: "plus", onClick: () => navigate("discounts:new") }, "Apply discount") }),
      h("div", { className: "card" }, h("div", { className: "tablewrap" }, h("table", { className: "data" },
        h("thead", null, h("tr", null, h("th", null, "Student"), h("th", null, "Type"), h("th", { className: "num" }, "Amount"), h("th", null, "Category"), h("th", null, "Applied by"), h("th", null, "Reason"))),
        h("tbody", null, discounts.map((d) => h("tr", { key: d.id, onClick: () => navigate("invoices:" + d.studentId), style: { cursor: "pointer" } },
          h("td", { style: { fontWeight: 600 } }, nameOf(d.studentId, students)),
          h("td", null, h("span", { className: "tag" }, d.value)),
          h("td", { className: "num naira", style: { fontWeight: 600 } }, F(d.amount)),
          h("td", null, d.category),
          h("td", { className: "muted", style: { fontSize: 13 } }, d.by),
          h("td", { className: "muted", style: { fontSize: 12.5, maxWidth: 220 } }, d.reason))))))));
    return h(window.DesktopScreen, { title: "Discounts" }, body);
  }

  /* ---------------- APPROVALS (48) ---------------- */
  function Approvals({ navigate, students, payments, onApprove, onReject }) {
    const pending = payments.filter((p) => p.state === "pending");
    const body = h("div", { className: "page-pad wide" },
      h(window.PageHead, { eyebrow: "Finance", title: "Payment approvals", sub: "Second-person sign-off for manual payments" }),
      pending.length === 0
        ? h("div", { className: "card" }, h(EmptyState, { icon: "check", title: "Nothing awaiting approval" }, "Manually-recorded payments that need a second sign-off appear here."))
        : h("div", { className: "card" }, h("div", null, pending.map((p, i) => h("div", { key: p.id, style: { display: "flex", alignItems: "center", gap: 14, padding: "14px 18px", borderTop: i ? "1px solid var(--line-soft)" : "none" } },
            h(Avatar, { name: nameOf(p.studentId, students), size: 38 }),
            h("div", { style: { flex: 1 } }, h("div", { style: { fontWeight: 600, fontSize: 14 } }, nameOf(p.studentId, students)), h("div", { className: "muted", style: { fontSize: 12.5 } }, p.channel + " · " + p.ref + " · by " + p.by)),
            h("span", { className: "naira", style: { fontWeight: 700, fontSize: 15 } }, F(p.amount)),
            h("div", { className: "row", style: { gap: 8 } }, h(Button, { kind: "danger-soft", size: "sm", onClick: () => onReject(p) }, "Reject"), h(Button, { kind: "primary", size: "sm", icon: "check", onClick: () => onApprove(p) }, "Approve")))))));
    return h(window.DesktopScreen, { title: "Approvals" }, body);
  }

  /* ---------------- REPORTS (51) ---------------- */
  function FinanceReports({ navigate, students, payments, discounts }) {
    const agg = D.financeAgg(students);
    const byChannel = {}; payments.filter((p) => p.state === "posted").forEach((p) => byChannel[p.channel] = (byChannel[p.channel] || 0) + p.amount);
    const channelTotal = Object.values(byChannel).reduce((a, b) => a + b, 0) || 1;
    const defaulters = students.filter((s) => D.feeStatus(s) === "owing");
    const tones = { Cash: "ok", Transfer: "info", POS: "warn", Paystack: "bad" };
    const body = h("div", { className: "page-pad wide" },
      h(window.PageHead, { eyebrow: "Finance · " + D.STRUCTURE.activeTerm, title: "Financial reports", sub: D.STRUCTURE.session,
        actions: h(Button, { kind: "ghost", icon: "upload", onClick: () => toast("Report exported to CSV") }, "Export CSV") }),
      h("div", { className: "grid-3", style: { marginBottom: 16 } },
        statTile("card", "Collected", F(agg.paid), agg.pct + "% of expected", "ok"),
        statTile("wallet", "Outstanding", F(agg.outstanding), defaulters.length + " students owing", "bad"),
        statTile("tag", "Discounted", F(agg.discounted), discounts.length + " discounts", null)),
      h("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16, alignItems: "start" }, className: "det-cols" },
        h("div", { className: "card", style: { padding: 20 } },
          h("h3", { style: { fontSize: 15, marginBottom: 4 } }, "Payment method split"),
          h("div", { className: "muted", style: { fontSize: 12.5, marginBottom: 16 } }, "Posted payments today"),
          Object.keys(byChannel).length === 0 ? h("div", { className: "muted", style: { fontSize: 13 } }, "No posted payments yet.")
          : Object.keys(byChannel).map((ch) => h("div", { key: ch, style: { marginBottom: 12 } },
              h("div", { style: { display: "flex", justifyContent: "space-between", fontSize: 13, marginBottom: 5 } }, h("span", null, ch), h("span", { className: "naira", style: { fontWeight: 600 } }, F(byChannel[ch]))),
              h("div", { className: "bar" }, h("i", { style: { width: Math.round(byChannel[ch] / channelTotal * 100) + "%", background: `var(--${tones[ch] || "info"})` } }))))),
        h("div", { className: "card" },
          h("div", { className: "card-h" }, h("h3", null, "Defaulters"), h("span", { className: "muted", style: { fontSize: 12.5 } }, defaulters.length + " owing")),
          h("div", { style: { maxHeight: 320, overflowY: "auto" }, className: "scroll" }, defaulters.map((s, i) => h("div", { key: s.id, onClick: () => navigate("invoices:" + s.id), style: { display: "flex", alignItems: "center", gap: 11, padding: "11px 18px", borderTop: i ? "1px solid var(--line-soft)" : "none", cursor: "pointer" } },
            h(Avatar, { name: s.first + " " + s.surname, size: 30 }),
            h("div", { style: { flex: 1 } }, h("div", { style: { fontWeight: 600, fontSize: 13.5 } }, s.surname + ", " + s.first), h("div", { className: "muted", style: { fontSize: 12 } }, s.cls)),
            h("span", { className: "naira", style: { fontWeight: 600, fontSize: 13.5, color: "var(--bad-fg)" } }, F(s.fee.total - s.fee.paid))))))));
    return h(window.DesktopScreen, { title: "Reports" }, body);
  }
  function statTile(icon, label, value, foot, tone) {
    return h("div", { className: "stat" }, h("div", { className: "l" }, h(Icon, { name: icon }), label), h("div", { className: "v", style: tone ? { color: `var(--${tone}-fg)` } : null }, value), foot && h("div", { className: "d" }, foot));
  }

  /* ---------------- ROUTER ---------------- */
  function Finance({ screen, params, navigate, students, upsertStudent, role }) {
    const [payments, setPayments] = useState(() => D.TODAY_PAYMENTS.map((p) => ({ ...p })));
    const [discounts, setDiscounts] = useState(() => D.DISCOUNTS.map((d) => ({ ...d })));

    const addPayment = (rec) => setPayments((p) => [{ id: "pay-" + Date.now(), studentId: rec.student.id, amount: rec.amount, channel: rec.channel, ref: rec.ref, by: "Mrs. Grace Okoro", time: new Date().toLocaleTimeString("en-NG", { hour: "2-digit", minute: "2-digit" }), state: "posted" }, ...p]);
    const reverse = (pmt, student) => { setPayments((p) => p.map((x) => x.id === pmt.id ? { ...x, state: "reversed" } : x)); upsertStudent({ ...student, fee: { ...student.fee, paid: Math.max(0, student.fee.paid - pmt.amount) } }); toast("Payment reversed · balance updated"); };
    const approve = (pmt) => { setPayments((p) => p.map((x) => x.id === pmt.id ? { ...x, state: "posted" } : x)); const s = students.find((x) => x.id === pmt.studentId); if (s) upsertStudent({ ...s, fee: { ...s.fee, paid: Math.min(s.fee.total, s.fee.paid + pmt.amount) } }); toast("Payment approved & posted"); };
    const reject = (pmt) => { setPayments((p) => p.filter((x) => x.id !== pmt.id)); toast("Payment rejected", "bad"); };
    const applyDiscount = (student, d) => { setDiscounts((p) => [{ id: "dsc-" + Date.now(), studentId: student.id, ...d, by: "Mrs. Grace Okoro", date: new Date().toISOString().slice(0, 10) }, ...p]); upsertStudent({ ...student, fee: { ...student.fee, total: Math.max(student.fee.paid, student.fee.total - d.amount) } }); toast("Discount applied · " + F(d.amount)); navigate("discounts"); };

    if (screen === "record") return h(window.RecordPayment, { navigate, students, upsertStudent, onPosted: addPayment, preselect: params[0] });
    if (screen === "invoices") { if (params[0]) { const s = students.find((x) => x.id === params[0]); return s ? h(InvoiceDetail, { student: s, navigate, payments, onReverse: reverse }) : h(InvoiceList, { navigate, students }); } return h(InvoiceList, { navigate, students }); }
    if (screen === "feestructure") return h(FeeStructure, { navigate });
    if (screen === "discounts") { if (params[0] === "new") return h(ApplyDiscount, { navigate, students, preselect: params[1], onApply: applyDiscount }); return h(Discounts, { navigate, students, discounts }); }
    if (screen === "approvals") return h(Approvals, { navigate, students, payments, onApprove: approve, onReject: reject });
    if (screen === "reports") return h(FinanceReports, { navigate, students, payments, discounts });
    return h(window.FinanceDashboard, { navigate, students, payments });
  }

  window.Finance = Finance;
})();
