/* ============================================================
   ELECTROMED — Finance: GST register · Withholding tax · Bank reconciliation
   All data live from /api/v1/finance/*. Exports via window.ExportKit.
   ============================================================ */
function useFetch(fn, deps) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [tick, setTick] = useState(0);
  const refetch = () => setTick(t => t + 1);
  useEffect(() => {
    let go = true; setLoading(true);
    fn().then(d => { if (go) setData(d); }).catch(() => { if (go) setData(null); }).finally(() => { if (go) setLoading(false); });
    return () => { go = false; };
  }, [...(deps || []), tick]);
  return { data, loading, refetch };
}

function Finance({ branch }) {
  const [tab, setTab] = useState('GST');
  return (
    <div className="view-enter">
      <PageHead eyebrow="09 · Finance" title="Tax & Bank"
        sub="GST / sales-tax register, withholding-tax tracking and bank reconciliation."
        actions={<div className="tabs">
          <button className={cls('tab', tab === 'GST' && 'active')} onClick={() => setTab('GST')}>GST Register</button>
          <button className={cls('tab', tab === 'WHT' && 'active')} onClick={() => setTab('WHT')}>Withholding Tax</button>
          <button className={cls('tab', tab === 'BANK' && 'active')} onClick={() => setTab('BANK')}>Bank Reconciliation</button>
        </div>} />
      {tab === 'GST' ? <GstRegister branch={branch} /> : tab === 'WHT' ? <WhtRegister branch={branch} /> : <BankRecon branch={branch} />}
    </div>
  );
}

/* ── GST / Sales-tax register ─────────────────────────────────── */
function GstRegister({ branch }) {
  const { PKR } = window.DATA;
  const [entity, setEntity] = useState('');
  const [q, setQ] = useState('');
  const [add, setAdd] = useState(false);
  const bf = () => ({ ...(branch !== 'All' ? { branch_id: branch } : {}), entity: entity || undefined, search: q || undefined });
  const { data, loading, refetch } = useFetch(() => api.getGstRegister(bf()), [branch, entity, q]);
  const rows = (data && data.rows) || [];
  const totals = (data && data.totals) || {};
  const cols = [
    { key: 'entity', label: 'Entity' }, { key: 'inv_no', label: 'Inv #' }, { key: 'emck_no', label: 'EMCK #' },
    { key: 'month', label: 'Month' }, { key: 'bill_to', label: 'Bill To' },
    { key: 'amount', label: 'Amount', type: 'currency', align: 'right', totalKey: 'amount' },
    { key: 'payment_channel', label: 'Channel' }, { key: 'reg_no', label: 'Reg. No.' },
  ];
  return (
    <div>
      <div className="grid" style={{ gridTemplateColumns: 'repeat(3,1fr)', marginBottom: 16 }}>
        <StatCard icon={<Icons.receipt size={18} />} label="Entries" value={data ? data.count : '—'} />
        <StatCard icon={<Icons.pay size={18} />} label="Taxable Amount" value={PKR(totals.amount || 0)} />
        <StatCard icon={<Icons.chart size={18} />} label="Entities" value="EMC · UM" sub="billing entities" />
      </div>
      <FilterCard>
        <div className="row" style={{ gap: 6 }}>
          {['', 'EMC', 'UM'].map(e => <button key={e || 'all'} className={cls('chip', entity === e && 'chip-on')} onClick={() => setEntity(e)}>{e || 'All Entities'}</button>)}
        </div>
        <SearchBox value={q} onChange={setQ} placeholder="Bill-to, inv #…" w={200} />
        <div className="grow" />
        <ExportButtons rows={rows} cols={cols} totals={totals} name="GST-Register" />
        {window.can('reports', 'create') && <Btn variant="primary" icon={<Icons.plus size={15} />} onClick={() => setAdd(true)}>Add Entry</Btn>}
      </FilterCard>
      <DataTable cols={cols} rows={rows} totals={totals} loading={loading} PKR={PKR} empty="No GST entries." />
      {add && <GstModal branch={branch} onClose={() => setAdd(false)} onSaved={() => { setAdd(false); refetch(); }} />}
    </div>
  );
}

