// Reconciliation page — proves the three statements articulate per month.
//
// Four checks per month:
//   1. Ending Cash (CFS) == Cash & equivalents (BS) at period end
//   2. Net Income (IS) == top line of CFS Operating
//   3. Retained Earnings roll-forward: RE_{m-1} + NI_m − distributions_m = RE_m
//   4. Assets == Liabilities + Equity (BS balances)
//
// Plus a transparent NI → ΔCash bridge.

const { useState: useRec_useState, useEffect: useRec_useEffect, useMemo: useRec_useMemo } = React;

function useRec_companyId(scopedCompanyId) {
  const [cid, setCid] = useRec_useState(scopedCompanyId || null);
  useRec_useEffect(() => {
    if (scopedCompanyId) { setCid(scopedCompanyId); return; }
    const db = window.supabaseClient;
    if (!db) return;
    (async () => {
      const { data: { session } } = await db.auth.getSession();
      if (!session) return;
      const { data: m } = await db.from('company_users').select('company_id')
        .eq('user_id', session.user.id).in('status', ['Active','Pending']).maybeSingle();
      if (m?.company_id) setCid(m.company_id);
    })();
  }, [scopedCompanyId]);
  return cid;
}

async function rec_fetchInputs(db, companyId) {
  const PAGE = 1000;
  let txns = [], from = 0;
  for (let i = 0; i < 80; i++) {
    const { data, error } = await db.from('gl_transactions')
      .select('id, posted_date, account_code, account_name, amount')
      .eq('company_id', companyId)
      .order('posted_date', { ascending: true })
      .range(from, from + PAGE - 1);
    if (error || !data || data.length === 0) break;
    txns = txns.concat(data);
    if (data.length < PAGE) break;
    from += PAGE;
  }
  const [mappings, accountMaster] = await Promise.all([
    db.from('account_mappings').select('account_code, canonical_category, subcategory').eq('company_id', companyId).range(0, 1999).then(r => r.data || []),
    db.from('account_master').select('account_no, account_name, account_type, statement, normal_balance').eq('company_id', companyId).range(0, 1999).then(r => r.data || []),
  ]);
  return { txns, mappings, accountMaster };
}

function fmtMoney(v) {
  const F = window.PerduraFmt || { fmtUSD: (n) => '$' + Math.round(n).toLocaleString() };
  return F.fmtUSD(v, { compact: true });
}
function fmtVar(v) {
  if (Math.abs(v) < 0.005) return '$0';
  return (v < 0 ? '−' : '') + fmtMoney(Math.abs(v)).replace('-', '');
}

const TOLS = [
  { value: 0,    label: 'Exact ($0)' },
  { value: 1,    label: '±$1' },
  { value: 10,   label: '±$10' },
  { value: 100,  label: '±$100' },
];

function CheckCell({ variance, tol }) {
  const pass = Math.abs(variance) <= tol;
  return (
    <td style={{ textAlign: 'center', padding: '6px 8px' }}>
      <span style={{
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
        width: 18, height: 18, borderRadius: 4,
        background: pass ? 'rgba(110,231,183,0.18)' : 'rgba(248,113,113,0.18)',
        color: pass ? 'var(--positive)' : 'var(--danger)', fontSize: 11, fontWeight: 700,
      }} title={'variance ' + fmtVar(variance)}>{pass ? '✓' : '✗'}</span>
    </td>
  );
}

function VarCell({ variance, tol }) {
  const pass = Math.abs(variance) <= tol;
  return (
    <td style={{ textAlign: 'right', padding: '6px 12px', fontFamily: 'ui-monospace, monospace', fontSize: 11.5,
                color: pass ? 'var(--text-3)' : 'var(--danger)' }}>
      {Math.abs(variance) < 0.005 ? '—' : fmtVar(variance)}
    </td>
  );
}

