/* global React, I, UI, SSSData */
// =============== บัญชีธนาคาร · จ่ายเงินจากบัญชีบริษัท ===============
// ใบสำคัญจ่าย → กดจ่าย เลือกบัญชี (เงินสด/ธนาคาร) → รายการขึ้นที่บัญชีนั้น →
// กดอนุมัติจ่าย + อัพโหลดสลิป/หลักฐาน → บันทึกลงระบบบัญชี (สมุดรายวันจ่ายเงิน) อัตโนมัติ
const { useState: useStateCC, useEffect: useEffectCC } = React;

const CC_KEY = "sss-company-pay-v2"; // v2 = ล้าง dummy data เก่า
const CC_MONTHS = ["ม.ค.","ก.พ.","มี.ค.","เม.ย.","พ.ค.","มิ.ย.","ก.ค.","ส.ค.","ก.ย.","ต.ค.","พ.ย.","ธ.ค."];
function ccToday() { const d = new Date(); return `${d.getDate()} ${CC_MONTHS[d.getMonth()]} ${d.getFullYear() + 543}`; }
function ccTimeNow() { const d = new Date(); return `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`; }
function ccJournalDate() { const d = new Date(); return `${String(d.getDate()).padStart(2, "0")}/${String(d.getMonth() + 1).padStart(2, "0")}/${d.getFullYear() + 543}`; }

const CC_ACCOUNTS_SEED = [
  { id: "CASH", code: "1110", name: "เงินสดบริษัท", short: "เงินสด", detail: "ลิ้นชัก/ตู้เซฟ สำนักงาน", emoji: "💵", kind: "เงินสด" },
  { id: "SCB",  code: "1121", name: "ธ.ไทยพาณิชย์ ออมทรัพย์", short: "SCB", detail: "4211849819", emoji: "🏦", kind: "ธนาคาร" },
  { id: "BBL",  code: "1122", name: "ธ.กรุงเทพ", short: "BBL", detail: "5697260775", emoji: "🏦", kind: "ธนาคาร" }
];
const CC_ACC_KEY = "sss-bank-accounts";
function ccAccountsLoad() { try { const s = JSON.parse(localStorage.getItem(CC_ACC_KEY) || "null"); if (s && Array.isArray(s) && s.length) return s; } catch {} return CC_ACCOUNTS_SEED; }
function ccAccountsSave(list) { try { localStorage.setItem(CC_ACC_KEY, JSON.stringify(list)); } catch {} window.dispatchEvent(new Event("sss-bank-accounts-changed")); }
window.BankAccountsStore = { load: ccAccountsLoad, save: ccAccountsSave, SEED: CC_ACCOUNTS_SEED };
const ccAcc = (id) => ccAccountsLoad().find(a => a.id === id) || ccAccountsLoad()[0];

// แปลงเลขเอกสารในรายละเอียด (EX-/PO-/PV-/INV-) ให้เป็นลิงก์เปิดเอกสารต้นทาง
const CC_DOC_ROUTE = { PV: "payment-vouchers", EX: "expenses", INV: "invoices", PO: "purchase-orders", DN: "delivery-notes", QO: "quotations" };
function renderDescLinks(desc, navigate) {
  if (!desc) return desc;
  const parts = String(desc).split(/((?:PV|EX|INV|PO|DN|QO)-[0-9]{4}-[0-9]+)/g);
  return parts.map((p, i) => {
    const m = /^((?:PV|EX|INV|PO|DN|QO))-[0-9]{4}-[0-9]+$/.exec(p);
    if (m && CC_DOC_ROUTE[m[1]]) {
      const route = m[1] === "EX" ? "expenses" : CC_DOC_ROUTE[m[1]] + "/" + p;
      return <button key={i} className="mono" style={{ border: 0, background: "transparent", color: "var(--info)", cursor: "pointer", fontWeight: 600, padding: 0, fontSize: "inherit" }} title={"เปิดเอกสาร " + p} onClick={(ev) => { ev.stopPropagation(); navigate(route); }}>{p}</button>;
    }
    return <React.Fragment key={i}>{p}</React.Fragment>;
  });
}

// แหล่งที่มาของเงินเติมเข้าบัญชี — กู้ยืมจะสร้างหนี้รอชำระ (ค่าใช้จ่ายรอจ่าย)
const CC_FUND_SOURCES = [
  { id: "director", label: "เงินกู้ยืมกรรมการ", emoji: "🤝", loan: true, payee: "กรรมการ (เงินให้กู้ยืม)", repay: "ชำระคืนเงินกู้ยืมกรรมการ", credit: "2120" },
  { id: "bankloan", label: "สินเชื่อ / เงินกู้ธนาคาร", emoji: "🏦", loan: true, payee: "ธนาคาร (สินเชื่อ)", repay: "ชำระคืนสินเชื่อ/เงินกู้ธนาคาร", credit: "2130" },
  { id: "capital", label: "เงินทุน / ทุนเจ้าของ", emoji: "💰", loan: false, credit: "3110" },
  { id: "other", label: "รายรับอื่น ๆ", emoji: "➕", loan: false, credit: "4900" }
];
const CC_ACC_TONE = { CASH: "var(--c-amber, #b45309)", SCB: "var(--info, #2563eb)", BBL: "var(--c-violet, #7c3aed)" };
const CC_MONTHS_FULL = ["มกราคม","กุมภาพันธ์","มีนาคม","เมษายน","พฤษภาคม","มิถุนายน","กรกฎาคม","สิงหาคม","กันยายน","ตุลาคม","พฤศจิกายน","ธันวาคม"];
function ccParseThaiDate(str) {
  const p = String(str || "").trim().split(/\s+/);
  const d = parseInt(p[0], 10) || 1;
  const mi = CC_MONTHS.indexOf(p[1]);
  const y = (parseInt(p[2], 10) || 2569) - 543;
  return new Date(y, mi < 0 ? 0 : mi, d);
}
function ccGroupByMonth(rows) {
  const enriched = rows.map(r => ({ ...r, _d: ccParseThaiDate(r.date) }));
  enriched.sort((a, b) => b._d - a._d);
  const months = [];
  enriched.forEach(r => {
    const key = `${r._d.getFullYear()}-${r._d.getMonth()}`;
    let mo = months.find(m => m.key === key);
    if (!mo) { mo = { key, label: `${CC_MONTHS_FULL[r._d.getMonth()]} ${r._d.getFullYear() + 543}`, rows: [] }; months.push(mo); }
    mo.rows.push(r);
  });
  months.forEach(mo => {
    mo.batches = ccAccountsLoad().map(a => ({ acc: a, rows: mo.rows.filter(r => r.accountId === a.id) })).filter(b => b.rows.length > 0);
  });
  return months;
}