function GstModal({ branch, onClose, onSaved }) {
  const [f, setF] = useState({ entity: 'EMC', inv_no: '', emck_no: '', month: '', bill_to: '', amount: '', payment_channel: '', reg_no: '' });
  const [busy, setBusy] = useState(false);
  const set = k => e => setF(s => ({ ...s, [k]: e.target.value }));
  const save = async () => {
    if (!f.bill_to.trim()) return window.toast('Bill-to is required', 'warn');
    setBusy(true);
    try { await api.createGstEntry({ ...f, amount: Number(f.amount) || 0, branch_id: branch !== 'All' ? branch : undefined }); window.toast('GST entry added', 'ok'); onSaved(); }
    catch (e) { window.toast(e.message, 'error'); setBusy(false); }
  };
  return <Modal title="New GST Entry" onClose={onClose} foot={<><Btn variant="ghost" onClick={onClose}>Cancel</Btn><Btn variant="primary" onClick={save} disabled={busy}>{busy ? 'Saving…' : 'Save'}</Btn></>}>
    <div className="grid" style={{ gridTemplateColumns: '1fr 1fr', gap: 12 }}>
      <label className="fld"><span>Entity</span><select className="input-block" value={f.entity} onChange={set('entity')}><option>EMC</option><option>UM</option></select></label>
      <label className="fld"><span>Month</span><input className="input-block" value={f.month} onChange={set('month')} placeholder="JUN" /></label>
      <label className="fld"><span>Invoice #</span><input className="input-block" value={f.inv_no} onChange={set('inv_no')} /></label>
      <label className="fld"><span>EMCK #</span><input className="input-block" value={f.emck_no} onChange={set('emck_no')} /></label>
      <label className="fld" style={{ gridColumn: '1 / -1' }}><span>Bill To *</span><input className="input-block" value={f.bill_to} onChange={set('bill_to')} /></label>
      <label className="fld"><span>Amount</span><input className="input-block mono" type="number" value={f.amount} onChange={set('amount')} /></label>
      <label className="fld"><span>Payment Channel</span><input className="input-block" value={f.payment_channel} onChange={set('payment_channel')} placeholder="HMBL / Cash" /></label>
      <label className="fld"><span>Reg. No.</span><input className="input-block" value={f.reg_no} onChange={set('reg_no')} /></label>
    </div>
  </Modal>;
}

/* ── Withholding-tax register ─────────────────────────────────── */
function WhtRegister({ branch }) {
  const { PKR } = window.DATA;
  const [pending, setPending] = useState(false);
  const [q, setQ] = useState('');
  const [add, setAdd] = useState(false);
  const bf = () => ({ ...(branch !== 'All' ? { branch_id: branch } : {}), pending: pending ? '1' : undefined, search: q || undefined });
  const { data, loading, refetch } = useFetch(() => api.getWhtRegister(bf()), [branch, pending, q]);
  const rows = (data && data.rows) || [];
  const totals = (data && data.totals) || {};
  const toggle = async (r, field) => { try { await api.updateWhtEntry(r.id, { [field]: r[field] ? 0 : 1 }); refetch(); } catch (e) { window.toast(e.message, 'error'); } };
  const cols = [
    { key: 'institute', label: 'Institute' }, { key: 'doc_no', label: 'DC / Inv #' },
    { key: 'total_bill', label: 'Total Bill', type: 'currency', align: 'right', totalKey: 'total_bill' },
    { key: 'tax_deducted', label: 'Tax Deducted', type: 'currency', align: 'right', totalKey: 'tax_deducted' },
    { key: 'mail_sent', label: 'Mail Sent', render: (r) => <Toggle on={r.mail_sent} onClick={() => toggle(r, 'mail_sent')} /> },
    { key: 'challan_received', label: 'Challan', render: (r) => <Toggle on={r.challan_received} onClick={() => toggle(r, 'challan_received')} /> },
  ];
  return (
    <div>
      <div className="grid" style={{ gridTemplateColumns: 'repeat(3,1fr)', marginBottom: 16 }}>
        <StatCard icon={<Icons.pay size={18} />} label="Tax Withheld" value={PKR(totals.tax_deducted || 0)} sub="to reclaim via challan" accent />
        <StatCard icon={<Icons.receipt size={18} />} label="Total Billed" value={PKR(totals.total_bill || 0)} />
        <StatCard icon={<Icons.clock size={18} />} label="Pending Challans" value={totals.pending_challans || 0} />
      </div>
      <FilterCard>
        <button className={cls('chip', pending && 'chip-on')} onClick={() => setPending(p => !p)}>Pending challans only</button>
        <SearchBox value={q} onChange={setQ} placeholder="Institute, doc #…" w={200} />
        <div className="grow" />
        <ExportButtons rows={rows} cols={cols} totals={totals} name="Withholding-Tax" />
        {window.can('reports', 'create') && <Btn variant="primary" icon={<Icons.plus size={15} />} onClick={() => setAdd(true)}>Add Entry</Btn>}
      </FilterCard>
      <DataTable cols={cols} rows={rows} totals={totals} loading={loading} PKR={PKR} empty="No withholding-tax entries." />
      {add && <WhtModal branch={branch} onClose={() => setAdd(false)} onSaved={() => { setAdd(false); refetch(); }} />}
    </div>
  );
}