function ReconciliationPage({ scopedCompanyId, periodResolved, companyProfile, setPage }) {
  const companyId = useRec_companyId(scopedCompanyId);
  const [loading, setLoading] = useRec_useState(true);
  const [error, setError]     = useRec_useState(null);
  const [raw, setRaw]         = useRec_useState(null);
  const [tol, setTol]         = useRec_useState(1);
  const [tab, setTab]         = useRec_useState('checks'); // 'checks' | 'bridge'

  useRec_useEffect(() => {
    if (!companyId) { setLoading(false); return; }
    const db = window.supabaseClient;
    if (!db) { setLoading(false); return; }
    let cancelled = false;
    setLoading(true); setError(null);
    rec_fetchInputs(db, companyId)
      .then(d => { if (!cancelled) { setRaw(d); setLoading(false); } })
      .catch(e => { if (!cancelled) { setError(String(e?.message || e)); setLoading(false); } });
    return () => { cancelled = true; };
  }, [companyId]);

  const engine    = window.PerduraCashFlow;
  const monthCols = periodResolved?.months || [];

  const cf = useRec_useMemo(() => {
    if (!engine || !raw) return null;
    return engine.compute({
      txns: raw.txns, mappings: raw.mappings, accountMaster: raw.accountMaster,
      monthCols, profile: companyProfile,
      fiscalYearStartMonth: companyProfile?.fiscal_year_start_month || 1,
    });
  }, [engine, raw, monthCols.map(m => m.year + '-' + m.month1).join(','), companyProfile?.fiscal_year_start_month]);

  if (!engine) return <div className="pc-page"><Card><div style={{ padding: 24 }}>Cash-flow engine not loaded.</div></Card></div>;
  if (!companyId) return <div className="pc-page"><Card><div style={{ padding: 24, color: 'var(--text-3)' }}>Resolving company…</div></Card></div>;
  if (loading) return <div className="pc-page"><Card><div style={{ padding: 24, color: 'var(--text-3)' }}>Loading transactions…</div></Card></div>;
  if (error) return <div className="pc-page"><Card><div style={{ padding: 24, color: 'var(--danger)' }}>Error: {error}</div></Card></div>;
  if (!cf || !monthCols.length) return <div className="pc-page"><Card><div style={{ padding: 24 }}>No period selected.</div></Card></div>;

  // Summary stats
  const failing = cf.reconciliation.filter(r =>
    Math.abs(r.cashCheck.variance) > tol || Math.abs(r.reCheck.variance) > tol || Math.abs(r.aleCheck.variance) > tol);
  const totalChecks = cf.reconciliation.length * 4;
  const failedChecks = cf.reconciliation.reduce((s, r) => s
    + (Math.abs(r.cashCheck.variance) > tol ? 1 : 0)
    + (Math.abs(r.niCheck.variance)   > tol ? 1 : 0)
    + (Math.abs(r.reCheck.variance)   > tol ? 1 : 0)
    + (Math.abs(r.aleCheck.variance)  > tol ? 1 : 0), 0);

  const cols = monthCols.length + 2;
  const tot = (row) => row.reduce((a, b) => a + b, 0);

  return (
    <div className="pc-page">
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, flexWrap: 'wrap' }}>
        <div>
          <div style={{ fontSize: 11, color: 'var(--text-3)', textTransform: 'uppercase', letterSpacing: 0.5 }}>Finance</div>
          <h2 style={{ margin: '2px 0 0', fontSize: 22, fontWeight: 600, letterSpacing: -0.3 }}>Reconciliation</h2>
          <div style={{ fontSize: 13, color: 'var(--text-2)', marginTop: 6 }}>
            Proves the three statements articulate, by month. {failedChecks === 0
              ? <span style={{ color: 'var(--positive)' }}>All {totalChecks} checks pass within {fmtMoney(tol)}.</span>
              : <span style={{ color: 'var(--danger)' }}>{failedChecks} of {totalChecks} checks fail at tolerance {fmtMoney(tol)}.</span>}
          </div>
        </div>
        <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
          <label style={{ fontSize: 11, color: 'var(--text-3)' }}>Tolerance</label>
          <select className="pc-period-select" value={tol} onChange={e => setTol(Number(e.target.value))}>
            {TOLS.map(t => <option key={t.value} value={t.value}>{t.label}</option>)}
          </select>
        </div>
      </div>

      <div className="pc-section-tabs" style={{ marginTop: 14 }}>
        <button className={tab === 'checks' ? 'active' : ''} onClick={() => setTab('checks')}>Per-month checks</button>
        <button className={tab === 'bridge' ? 'active' : ''} onClick={() => setTab('bridge')}>NI → ΔCash bridge</button>
      </div>

      {tab === 'checks' && (
        <Card padding={0} style={{ marginTop: 10 }}>
          <div style={{ overflowX: 'auto' }}>
            <table className="pc-table" style={{ fontSize: 11.5, minWidth: 1000 }}>
              <thead>
                <tr>
                  <th style={{ padding: '10px 14px', textAlign: 'left' }}>Month</th>
                  <th colSpan={3} style={{ padding: '10px 12px', textAlign: 'center', borderLeft: '1px solid var(--border)' }}>1. Cash CFS = BS</th>
                  <th colSpan={2} style={{ padding: '10px 12px', textAlign: 'center', borderLeft: '1px solid var(--border)' }}>2. NI = CF op</th>
                  <th colSpan={3} style={{ padding: '10px 12px', textAlign: 'center', borderLeft: '1px solid var(--border)' }}>3. RE roll-forward</th>
                  <th colSpan={3} style={{ padding: '10px 12px', textAlign: 'center', borderLeft: '1px solid var(--border)' }}>4. A = L + E</th>
                </tr>
                <tr style={{ fontSize: 10, color: 'var(--text-3)', textTransform: 'uppercase', letterSpacing: 0.4 }}>
                  <th></th>
                  <th style={{ borderLeft: '1px solid var(--border)' }}>CF end</th><th>BS cash</th><th>Δ</th>
                  <th style={{ borderLeft: '1px solid var(--border)' }}>NI</th><th>✓</th>
                  <th style={{ borderLeft: '1px solid var(--border)' }}>RE roll</th><th>BS RE</th><th>Δ</th>
                  <th style={{ borderLeft: '1px solid var(--border)' }}>Assets</th><th>L + E</th><th>Δ</th>
                </tr>
              </thead>
              <tbody>
                {cf.reconciliation.map((r) => (
                  <tr key={r.year + '-' + r.month1}
                      style={{ background: (Math.abs(r.cashCheck.variance) > tol || Math.abs(r.reCheck.variance) > tol || Math.abs(r.aleCheck.variance) > tol) ? 'rgba(248,113,113,0.04)' : 'transparent' }}>
                    <td style={{ paddingLeft: 14, fontFamily: 'ui-monospace, monospace', fontSize: 11 }}>{r.label}</td>
                    {/* check 1 */}
                    <td style={{ textAlign: 'right', borderLeft: '1px solid var(--border)', fontFamily: 'ui-monospace, monospace', fontSize: 11 }}>{fmtMoney(r.cfEndCash)}</td>
                    <td style={{ textAlign: 'right', fontFamily: 'ui-monospace, monospace', fontSize: 11 }}>{fmtMoney(r.endingCash)}</td>
                    <VarCell variance={r.cashCheck.variance} tol={tol} />
                    {/* check 2 */}
                    <td style={{ textAlign: 'right', borderLeft: '1px solid var(--border)', fontFamily: 'ui-monospace, monospace', fontSize: 11 }}>{fmtMoney(r.ni)}</td>
                    <CheckCell variance={r.niCheck.variance} tol={tol} />
                    {/* check 3 */}
                    <td style={{ textAlign: 'right', borderLeft: '1px solid var(--border)', fontFamily: 'ui-monospace, monospace', fontSize: 11 }}
                        title={`Beg RE ${fmtMoney(r.reCheck.beg)} + NI ${fmtMoney(r.reCheck.ni)} − Dist ${fmtMoney(r.reCheck.dist)}`}>
                      {fmtMoney(r.reCheck.actual)}
                    </td>
                    <td style={{ textAlign: 'right', fontFamily: 'ui-monospace, monospace', fontSize: 11 }}>{fmtMoney(r.reCheck.end)}</td>
                    <VarCell variance={r.reCheck.variance} tol={tol} />
                    {/* check 4 */}
                    <td style={{ textAlign: 'right', borderLeft: '1px solid var(--border)', fontFamily: 'ui-monospace, monospace', fontSize: 11 }}>{fmtMoney(r.aleCheck.assets)}</td>
                    <td style={{ textAlign: 'right', fontFamily: 'ui-monospace, monospace', fontSize: 11 }}>{fmtMoney(r.aleCheck.expected)}</td>
                    <VarCell variance={r.aleCheck.variance} tol={tol} />
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </Card>
      )}

      {tab === 'bridge' && (
        <Card padding={0} style={{ marginTop: 10 }}>
          <div style={{ padding: '10px 14px', fontSize: 11, color: 'var(--text-3)', borderBottom: '1px solid var(--border)' }}>
            How the balance-sheet movements produce the cash flow. Every line is the cash effect of one BS-account change category.
          </div>
          <div style={{ overflowX: 'auto' }}>
            <table className="pc-table" style={{ fontSize: 11.5, minWidth: 320 + monthCols.length * 100 + 100 }}>
              <thead>
                <tr>
                  <th style={{ padding: '10px 14px', textAlign: 'left' }}>&nbsp;</th>
                  {monthCols.map(m => {
                    const MS = (window.PerduraCashFlow && window.PerduraCashFlow.MONTH_SHORT) || ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
                    return <th key={m.year + '-' + m.month1} style={{ padding: '10px 12px', textAlign: 'right', fontFamily: 'ui-monospace, monospace', fontSize: 11 }}>{MS[m.month1 - 1]} {m.year}</th>;
                  })}
                  <th style={{ padding: '10px 12px', textAlign: 'right', fontWeight: 700 }}>Total</th>
                </tr>
              </thead>
              <tbody>
                {[
                  ['Net income',                     cf.operating.netIncome],
                  ['+ D&A (non-cash)',               cf.operating.depreciation],
                  ['− Δ AR',                         cf.operating.deltaAR],
                  ['− Δ Inventory',                  cf.operating.deltaInventory],
                  ['+ Δ AP',                         cf.operating.deltaAP],
                  ['+ Δ Accruals',                   cf.operating.deltaAccrued],
                  ['± Δ other current assets',       cf.operating.deltaOtherCA],
                  ['± Δ other current liabilities',  cf.operating.deltaOtherCL],
                  ['Capex / investing',              cf.investing.capex.map((v,i) => v + cf.investing.other[i])],
                  ['Debt — net',                     cf.financing.debt],
                  ['Equity contributions',           cf.financing.equityContrib],
                  ['Distributions',                  cf.financing.distributions],
                ].map(([label, vals]) => (
                  <tr key={label}>
                    <td style={{ paddingLeft: 14, fontSize: 12, color: 'var(--text-2)' }}>{label}</td>
                    {vals.map((v, i) => (
                      <td key={i} style={{ textAlign: 'right', padding: '6px 12px', fontFamily: 'ui-monospace, monospace', fontSize: 11.5,
                                            color: v === 0 ? 'var(--text-4)' : (v < 0 ? 'var(--danger)' : 'var(--text-1)') }}>
                        {Math.abs(v) < 0.5 ? '—' : (v < 0 ? '(' + fmtMoney(Math.abs(v)) + ')' : fmtMoney(v))}
                      </td>
                    ))}
                    <td style={{ textAlign: 'right', padding: '6px 12px', fontFamily: 'ui-monospace, monospace', fontSize: 11.5, fontWeight: 600 }}>
                      {(() => { const t = tot(vals); return Math.abs(t) < 0.5 ? '—' : (t < 0 ? '(' + fmtMoney(Math.abs(t)) + ')' : fmtMoney(t)); })()}
                    </td>
                  </tr>
                ))}
                <tr style={{ borderTop: '1px solid var(--border)', background: 'rgba(96,165,250,0.08)' }}>
                  <td style={{ paddingLeft: 14, fontWeight: 700 }}>= Net change in cash</td>
                  {cf.netChange.map((v, i) => (
                    <td key={i} style={{ textAlign: 'right', padding: '6px 12px', fontFamily: 'ui-monospace, monospace', fontSize: 11.5, fontWeight: 700 }}>
                      {Math.abs(v) < 0.5 ? '—' : (v < 0 ? '(' + fmtMoney(Math.abs(v)) + ')' : fmtMoney(v))}
                    </td>
                  ))}
                  <td style={{ textAlign: 'right', padding: '6px 12px', fontFamily: 'ui-monospace, monospace', fontSize: 11.5, fontWeight: 700 }}>
                    {(() => { const t = tot(cf.netChange); return Math.abs(t) < 0.5 ? '—' : (t < 0 ? '(' + fmtMoney(Math.abs(t)) + ')' : fmtMoney(t)); })()}
                  </td>
                </tr>
                <tr style={{ color: 'var(--text-3)' }}>
                  <td style={{ paddingLeft: 14, fontSize: 11 }}>Actual ΔBS cash (validator)</td>
                  {cf.bsEndingCash.map((v, i) => {
                    const delta = i === 0 ? v - cf.beginningCash[0] : v - cf.bsEndingCash[i - 1];
                    return (
                      <td key={i} style={{ textAlign: 'right', padding: '6px 12px', fontFamily: 'ui-monospace, monospace', fontSize: 11 }}>
                        {Math.abs(delta) < 0.5 ? '—' : (delta < 0 ? '(' + fmtMoney(Math.abs(delta)) + ')' : fmtMoney(delta))}
                      </td>
                    );
                  })}
                  <td style={{ textAlign: 'right', padding: '6px 12px', fontFamily: 'ui-monospace, monospace', fontSize: 11 }}>
                    {(() => { const t = cf.bsEndingCash[cf.bsEndingCash.length - 1] - cf.beginningCash[0]; return Math.abs(t) < 0.5 ? '—' : (t < 0 ? '(' + fmtMoney(Math.abs(t)) + ')' : fmtMoney(t)); })()}
                  </td>
                </tr>
                {cf.unreconciledLine.some(v => Math.abs(v) >= 1) && (
                  <tr style={{ background: 'rgba(248,113,113,0.06)' }}>
                    <td style={{ paddingLeft: 14, color: 'var(--danger)' }}>Unreconciled (bridge − actual)</td>
                    {cf.unreconciledLine.map((v, i) => (
                      <td key={i} style={{ textAlign: 'right', padding: '6px 12px', fontFamily: 'ui-monospace, monospace', fontSize: 11.5, color: 'var(--danger)' }}>
                        {Math.abs(v) < 0.5 ? '—' : (v < 0 ? '(' + fmtMoney(Math.abs(v)) + ')' : fmtMoney(v))}
                      </td>
                    ))}
                    <td style={{ textAlign: 'right', padding: '6px 12px', fontFamily: 'ui-monospace, monospace', fontSize: 11.5, color: 'var(--danger)' }}>
                      {(() => { const t = tot(cf.unreconciledLine); return Math.abs(t) < 0.5 ? '—' : (t < 0 ? '(' + fmtMoney(Math.abs(t)) + ')' : fmtMoney(t)); })()}
                    </td>
                  </tr>
                )}
              </tbody>
            </table>
          </div>
        </Card>
      )}

      {failing.length > 0 && (
        <Card padding={0} style={{ marginTop: 12, borderLeft: '3px solid var(--danger)' }}>
          <div style={{ padding: '10px 14px', fontSize: 11, color: 'var(--danger)', textTransform: 'uppercase', letterSpacing: 0.5, borderBottom: '1px solid var(--border)' }}>
            {failing.length} month{failing.length === 1 ? '' : 's'} with variances above tolerance
          </div>
          <div style={{ padding: '10px 14px', fontSize: 12, color: 'var(--text-2)', lineHeight: 1.6 }}>
            {failing.slice(0, 12).map(r => (
              <div key={r.year + '-' + r.month1}>
                <b>{r.label}</b>: cash Δ {fmtVar(r.cashCheck.variance)} · RE Δ {fmtVar(r.reCheck.variance)} · A−(L+E) {fmtVar(r.aleCheck.variance)}
              </div>
            ))}
            {failing.length > 12 && <div style={{ marginTop: 6, color: 'var(--text-3)' }}>… and {failing.length - 12} more.</div>}
          </div>
        </Card>
      )}
    </div>
  );
}

Object.assign(window, { ReconciliationPage });