const CC_SEED = {
  baselines: { CASH: 0, SCB: 0, BBL: 0 },
  entries: []
};
function ccLoad() { try { return JSON.parse(localStorage.getItem(CC_KEY) || "null") || CC_SEED; } catch { return CC_SEED; } }
function ccSave(d) { try { localStorage.setItem(CC_KEY, JSON.stringify(d)); } catch {} window.dispatchEvent(new Event("sss-company-pay-changed")); }
function ccBalanceOf(d, accId) {
  const paid = d.entries.filter(e => e.accountId === accId && e.status === "จ่ายแล้ว").reduce((s, e) => s + e.amount, 0);
  const mv = (d.movements || []).filter(m => m.accountId === accId).reduce((s, m) => s + (m.direction === "in" ? m.amount : -m.amount), 0);
  return (d.baselines[accId] || 0) - paid + mv;
}

// API ให้หน้าอื่นใช้ (เช่น หน้าใบสำคัญจ่าย กด "จ่าย" → สร้างรายการรออนุมัติ)
window.CompanyCashStore = {
  get ACCOUNTS() { return ccAccountsLoad(); },
  load: ccLoad,
  balances() { const d = ccLoad(); return ccAccountsLoad().map(a => ({ ...a, balance: ccBalanceOf(d, a.id) })); },
  addPayment({ voucherNo, payee, desc, accountId, amount }) {
    const d = ccLoad();
    const dup = d.entries.find(e => e.voucherNo === voucherNo && voucherNo !== "—" && e.status === "รออนุมัติจ่าย");
    if (dup) return dup;
    const entry = { id: "CP-" + Date.now(), date: ccToday(), voucherNo: voucherNo || "—", payee, desc: desc || "", accountId, amount: +amount || 0, status: "รออนุมัติจ่าย", slip: null, je: null };
    d.entries = [entry, ...d.entries];
    ccSave(d);
    return entry;
  },
  // บันทึกเงินเข้า/ออกบัญชีโดยตรง (จากรายรับรายจ่าย / ค่าแรง / รับเงิน) — มีผลต่อยอดบัญชี
  addMovement({ accountId, direction, amount, desc, ref, source }) {
    const d = ccLoad();
    d.movements = d.movements || [];
    const id = "MV-" + Date.now() + "-" + Math.random().toString(36).slice(2, 6);
    d.movements.unshift({ id, accountId, direction, amount: +amount || 0, desc: desc || "", ref: ref || "", source: source || "", date: ccToday() });
    ccSave(d);
    return id;
  },
  removeMovement(id) {
    if (!id) return;
    const d = ccLoad();
    d.movements = (d.movements || []).filter(m => m.id !== id);
    ccSave(d);
  },
  accName(id) { return ccAcc(id).name; },
  accShort(id) { return ccAcc(id).short; },
  accEmoji(id) { return ccAcc(id).emoji; }
};

// ลงสมุดรายวันจ่ายเงิน (CP): Dr เจ้าหนี้/ค่าใช้จ่าย · Cr บัญชีที่จ่าย
function ccPostJournal(entry) {
  const A = window.SSSAccounting;
  if (!A) return null;
  const acc = ccAcc(entry.accountId);
  const nums = A.JournalEntries.filter(e => e.type === "CP").map(e => parseInt((e.id.split("-")[1]) || 0, 10));
  const id = "CP69-" + String(Math.max(200, ...nums, 0) + 1).padStart(4, "0");
  A.JournalEntries.unshift({
    id, type: "CP", date: ccJournalDate(), ref: entry.voucherNo !== "—" ? entry.voucherNo : "จ่ายเงินบริษัท",
    desc: `จ่ายเงิน ${entry.payee} — ${entry.desc || entry.voucherNo}`, by: "ระบบ · บัญชีบริษัท",
    lines: [
      { acc: "2110", dr: entry.amount, cr: 0, note: `จ่าย ${entry.payee}` },
      { acc: acc.code, dr: 0, cr: entry.amount, note: `จ่ายผ่าน${acc.short} (${acc.name})` }
    ]
  });
  return id;
}