function WhtModal({ branch, onClose, onSaved }) {
  const [f, setF] = useState({ institute: '', doc_no: '', total_bill: '', tax_deducted: '' });
  const [busy, setBusy] = useState(false);
  const set = k => e => setF(s => ({ ...s, [k]: e.target.value }));
  const save = async () => {
    if (!f.institute.trim()) return window.toast('Institute is required', 'warn');
    setBusy(true);
    try { await api.createWhtEntry({ ...f, total_bill: Number(f.total_bill) || 0, tax_deducted: Number(f.tax_deducted) || 0, branch_id: branch !== 'All' ? branch : undefined }); window.toast('WHT entry added', 'ok'); onSaved(); }
    catch (e) { window.toast(e.message, 'error'); setBusy(false); }
  };
  return <Modal title="New Withholding-Tax Entry" onClose={onClose} foot={<><Btn variant="ghost" onClick={onClose}>Cancel</Btn><Btn variant="primary" onClick={save} disabled={busy}>{busy ? 'Saving…' : 'Save'}</Btn></>}>
    <div className="grid" style={{ gridTemplateColumns: '1fr 1fr', gap: 12 }}>
      <label className="fld" style={{ gridColumn: '1 / -1' }}><span>Institute *</span><input className="input-block" value={f.institute} onChange={set('institute')} placeholder="e.g. LNH" /></label>
      <label className="fld"><span>DC / Inv #</span><input className="input-block" value={f.doc_no} onChange={set('doc_no')} /></label>
      <label className="fld"><span>Total Bill</span><input className="input-block mono" type="number" value={f.total_bill} onChange={set('total_bill')} /></label>
      <label className="fld"><span>Tax Deducted</span><input className="input-block mono" type="number" value={f.tax_deducted} onChange={set('tax_deducted')} /></label>
    </div>
  </Modal>;
}

/* ── Bank reconciliation ──────────────────────────────────────── */
function BankRecon({ branch }) {
  const { PKR } = window.DATA;
  const [bankCode, setBankCode] = useState('');
  const [status, setStatus] = useState('');
  const [q, setQ] = useState('');
  const { data: acctData } = useFetch(() => api.getBankAccounts(), []);
  const accounts = (acctData && acctData.accounts) || [];
  const bf = () => ({ ...(branch !== 'All' ? { branch_id: branch } : {}), bank_code: bankCode || undefined, reconciled: status || undefined, search: q || undefined });
  const { data, loading, refetch } = useFetch(() => api.getBankTxns(bf()), [branch, bankCode, status, q]);
  const rows = (data && data.rows) || [];
  const totals = (data && data.totals) || {};
  const flip = async (r) => { try { await api.reconcileBankTxn(r.id, { reconciled: r.reconciled ? 0 : 1 }); refetch(); } catch (e) { window.toast(e.message, 'error'); } };
  const cols = [
    { key: 'date', label: 'Date', type: 'date' }, { key: 'bank_code', label: 'Bank' },
    { key: 'type', label: 'Type' }, { key: 'client_name', label: 'Client' }, { key: 'inv_no', label: 'Inv #' },
    { key: 'amount', label: 'Amount', type: 'currency', align: 'right', totalKey: 'amount' },
    { key: 'reconciled', label: 'Reconciled', render: (r) => <Toggle on={r.reconciled} onClick={() => flip(r)} /> },
  ];
  return (
    <div>
      <div className="grid" style={{ gridTemplateColumns: 'repeat(3,1fr)', marginBottom: 16 }}>
        <StatCard icon={<Icons.pay size={18} />} label="Total In" value={PKR(totals.amount || 0)} sub={`${data ? data.count : 0} transactions`} />
        <StatCard icon={<Icons.check size={18} />} label="Reconciled" value={PKR(totals.reconciled || 0)} />
        <StatCard icon={<Icons.clock size={18} />} label="Unreconciled" value={PKR(totals.unreconciled || 0)} accent />
      </div>
      <FilterCard>
        <select className="input-block" style={{ width: 'auto' }} value={bankCode} onChange={e => setBankCode(e.target.value)}>
          <option value="">All Banks</option>
          {accounts.map(a => <option key={a.code} value={a.code}>{a.code} · {a.name}</option>)}
        </select>
        <select className="input-block" style={{ width: 'auto' }} value={status} onChange={e => setStatus(e.target.value)}>
          <option value="">All</option><option value="1">Reconciled</option><option value="0">Unreconciled</option>
        </select>
        <SearchBox value={q} onChange={setQ} placeholder="Client, inv #…" w={180} />
        <div className="grow" />
        <ExportButtons rows={rows} cols={cols} totals={totals} name="Bank-Reconciliation" />
      </FilterCard>
      <DataTable cols={cols} rows={rows} totals={totals} loading={loading} PKR={PKR} empty="No bank transactions." />
    </div>
  );
}