// ลงสมุดรายวันรับเงินเข้าบัญชี (เติมเงิน/กู้): Dr เงินสด/ธนาคาร · Cr เงินกู้/ทุน
function ccPostReceiptJournal(accountId, amount, source, note) {
  const A = window.SSSAccounting;
  if (!A) return null;
  const acc = ccAcc(accountId);
  const nums = A.JournalEntries.filter(e => e.type === "GJ").map(e => parseInt((e.id.split("-")[1]) || 0, 10));
  const id = "GJ69-" + String(Math.max(120, ...nums, 0) + 1).padStart(4, "0");
  A.JournalEntries.unshift({
    id, type: "GJ", date: ccJournalDate(), ref: "เติมเงินเข้าบัญชี",
    desc: `เติมเงินเข้า${acc.short} — ${source.label}${note ? " · " + note : ""}`, by: "ระบบ · บัญชีบริษัท",
    lines: [
      { acc: acc.code, dr: amount, cr: 0, note: `รับเงินเข้า${acc.name}` },
      { acc: source.credit, dr: 0, cr: amount, note: source.label }
    ]
  });
  return id;
}
function CCModal({ title, children, onClose, footer, width = 460 }) {
  return (
    <>
      <div className="scrim" style={{ zIndex: 80 }} onClick={onClose}></div>
      <div style={{ position: "fixed", left: "50%", top: "50%", transform: "translate(-50%, -50%)", zIndex: 81, background: "var(--surface)", border: "1px solid var(--line)", borderRadius: 12, padding: 18, width, maxWidth: "94vw", maxHeight: "92vh", overflowY: "auto", boxShadow: "var(--shadow-lg)" }}>
        <div style={{ fontSize: 14.5, fontWeight: 700, marginBottom: 12 }}>{title}</div>
        {children}
        <div style={{ display: "flex", gap: 8, justifyContent: "flex-end", marginTop: 14 }}>{footer}</div>
      </div>
    </>
  );
}

// เลือกบัญชีจ่าย (การ์ดเรดิโอ) — ใช้ซ้ำในหลาย modal
function CCAccountPicker({ value, onChange, balances }) {
  const { fmt0 } = window.UI;
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
      {balances.map(a => (
        <label key={a.id} style={{ display: "flex", alignItems: "center", gap: 10, padding: "9px 12px", border: value === a.id ? "1.5px solid var(--accent)" : "1px solid var(--line)", borderRadius: 10, cursor: "pointer", background: value === a.id ? "var(--surface-2)" : "var(--surface)" }}>
          <input type="radio" name="cc-acc" checked={value === a.id} onChange={() => onChange(a.id)}></input>
          <span style={{ fontSize: 18 }}>{a.emoji}</span>
          <span style={{ flex: 1, minWidth: 0 }}>
            <span style={{ display: "block", fontSize: 13, fontWeight: 600 }}>{a.name}</span>
            <span style={{ display: "block", fontSize: 11, color: "var(--ink-3)" }}>{a.detail} · บัญชี {a.code}</span>
          </span>
          <span className="amount" style={{ fontSize: 12.5, fontWeight: 600 }}>฿{fmt0(a.balance)}</span>
        </label>
      ))}
    </div>
  );
}
window.CCAccountPicker = CCAccountPicker;

function CompanyCashPage({ navigate }) {
  const D = window.SSSData;
  const { Btn, Badge, Card, PageHead, Tabs, fmt0 } = window.UI;
  const [data, setData] = useStateCC(ccLoad);
  const [tab, setTab] = useStateCC("ALL");
  const [modal, setModal] = useStateCC(null); // "new" | "set"
  const [approveFor, setApproveFor] = useStateCC(null);
  const [slipView, setSlipView] = useStateCC(null);
  const [view, setView] = useStateCC("group");   // group | flat
  const [statusF, setStatusF] = useStateCC("all");
  const [q, setQ] = useStateCC("");

  useEffectCC(() => {
    const h = () => setData(ccLoad());
    window.addEventListener("sss-company-pay-changed", h);
    window.addEventListener("sss-bank-accounts-changed", h);
    return () => { window.removeEventListener("sss-company-pay-changed", h); window.removeEventListener("sss-bank-accounts-changed", h); };
  }, []);

  const CC_ACCOUNTS = ccAccountsLoad();

  const balances = CC_ACCOUNTS.map(a => ({ ...a, balance: ccBalanceOf(data, a.id), pending: data.entries.filter(e => e.accountId === a.id && e.status === "รออนุมัติจ่าย") }));
  const pendingAll = data.entries.filter(e => e.status === "รออนุมัติจ่าย");
  const pendingSum = pendingAll.reduce((s, e) => s + e.amount, 0);
  const totalAll = balances.reduce((s, a) => s + a.balance, 0);
  const paidList = data.entries.filter(e => e.status === "จ่ายแล้ว");
  const paidSum = paidList.reduce((s, e) => s + e.amount, 0);
  const slipCount = paidList.filter(e => e.slip).length;
  const jeCount = data.entries.filter(e => e.je).length;
  const byTab = data.entries.filter(e => tab === "ALL" || e.accountId === tab);
  const byStatus = statusF === "all" ? byTab : byTab.filter(e => e.status === statusF);
  const entries = q.trim() ? byStatus.filter(e => (e.voucherNo + " " + e.payee + " " + (e.desc || "")).toLowerCase().includes(q.trim().toLowerCase())) : byStatus;
  const grouped = ccGroupByMonth(entries);
  const commit = (next) => { setData(next); ccSave(next); };

  // ── สร้างรายการจ่าย ──
  const [f, setF] = useStateCC({ pv: "", payee: "", desc: "", amount: "", accountId: "SCB" });
  const upd = (k, v) => setF(p => ({ ...p, [k]: v }));
  const pickPV = (no) => {
    const pv = (D.PaymentVouchers || []).find(p => p.no === no);
    if (pv) setF(p => ({ ...p, pv: no, payee: pv.payee, amount: pv.amount, desc: `ตามใบสำคัญจ่าย ${pv.no} · อ้างอิง ${pv.ref}` }));
    else setF(p => ({ ...p, pv: no }));
  };
  const saveNew = () => {
    if (!f.payee.trim()) { window.toast && window.toast("กรอกชื่อผู้รับเงิน"); return; }
    if (!(+f.amount > 0)) { window.toast && window.toast("กรอกยอดจ่ายให้ถูกต้อง"); return; }
    const entry = window.CompanyCashStore.addPayment({ voucherNo: f.pv || "—", payee: f.payee.trim(), desc: f.desc.trim(), accountId: f.accountId, amount: +f.amount });
    const acc = ccAcc(f.accountId);
    window.logActivity && window.logActivity("สร้างรายการจ่าย", `${entry.payee} ฿${fmt0(entry.amount)} ผ่าน${acc.short}`, "expense");
    window.toast && window.toast(`สร้างรายการจ่าย ฿${fmt0(entry.amount)} ขึ้นที่บัญชี${acc.short}แล้ว — รออนุมัติจ่าย`);
    setF({ pv: "", payee: "", desc: "", amount: "", accountId: "SCB" });
    setModal(null);
  };

  // ── ตั้งยอดบัญชี ──
  const [setAcc, setSetAcc] = useStateCC("CASH");
  const [setAmt, setSetAmt] = useStateCC("");
  const saveSet = () => {
    const v = +setAmt;
    if (isNaN(v) || v < 0) { window.toast && window.toast("กรอกยอดเงินให้ถูกต้อง"); return; }
    const paid = data.entries.filter(e => e.accountId === setAcc && e.status === "จ่ายแล้ว").reduce((s, e) => s + e.amount, 0);
    commit({ ...data, baselines: { ...data.baselines, [setAcc]: v + paid } });
    window.logActivity && window.logActivity("ตั้งยอดบัญชี", `${ccAcc(setAcc).name} = ฿${fmt0(v)}`, "update");
    window.toast && window.toast(`ตั้งยอด${ccAcc(setAcc).short}เป็น ฿${fmt0(v)} แล้ว`);
    setSetAmt(""); setModal(null);
  };

  // ---------- แถวรายการ (ใช้ซ้ำทั้งแบบ group และ flat) ----------
  const renderRow = (e) => {
    const acc = ccAcc(e.accountId);
    return (
      <tr key={e.id}>
        <td style={{ whiteSpace: "nowrap" }}>{e.date}</td>
        <td>{e.voucherNo !== "—"
          ? <button className="badge outline mono" style={{ cursor: "pointer" }} title="เปิดใบสำคัญจ่าย" onClick={() => navigate("payment-vouchers/" + e.voucherNo)}>{e.voucherNo}</button>
          : <span className="muted">—</span>}</td>
        <td style={{ fontWeight: 500 }}>{e.payee}</td>
        <td className="muted" style={{ maxWidth: 260, fontSize: 12 }}><span style={{ display: "block", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{renderDescLinks(e.desc, navigate)}</span></td>
        <td><Badge tone={e.accountId === "CASH" ? "warning" : "info"}>{acc.emoji} {acc.short}</Badge></td>
        <td className="right amount" style={{ fontWeight: 600 }}>฿{fmt0(e.amount)}</td>
        <td>{e.slip
          ? <button className="badge outline" style={{ cursor: "pointer" }} onClick={() => e.slip.url ? setSlipView(e.slip) : (window.toast && window.toast(e.slip.name))} title={e.slip.name}>📎 สลิป</button>
          : <span className="muted" style={{ fontSize: 11.5 }}>ยังไม่แนบ</span>}</td>
        <td>{e.status === "จ่ายแล้ว"
          ? <div><Badge tone="success">จ่ายแล้ว</Badge>{e.je && <div style={{ marginTop: 3 }}><button className="badge outline mono" style={{ cursor: "pointer", fontSize: 10 }} onClick={() => navigate("accounting")} title="เปิดสมุดรายวัน">{e.je}</button></div>}</div>
          : <Badge tone="warning" dot>รออนุมัติจ่าย</Badge>}</td>
        <td onClick={ev => ev.stopPropagation()}>
          <div style={{ display: "flex", gap: 4, justifyContent: "flex-end" }}>
            {e.status === "รออนุมัติจ่าย" && <Btn size="sm" kind="primary" icon={I.check} onClick={() => setApproveFor(e)}>อนุมัติจ่าย</Btn>}
            {e.status === "รออนุมัติจ่าย" && <button className="icon-btn" title="ยกเลิกรายการ" onClick={async () => {
              const ok = await window.confirmDelete(`รายการจ่าย ${e.payee}`, `฿${fmt0(e.amount)} · ${e.voucherNo}`);
              if (!ok) return;
              commit({ ...data, entries: data.entries.filter(x => x.id !== e.id) });
            }}><I.trash size={13} /></button>}
          </div>
        </td>
      </tr>
    );
  };

  // ── เติมเงิน / กู้เงินเข้าบัญชี ──
  const [tu, setTu] = useStateCC({ accountId: "SCB", sourceId: "director", amount: "", note: "" });
  const tuUpd = (k, v) => setTu(p => ({ ...p, [k]: v }));
  const saveTopup = () => {
    const amt = +tu.amount;
    if (!(amt > 0)) { window.toast && window.toast("กรอกจำนวนเงินที่เติมให้ถูกต้อง"); return; }
    const acc = ccAcc(tu.accountId);
    const src = CC_FUND_SOURCES.find(s => s.id === tu.sourceId) || CC_FUND_SOURCES[0];
    // 1) เงินเข้าบัญชีทันที (ยอดขึ้น)
    window.CompanyCashStore.addMovement({ accountId: tu.accountId, direction: "in", amount: amt, desc: `เติมเงินเข้า${acc.short} — ${src.label}${tu.note ? " · " + tu.note : ""}`, ref: "เติมเงิน", source: src.label });
    // 2) ลงสมุดรายวันรับเงิน
    const je = ccPostReceiptJournal(tu.accountId, amt, src, tu.note.trim());
    // 3) ถ้าเป็นเงินกู้ → สร้างรายการค่าใช้จ่ายรอจ่าย (ชำระคืน) อัตโนมัติ
    if (src.loan) {
      window.CompanyCashStore.addPayment({ voucherNo: "—", payee: src.payee, desc: `${src.repay}${tu.note ? " · " + tu.note : ""} (ยอดกู้ ฿${fmt0(amt)})`, accountId: tu.accountId, amount: amt });
    }
    window.logActivity && window.logActivity("เติมเงินเข้าบัญชี", `${acc.short} +฿${fmt0(amt)} · ${src.label}`, "income");
    window.toast && window.toast(src.loan
      ? `เติมเงินเข้า${acc.name} ฿${fmt0(amt)} (${src.label}) — สร้างรายการคืนเงินไว้ที่ ค่าใช้จ่ายรอจ่าย แล้ว`
      : `เติมเงินเข้า${acc.name} ฿${fmt0(amt)} (${src.label}) แล้ว · ลงบัญชี ${je || ""}`);
    setTu({ accountId: tu.accountId, sourceId: tu.sourceId, amount: "", note: "" });
    setModal(null);
  };

  return (
    <>
      <PageHead
        title="บัญชีธนาคาร · จ่ายเงินบริษัท"
        sub="กดจ่ายใบสำคัญจ่าย → เลือกบัญชี (เงินสด/ธนาคาร) → อนุมัติจ่าย + แนบสลิป → บันทึกลงระบบบัญชีอัตโนมัติ"
        right={<>
          <Btn icon={I.edit} kind="ghost" onClick={() => { setSetAmt(""); setModal("set"); }}>ตั้งยอดบัญชี</Btn>
          <Btn icon={I.book} kind="ghost" onClick={() => navigate("accounting")}>สมุดรายวัน</Btn>
          <Btn icon={I.arrowDown} kind="ghost" onClick={() => setModal("topup")}>เติมเงิน / กู้เงิน</Btn>
          <Btn icon={I.plus} kind="primary" onClick={() => setModal("new")}>สร้างรายการจ่าย</Btn>
        </>}
      />

      {/* การ์ดบัญชี */}
      <div className="grid cols-3 mb-lg">
        {balances.map(a => (
          <div key={a.id} onClick={() => setTab(a.id)} style={{ cursor: "pointer", padding: 14, background: "var(--surface)", border: tab === a.id ? "1.5px solid var(--accent)" : "1px solid var(--line)", borderRadius: "var(--radius, 10px)", display: "flex", flexDirection: "column", gap: 6 }}>
            <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
              <span style={{ fontSize: 20 }}>{a.emoji}</span>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 13, fontWeight: 700 }}>{a.name}</div>
                <div style={{ fontSize: 10.5, color: "var(--ink-3)" }}>{a.detail} · ผังบัญชี {a.code}</div>
              </div>
            </div>
            <div style={{ fontSize: 21, fontWeight: 700, fontVariantNumeric: "tabular-nums" }}>฿{fmt0(a.balance)}</div>
            <div style={{ fontSize: 11.5, color: a.pending.length ? "var(--warning)" : "var(--ink-3)", fontWeight: a.pending.length ? 600 : 400 }}>
              {a.pending.length ? `⏳ รออนุมัติจ่าย ${a.pending.length} รายการ · ฿${fmt0(a.pending.reduce((s, e) => s + e.amount, 0))}` : "ไม่มีรายการค้างอนุมัติ"}
            </div>
          </div>
        ))}
      </div>

      <div className="grid cols-4 mb-lg">
        <UI.Stat label="รวมเงินทุกบัญชี" value={`฿${fmt0(totalAll)}`} sub={`${CC_ACCOUNTS.length} บัญชี · เงินสด + ธนาคาร`} icon={I.money} />
        <UI.Stat label="รออนุมัติจ่าย" value={pendingAll.length} sub={`฿${fmt0(pendingSum)} รอจ่าย`} icon={I.clock} deltaDir={pendingAll.length ? "down" : ""} />
        <UI.Stat label="จ่ายแล้ว (จำนวนใบ)" value={paidList.length} sub={`รวม ฿${fmt0(paidSum)}`} icon={I.receipt} />
        <UI.Stat label="ลงบัญชีแล้ว" value={`${jeCount} รายการ`} sub={`แนบสลิป ${slipCount} · สมุดรายวัน CP`} icon={I.book} />
      </div>

      <Card flush padded={false}>
        <div style={{ padding: 12, borderBottom: "1px solid var(--line)", display: "flex", gap: 10, alignItems: "center", flexWrap: "wrap" }}>
          <Tabs
            items={[{ key: "ALL", label: "ทุกบัญชี", count: data.entries.length }, ...CC_ACCOUNTS.map(a => ({ key: a.id, label: a.short, count: data.entries.filter(e => e.accountId === a.id).length }))]}
            active={tab} onChange={setTab}
          />
          <span className="spacer" />
          {/* ตัวกรองสถานะ */}
          <div className="seg">
            {[{ k: "all", l: "ทุกสถานะ" }, { k: "รออนุมัติจ่าย", l: "รออนุมัติ" }, { k: "จ่ายแล้ว", l: "จ่ายแล้ว" }].map(o => (
              <button key={o.k} className={`seg-btn ${statusF === o.k ? "on" : ""}`} onClick={() => setStatusF(o.k)}>{o.l}</button>
            ))}
          </div>
          {/* view toggle */}
          <div className="seg">
            <button className={`seg-btn ${view === "group" ? "on" : ""}`} onClick={() => setView("group")} title="จัดกลุ่มตามเดือน + บัญชี"><I.calc size={13} className="icon" />จัดกลุ่ม</button>
            <button className={`seg-btn ${view === "flat" ? "on" : ""}`} onClick={() => setView("flat")} title="ตารางปกติ"><I.receipt size={13} className="icon" />ตาราง</button>
          </div>
          <div className="search" style={{ width: 220 }}><I.search size={14} /><input placeholder="ค้นหาผู้รับเงิน/ใบสำคัญจ่าย…" value={q} onChange={e => setQ(e.target.value)} /></div>
        </div>
        <div className="table-wrap">
          <table className="t ca-table">
            <thead><tr><th>วันที่</th><th>ใบสำคัญจ่าย</th><th>ผู้รับเงิน</th><th>รายละเอียด</th><th>จ่ายจากบัญชี</th><th className="right">ยอดจ่าย</th><th>หลักฐาน</th><th>สถานะ</th><th></th></tr></thead>
            {view === "flat" ? (
              <tbody>
                {entries.length === 0 && <tr><td colSpan={9} style={{ padding: 30, textAlign: "center", color: "var(--ink-3)" }}>ไม่มีรายการในเงื่อนไขที่เลือก</td></tr>}
                {entries.map(renderRow)}
              </tbody>
            ) : (
              grouped.map(mo => {
                const moSum = mo.rows.reduce((s, r) => s + r.amount, 0);
                return (
                  <tbody key={mo.key}>
                    <tr className="ca-month">
                      <td colSpan={9}>
                        <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                          <I.calc size={14} style={{ color: "var(--ink-3)" }} />
                          <span style={{ fontWeight: 700, fontSize: 13.5 }}>{mo.label}</span>
                          <span style={{ fontSize: 11.5, color: "var(--ink-3)" }}>{mo.rows.length} รายการ · {mo.batches.length} บัญชี</span>
                          <span className="spacer" />
                          <span style={{ fontSize: 12, color: "var(--ink-3)" }}>รวมจ่าย</span>
                          <span className="amount" style={{ fontWeight: 700, fontSize: 13.5 }}>฿{fmt0(moSum)}</span>
                        </div>
                      </td>
                    </tr>
                    {mo.batches.map(b => {
                      const bSum = b.rows.reduce((s, r) => s + r.amount, 0);
                      const tone = CC_ACC_TONE[b.acc.id] || "var(--ink-3)";
                      return (
                        <React.Fragment key={b.acc.id}>
                          <tr className="ca-batch">
                            <td colSpan={9}>
                              <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                                <span style={{ display: "inline-flex", alignItems: "center", gap: 6, padding: "3px 10px", borderRadius: 999, background: `color-mix(in srgb, ${tone} 14%, transparent)`, color: tone, fontWeight: 600, fontSize: 11.5 }}>
                                  <span style={{ width: 7, height: 7, borderRadius: "50%", background: tone }} />
                                  {b.acc.emoji} {b.acc.name}
                                </span>
                                <span style={{ fontSize: 11.5, color: "var(--ink-3)" }}>{b.rows.length} รายการ</span>
                                <span className="spacer" />
                                <span className="amount" style={{ fontWeight: 600, fontSize: 12.5, color: "var(--ink-2)" }}>฿{fmt0(bSum)}</span>
                              </div>
                            </td>
                          </tr>
                          {b.rows.map(renderRow)}
                        </React.Fragment>
                      );
                    })}
                  </tbody>
                );
              })
            )}
          </table>
          {view === "group" && grouped.length === 0 && <div style={{ padding: 30, textAlign: "center", color: "var(--ink-3)" }}>ไม่มีรายการในเงื่อนไขที่เลือก</div>}
        </div>
        <div style={{ padding: "10px 14px", borderTop: "1px solid var(--line)", fontSize: 12, color: "var(--ink-3)" }}>
          เมื่อ <b style={{ color: "var(--ink-1)" }}>อนุมัติจ่าย + แนบสลิป</b> ระบบจะลงสมุดรายวันจ่ายเงิน (CP) — Dr เจ้าหนี้ / Cr บัญชีที่จ่าย — และเปลี่ยนสถานะใบสำคัญจ่ายเป็น "จ่ายแล้ว" ให้อัตโนมัติ
        </div>
      </Card>

      {/* ── เติมเงิน / กู้เงินเข้าบัญชี ── */}
      {modal === "topup" && (() => {
        const src = CC_FUND_SOURCES.find(s => s.id === tu.sourceId) || CC_FUND_SOURCES[0];
        const acc = ccAcc(tu.accountId);
        return (
          <CCModal title="เติมเงิน / กู้เงินเข้าบัญชี" onClose={() => setModal(null)} width={500}
            footer={<><Btn kind="ghost" onClick={() => setModal(null)}>ยกเลิก</Btn><Btn kind="primary" icon={I.check} onClick={saveTopup}>เติมเงินเข้าบัญชี</Btn></>}>
            <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
              <div className="field"><label>แหล่งที่มาของเงิน</label>
                <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
                  {CC_FUND_SOURCES.map(s => (
                    <label key={s.id} style={{ display: "flex", alignItems: "center", gap: 10, padding: "9px 12px", border: tu.sourceId === s.id ? "1.5px solid var(--accent)" : "1px solid var(--line)", borderRadius: 10, cursor: "pointer", background: tu.sourceId === s.id ? "var(--surface-2)" : "var(--surface)" }}>
                      <input type="radio" name="cc-src" checked={tu.sourceId === s.id} onChange={() => tuUpd("sourceId", s.id)}></input>
                      <span style={{ fontSize: 18 }}>{s.emoji}</span>
                      <span style={{ flex: 1 }}>
                        <span style={{ display: "block", fontSize: 13, fontWeight: 600 }}>{s.label}</span>
                        <span style={{ display: "block", fontSize: 11, color: "var(--ink-3)" }}>{s.loan ? "มีภาระต้องชำระคืน — จะสร้างค่าใช้จ่ายรอจ่ายให้อัตโนมัติ" : "ไม่ต้องชำระคืน"}</span>
                      </span>
                    </label>
                  ))}
                </div>
              </div>
              <div className="field"><label>เข้าบัญชี</label>
                <CCAccountPicker value={tu.accountId} onChange={v => tuUpd("accountId", v)} balances={balances} />
              </div>
              <div className="field"><label>จำนวนเงินที่เติม (บาท) *</label>
                <input className="input" type="number" min="0" value={tu.amount} onChange={e => tuUpd("amount", e.target.value)} autoFocus style={{ fontSize: 16, fontWeight: 600 }}></input>
              </div>
              <div className="field"><label>หมายเหตุ (ไม่บังคับ)</label>
                <input className="input" value={tu.note} onChange={e => tuUpd("note", e.target.value)} placeholder="เช่น กู้เสริมสภาพคล่อง / ลงทุนเพิ่ม"></input>
              </div>
              {tu.amount > 0 && (
                <div style={{ padding: "10px 14px", background: "var(--surface-2)", border: "1px solid var(--line)", borderRadius: 10, fontSize: 12, color: "var(--ink-2)", lineHeight: 1.8 }}>
                  ✓ {acc.emoji} {acc.name} จะเพิ่มขึ้น <b style={{ color: "var(--success)" }}>+฿{fmt0(+tu.amount)}</b> (เป็น ฿{fmt0((balances.find(b => b.id === tu.accountId)?.balance || 0) + (+tu.amount))})<br />
                  ✓ ลงสมุดรายวัน: Dr {acc.code} {acc.short} / Cr {src.credit} {src.label}
                  {src.loan && <><br />✓ สร้างค่าใช้จ่ายรอจ่าย "{src.repay}" <b style={{ color: "var(--warning)" }}>฿{fmt0(+tu.amount)}</b> รอชำระคืน</>}
                </div>
              )}
            </div>
          </CCModal>
        );
      })()}

      {/* ── สร้างรายการจ่าย ── */}
      {modal === "new" && (
        <CCModal title="สร้างรายการจ่ายจากบัญชีบริษัท" onClose={() => setModal(null)} width={500}
          footer={<><Btn kind="ghost" onClick={() => setModal(null)}>ยกเลิก</Btn><Btn kind="primary" icon={I.check} onClick={saveNew}>สร้างรายการ (รออนุมัติจ่าย)</Btn></>}>
          <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
            <div className="field"><label>อ้างอิงใบสำคัญจ่าย (ไม่บังคับ)</label>
              <select className="input" value={f.pv} onChange={e => pickPV(e.target.value)}>
                <option value="">— ไม่อ้างอิง / จ่ายอื่น ๆ —</option>
                {(D.PaymentVouchers || []).map(p => <option key={p.no} value={p.no}>{p.no} · {p.payee} · ฿{fmt0(p.amount)}</option>)}
              </select>
            </div>
            <div className="field-row cols-2">
              <div className="field"><label>ผู้รับเงิน *</label><input className="input" value={f.payee} onChange={e => upd("payee", e.target.value)}></input></div>
              <div className="field"><label>ยอดจ่าย (บาท) *</label><input className="input" type="number" min="0" value={f.amount} onChange={e => upd("amount", e.target.value)}></input></div>
            </div>
            <div className="field"><label>รายละเอียด</label><input className="input" value={f.desc} onChange={e => upd("desc", e.target.value)} placeholder="เช่น ค่าวัตถุดิบตาม PO…"></input></div>
            <div className="field"><label>จ่ายจากบัญชี *</label>
              <CCAccountPicker value={f.accountId} onChange={v => upd("accountId", v)} balances={balances} />
            </div>
          </div>
        </CCModal>
      )}

      {/* ── ตั้งยอดบัญชี ── */}
      {modal === "set" && (
        <CCModal title="ตั้งยอดเงินในบัญชี" onClose={() => setModal(null)}
          footer={<><Btn kind="ghost" onClick={() => setModal(null)}>ยกเลิก</Btn><Btn kind="primary" icon={I.check} onClick={saveSet}>ตั้งยอด</Btn></>}>
          <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
            <div className="field"><label>บัญชี</label>
              <select className="input" value={setAcc} onChange={e => setSetAcc(e.target.value)}>
                {balances.map(a => <option key={a.id} value={a.id}>{a.name} — ปัจจุบัน ฿{fmt0(a.balance)}</option>)}
              </select>
            </div>
            <div className="field"><label>ยอดที่ถูกต้องตามจริง (บาท)</label>
              <input className="input" type="number" min="0" value={setAmt} onChange={e => setSetAmt(e.target.value)} autoFocus placeholder="กระทบยอดกับ statement / นับเงินจริง"></input>
            </div>
          </div>
        </CCModal>
      )}

      {/* ── อนุมัติจ่าย + แนบสลิป ── */}
      {approveFor && (
        <CCApproveModal entry={approveFor} balances={balances} navigate={navigate} onClose={() => setApproveFor(null)}
          onApproved={(updated) => {
            const next = { ...data, entries: data.entries.map(x => x.id === updated.id ? updated : x) };
            commit(next);
            setApproveFor(null);
          }} />
      )}

      {/* ── ดูสลิป ── */}
      {slipView && slipView.url && (
        <div className="scrim" style={{ display: "flex", alignItems: "center", justifyContent: "center", padding: 24, zIndex: 240 }} onClick={() => setSlipView(null)}>
          <div style={{ position: "relative", maxWidth: "90vw", maxHeight: "90vh" }}>
            <img src={slipView.url} alt={slipView.name} style={{ maxWidth: "90vw", maxHeight: "88vh", borderRadius: 8, boxShadow: "0 20px 60px rgba(0,0,0,0.4)" }} />
            <div style={{ position: "absolute", left: 0, bottom: -26, color: "white", fontSize: 12 }}>{slipView.name}</div>
          </div>
        </div>
      )}
    </>
  );
}