/* ── Shared bits ──────────────────────────────────────────────── */
function FilterCard({ children }) {
  return <div className="card card-pad no-print row" style={{ gap: 10, flexWrap: 'wrap', alignItems: 'center', marginBottom: 14 }}>{children}</div>;
}
function Toggle({ on, onClick }) {
  return <button onClick={onClick} className={cls('chip', on && 'chip-on')} style={{ padding: '3px 10px' }}>{on ? '✓ Yes' : 'No'}</button>;
}
function ExportButtons({ rows, cols, totals, name }) {
  const totalsRow = () => { const t = {}; cols.forEach(c => { if (c.totalKey) t[c.key] = totals[c.totalKey]; }); return Object.keys(t).length ? t : null; };
  const exp = (kind) => {
    const payload = { rows, columns: cols.filter(c => !c.render), totals: totalsRow(), reportName: name, from: '', to: '' };
    if (kind === 'xlsx') window.ExportKit.toXLSX(payload); else window.ExportKit.toCSV(payload);
    window.toast && window.toast(name + ' exported', 'ok');
  };
  return <><Btn variant="ghost" icon={<Icons.download size={14} />} onClick={() => exp('csv')} disabled={!rows.length}>CSV</Btn>
    <Btn variant="ghost" icon={<Icons.download size={14} />} onClick={() => exp('xlsx')} disabled={!rows.length}>Excel</Btn></>;
}
function DataTable({ cols, rows, totals, loading, PKR, empty }) {
  const fmt = (r, c) => {
    if (c.render) return c.render(r);
    const v = r[c.key];
    if (v === null || v === undefined || v === '') return c.type === 'currency' ? '—' : '';
    return c.type === 'currency' ? PKR(v) : String(v);
  };
  return (
    <div className="card" style={{ overflow: 'hidden' }}>
      <div style={{ overflowX: 'auto' }}>
        <table className="tbl" style={{ fontSize: 13 }}>
          <thead><tr>{cols.map(c => <th key={c.key} style={{ textAlign: c.align || 'left', whiteSpace: 'nowrap' }}>{c.label}</th>)}</tr></thead>
          <tbody>
            {loading && !rows.length ? <tr><td colSpan={cols.length} className="muted tiny" style={{ padding: 20, textAlign: 'center' }}>Loading…</td></tr>
              : !rows.length ? <tr><td colSpan={cols.length} className="muted tiny" style={{ padding: 20, textAlign: 'center' }}>{empty}</td></tr>
              : rows.slice(0, 500).map((r, i) => <tr key={i}>{cols.map(c => <td key={c.key} className={c.type === 'currency' ? 'mono' : ''} style={{ textAlign: c.align || 'left' }}>{fmt(r, c)}</td>)}</tr>)}
          </tbody>
          {totals && rows.length > 0 && (
            <tfoot><tr style={{ borderTop: '2px solid var(--ink)', fontWeight: 800 }}>
              {cols.map((c, i) => <td key={c.key} className={c.type === 'currency' ? 'mono' : ''} style={{ textAlign: c.align || 'left' }}>{i === 0 ? 'TOTAL' : (c.totalKey && totals[c.totalKey] !== undefined ? PKR(totals[c.totalKey]) : '')}</td>)}
            </tr></tfoot>
          )}
        </table>
      </div>
      {rows.length > 500 && <div className="tiny muted" style={{ padding: 10, textAlign: 'center' }}>Showing first 500 of {rows.length} — refine filters or export for the full set.</div>}
    </div>
  );
}

window.Finance = Finance;