// ---------- Modal อนุมัติจ่าย ----------
function CCApproveModal({ entry, balances, onClose, onApproved, navigate }) {
  const { Btn, Badge, fmt0 } = window.UI;
  const [accountId, setAccountId] = useStateCC(entry.accountId);
  const [slip, setSlip] = useStateCC(null);
  const acc = ccAcc(accountId);
  const bal = (balances.find(a => a.id === accountId) || {}).balance || 0;

  const pickSlip = (e) => {
    const file = e.target.files[0];
    e.target.value = "";
    if (!file) return;
    if (file.type.startsWith("image/") && window.DeliveryStore && window.DeliveryStore.resizeImage) {
      window.DeliveryStore.resizeImage(file, 900).then(url => setSlip({ name: file.name, url }));
    } else {
      const r = new FileReader();
      r.onload = () => setSlip({ name: file.name, url: file.type.startsWith("image/") ? r.result : null });
      r.readAsDataURL(file);
    }
  };

  const approve = () => {
    if (!slip) { window.toast && window.toast("กรุณาแนบสลิป/หลักฐานการจ่ายก่อนอนุมัติ"); return; }
    if (entry.amount > bal) { window.toast && window.toast(`ยอดเงินใน${acc.short}ไม่พอ — คงเหลือ ฿${fmt0(bal)}`); return; }
    const je = ccPostJournal({ ...entry, accountId });
    const updated = { ...entry, accountId, status: "จ่ายแล้ว", slip, je, approvedBy: window.SSSData.Company.currentUser?.name || "ปิยะ ศ.", paidAt: `${ccToday()} ${ccTimeNow()}` };
    // อัพเดทสถานะใบสำคัญจ่ายให้อัตโนมัติ
    if (entry.voucherNo !== "—" && window.DocStatusStore) {
      window.DocStatusStore.set("payment-voucher", entry.voucherNo, "จ่ายแล้ว");
    }
    window.logActivity && window.logActivity("อนุมัติจ่าย", `${entry.payee} ฿${fmt0(entry.amount)} ผ่าน${acc.short} · ลงบัญชี ${je || "—"}`, "approve");
    window.toast && window.toast(`อนุมัติจ่าย ฿${fmt0(entry.amount)} ผ่าน${acc.short}แล้ว · บันทึกลงสมุดรายวัน ${je || ""} ✓`);
    onApproved(updated);
  };

  return (
    <CCModal title="อนุมัติจ่าย + แนบหลักฐาน" onClose={onClose} width={500}
      footer={<><Btn kind="ghost" onClick={onClose}>ยกเลิก</Btn><Btn kind="primary" icon={I.check} onClick={approve}>อนุมัติจ่าย + ลงบัญชี</Btn></>}>
      <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
        <div style={{ padding: "10px 14px", background: "var(--surface-2)", border: "1px solid var(--line)", borderRadius: 10, fontSize: 13 }}>
          <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 4 }}><span className="muted">ผู้รับเงิน</span><b>{entry.payee}</b></div>
          <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 4 }}><span className="muted">ใบสำคัญจ่าย</span>{entry.voucherNo !== "—" ? <button className="badge outline mono" style={{ cursor: "pointer" }} onClick={() => navigate && navigate("payment-vouchers/" + entry.voucherNo)}>{entry.voucherNo} ↗</button> : <span className="mono">—</span>}</div>
        <div style={{ fontSize: 11.5, color: "var(--ink-3)", marginTop: 2 }}>{renderDescLinks(entry.desc, navigate || (() => {}))}</div>
          <div style={{ display: "flex", justifyContent: "space-between" }}><span className="muted">ยอดจ่าย</span><b className="amount" style={{ fontSize: 16 }}>฿{fmt0(entry.amount)}</b></div>
        </div>

        <div className="field"><label>จ่ายจากบัญชี</label>
          <CCAccountPicker value={accountId} onChange={setAccountId} balances={balances} />
        </div>

        <div className="field"><label>สลิปโอน / หลักฐานการจ่าย * {acc.id === "CASH" ? "(บิล/ใบรับเงิน)" : "(สลิปธนาคาร)"}</label>
          {!slip ? (
            <label style={{ cursor: "pointer", display: "block" }}>
              <input type="file" accept="image/*,application/pdf" style={{ display: "none" }} onChange={pickSlip}></input>
              <div style={{ padding: "20px 12px", border: "1.5px dashed var(--line-strong)", borderRadius: 10, textAlign: "center", color: "var(--ink-3)", fontSize: 12.5 }}>
                <I.upload size={20} />
                <div style={{ marginTop: 6 }}>คลิกเพื่ออัพโหลดสลิป/หลักฐาน (JPG, PNG, PDF)</div>
              </div>
            </label>
          ) : (
            <div style={{ display: "flex", alignItems: "center", gap: 10, padding: 8, border: "1px solid var(--line)", borderRadius: 10 }}>
              {slip.url
                ? <img src={slip.url} alt={slip.name} style={{ width: 54, height: 54, objectFit: "cover", borderRadius: 6, border: "1px solid var(--line)" }} />
                : <div style={{ width: 54, height: 54, borderRadius: 6, background: "var(--surface-2)", display: "grid", placeItems: "center", fontSize: 10, fontWeight: 700, color: "var(--ink-3)" }}>PDF</div>}
              <div style={{ flex: 1, minWidth: 0, fontSize: 12.5, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{slip.name}</div>
              <Badge tone="success">พร้อมบันทึก ✓</Badge>
              <button className="icon-btn" onClick={() => setSlip(null)}><I.trash size={13} /></button>
            </div>
          )}
        </div>

        <div style={{ padding: "8px 12px", background: "var(--surface-2)", borderRadius: 8, fontSize: 11.5, color: "var(--ink-3)", lineHeight: 1.7 }}>
          เมื่อกดอนุมัติ: ✓ ตัดยอดจาก{acc.short} ✓ ลงสมุดรายวันจ่ายเงิน (Dr 2110 / Cr {acc.code}) ✓ เปลี่ยนสถานะใบสำคัญจ่ายเป็น "จ่ายแล้ว"
        </div>
      </div>
    </CCModal>
  );
}

window.CompanyCash = CompanyCashPage;
