// financial/src/debt.jsx — the Debt tab (M6).
//
// Every liability in one table with rate, balance, minimum, payoff date
// and remaining interest (lib/debtPlan over the Monarch accounts and the
// per-account rates in debt/config), the avalanche / snowball / invest-
// instead comparison on the household's own marginal rate and the
// planner's return assumption, and the credit-card float detector — which
// says, in words, that $358 of interest on $50,089 of balances is float,
// not a fire.
//
// Slices run in their own Babel scope; src/shared.jsx runs first and
// publishes window.FinanceShared.

const { useState, useContext, useMemo } = React;
const { DataContext, useToast, fmtCur, fmtDate, timeAgo } = window.FinanceShared;

const Tag = window.FinanceShared.ProvenanceTag;

function Debt({ setTab }) {
  const d = useContext(DataContext);
  const { show, Toast } = useToast();
  const DP = window.DebtPlan, ST = window.SpendingTaxonomy;
  const [extra, setExtra] = useState(1000);
  const [draft, setDraft] = useState({});
  const cfg = d.retirementConfig || {};
  const outSign = d.spendingTaxonomy?.outSign ?? (ST && d.transactions.length ? ST.detectOutSign(d.transactions).outSign : -1);
  const L = useMemo(() => DP ? DP.liabilities({ accounts: d.accounts, debtConfig: d.debtConfig, transactions: d.transactions, outSign }) : null, [DP, d.accounts, d.debtConfig, d.transactions, outSign]);
  // The household's marginal rate off the same bracket rule the Retirement tab uses.
  // The household's marginal rate: the one lookup every tab shares.
  const marginal = useMemo(() => window.MarginalRateCurve ? window.MarginalRateCurve.householdMarginal({ cfg, year: new Date().getFullYear() }).totalPct : 30.6, [cfg]);
  const ret = (() => { const Sens = window.Sensitivity; const patch = Sens ? Sens.presetPatch(cfg.headlinePreset || 'base', cfg) : {}; return patch.expectedReturn != null ? patch.expectedReturn : (cfg.expectedReturn || 7); })();
  const S = useMemo(() => DP && L ? DP.strategies({ liabilities: L, extraMonthly: extra, marginalRatePct: marginal, returnPct: ret }) : null, [DP, L, extra, marginal, ret]);
  if (!DP || !L) return <div className="page"><div className="card">Debt module not loaded.</div></div>;
  const save = async (id) => {
    const cur = ((d.debtConfig && d.debtConfig.accounts) || {})[id] || {};
    const dr = draft[id] || {};
    const next = { ...cur, ...(dr.ratePct !== undefined ? { ratePct: dr.ratePct === '' ? null : Number(dr.ratePct) } : {}), ...(dr.minimumPayment !== undefined ? { minimumPayment: dr.minimumPayment === '' ? null : Number(dr.minimumPayment) } : {}), ...(dr.note !== undefined ? { note: dr.note } : {}), updatedAt: new Date().toISOString() };
    try { await d.saveDebtConfig({ accounts: { ...((d.debtConfig && d.debtConfig.accounts) || {}), [id]: next } }); setDraft(x => { const y = { ...x }; delete y[id]; return y; }); show('Saved'); } catch (e) { show(e.message, 'error'); }
  };
  const lastSync = d.monarchAuth && d.monarchAuth.lastSync;
  const cardColor = L.cards.float ? '#10b981' : '#f59e0b';
  return (
    <div className="page">
      {Toast}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', gap: 12, flexWrap: 'wrap', marginBottom: 12 }}>
        <div className="page-title" style={{ marginBottom: 0 }}>Debt</div>
        <div style={{ fontSize: 10, color: '#475569' }}>Balances from Monarch (synced {lastSync ? timeAgo(lastSync) : 'never'}); rates and minimums from debt/config (typed once); interest from the ledger's own rows.</div>
      </div>

      {/* ANSWER */}
      <div className="card" style={{ marginBottom: 16, borderColor: `${cardColor}66` }}>
        <div style={{ display: 'flex', gap: 20, flexWrap: 'wrap', alignItems: 'center' }}>
          <div style={{ textAlign: 'center', minWidth: 120 }}>
            <div style={{ fontSize: 34, fontWeight: 900, color: '#e2e8f0', lineHeight: 1 }}>{fmtCur(L.total)}</div>
            <div style={{ fontSize: 9, color: '#64748b', letterSpacing: '0.1em', textTransform: 'uppercase', marginTop: 4 }}>total liabilities</div>
            <div style={{ marginTop: 4 }}><Tag kind="data">accounts</Tag></div>
          </div>
          <div style={{ flex: 1, minWidth: 260, fontSize: 13, color: '#e2e8f0', lineHeight: 1.5 }}>
            <div><strong style={{ color: cardColor }}>Cards: {L.cards.verdict}.</strong></div>
            <div style={{ fontSize: 11, color: '#94a3b8', marginTop: 4 }}>
              {fmtCur(L.cards.balance)} of card balances paid {fmtCur(L.cards.interestPaid12)} of interest in the trailing 12 months ({L.cards.effectiveApr == null ? '—' : `${L.cards.effectiveApr}%`} effective; float is under {L.cards.thresholdPct}%). Remaining interest on the priced loans at their minimums: <strong style={{ color: '#e2e8f0' }}>{fmtCur(L.remainingInterest)}</strong>.
              {L.unknownRates.length > 0 && <span style={{ color: '#f59e0b' }}> {L.unknownRates.length} account{L.unknownRates.length === 1 ? '' : 's'} with no rate recorded ({L.unknownRates.join(', ')}) — type them below; nothing is guessed.</span>}
            </div>
            <div style={{ fontSize: 10, color: '#475569', marginTop: 4 }}>{S ? S.verdict : ''}</div>
          </div>
        </div>
      </div>

      {/* The table */}
      <div className="card" style={{ marginBottom: 16 }}>
        <div className="label" style={{ marginBottom: 6 }}>Every liability <Tag kind="data">accounts · debt/config · transactions</Tag></div>
        <table style={{ fontSize: 11 }}>
          <thead><tr><th>Account</th><th>Kind</th><th style={{ textAlign: 'right' }}>Balance</th><th style={{ textAlign: 'right' }}>Rate %</th><th style={{ textAlign: 'right' }}>Minimum /mo</th><th>Payoff</th><th style={{ textAlign: 'right' }}>Remaining interest</th><th style={{ textAlign: 'right' }}>Interest paid (12 mo)</th><th>Note</th><th></th></tr></thead>
          <tbody>{L.rows.map(r => {
            const dr = draft[r.id] || {};
            return (
              <tr key={r.id}>
                <td style={{ padding: '4px 8px', color: '#e2e8f0' }}>{r.name}</td>
                <td style={{ padding: '4px 8px', color: '#94a3b8' }}>{r.kindLabel}{r.float && <span style={{ fontSize: 9, color: '#10b981', marginLeft: 6 }}>float</span>}</td>
                <td style={{ padding: '4px 8px', textAlign: 'right', color: '#e2e8f0' }}>{fmtCur(r.balance)}</td>
                <td style={{ padding: '4px 8px', textAlign: 'right' }}><input type="number" step="0.01" value={dr.ratePct !== undefined ? dr.ratePct : (r.ratePct ?? '')} placeholder="—" style={{ width: 70, textAlign: 'right', fontSize: 11, padding: '2px 6px', borderColor: r.ratePct == null ? '#f59e0b' : undefined }} onChange={e => setDraft(x => ({ ...x, [r.id]: { ...(x[r.id] || {}), ratePct: e.target.value } }))} /></td>
                <td style={{ padding: '4px 8px', textAlign: 'right' }}><input type="number" value={dr.minimumPayment !== undefined ? dr.minimumPayment : (r.minimum ?? '')} placeholder="—" style={{ width: 90, textAlign: 'right', fontSize: 11, padding: '2px 6px' }} onChange={e => setDraft(x => ({ ...x, [r.id]: { ...(x[r.id] || {}), minimumPayment: e.target.value } }))} /></td>
                <td style={{ padding: '4px 8px', color: '#94a3b8', fontSize: 10 }}>{r.neverPays ? <span style={{ color: '#ef4444' }}>never at this minimum</span> : r.payoffDate ? <>{r.payoffDate.slice(0, 7)} <span style={{ color: '#475569' }}>({r.monthsToPayoff} mo, {r.payoffSource})</span></> : '—'}</td>
                <td style={{ padding: '4px 8px', textAlign: 'right', color: '#94a3b8' }}>{r.remainingInterest == null ? '—' : fmtCur(r.remainingInterest)}</td>
                <td style={{ padding: '4px 8px', textAlign: 'right', color: r.kind === 'creditCard' ? (r.float ? '#10b981' : '#f59e0b') : '#94a3b8' }} title={r.verdict || ''}>{fmtCur(r.interestPaid12)}{r.effectiveApr != null && r.kind === 'creditCard' ? <span style={{ fontSize: 9, color: '#475569' }}> ({r.effectiveApr}%)</span> : null}</td>
                <td style={{ padding: '4px 8px' }}><input value={dr.note !== undefined ? dr.note : (r.note || '')} placeholder="note" style={{ width: 120, fontSize: 11, padding: '2px 6px' }} onChange={e => setDraft(x => ({ ...x, [r.id]: { ...(x[r.id] || {}), note: e.target.value } }))} /></td>
                <td style={{ padding: '4px 8px' }}>{draft[r.id] && <button className="btn-primary" style={{ fontSize: 10, padding: '2px 8px' }} onClick={() => save(r.id)}>Save</button>}</td>
              </tr>);
          })}</tbody>
        </table>
        {L.rows.length === 0 && <div style={{ fontSize: 11, color: '#64748b' }}>No liabilities in the synced accounts.</div>}
        <div style={{ marginTop: 6, display: 'flex', gap: 6 }}>
          <window.FinanceShared.ExportCsv name="liabilities" rows={L.rows.map(r => ({ account: r.name, kind: r.kindLabel, balance: r.balance, ratePct: r.ratePct, minimum: r.minimum, payoffDate: r.payoffDate, monthsToPayoff: r.monthsToPayoff, remainingInterest: r.remainingInterest, interestPaid12: r.interestPaid12, effectiveApr: r.effectiveApr, float: r.float, verdict: r.verdict || '' }))} />
          {S && <window.FinanceShared.ExportCsv name="debt-strategies" label="Export strategies CSV" rows={[['avalanche', S.avalanche], ['snowball', S.snowball], ['minimumsOnly', S.minimumsOnly]].map(([k, r]) => ({ strategy: k, months: r.months, interest: r.interest, interestSaved: r.interestSaved == null ? '' : r.interestSaved, order: (r.order || []).join(' → '), extraMonthly: S.extraMonthly, marginalRatePct: S.marginalRatePct, returnPct: S.returnPct })).concat([{ strategy: 'investInstead', months: S.investInstead.months, interest: '', interestSaved: S.investInstead.afterTaxGain, order: 'after-tax gain on the extra', extraMonthly: S.extraMonthly, marginalRatePct: S.marginalRatePct, returnPct: S.returnPct }])} />}
        </div>
        {L.rows.filter(r => r.kind === 'creditCard').map(r => <div key={r.id} style={{ fontSize: 10, color: r.float ? '#10b981' : '#f59e0b', marginTop: 4 }}>{r.name}: {r.verdict}</div>)}
      </div>

      {/* Strategies */}
      {S && (
        <div className="card" style={{ marginBottom: 16 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12, flexWrap: 'wrap', marginBottom: 6 }}>
            <div className="label" style={{ marginBottom: 0 }}>Avalanche vs snowball vs invest instead <Tag kind="heuristic">debtPlan.strategies</Tag></div>
            <div style={{ display: 'flex', gap: 8, alignItems: 'center', fontSize: 11 }}>
              <span style={{ color: '#94a3b8' }}>Extra per month</span>
              <input type="number" step="100" value={extra} style={{ width: 90, fontSize: 11, padding: '2px 6px' }} onChange={e => setExtra(Number(e.target.value) || 0)} />
              <span style={{ fontSize: 10, color: '#475569' }}>marginal {marginal}% · return {ret}% ({cfg.headlinePreset || 'base'} preset)</span>
            </div>
          </div>
          <div className="grid-3" style={{ gap: 12 }}>
            {[['Avalanche', S.avalanche, 'highest rate first'], ['Snowball', S.snowball, 'smallest balance first'], ['Minimums only', S.minimumsOnly, 'every loan at its minimum']].map(([label, r, sub]) => (
              <div key={label} style={{ border: '1px solid #1e2a3a', borderRadius: 8, padding: '10px 12px', fontSize: 11 }}>
                <div style={{ color: '#e2e8f0', fontWeight: 600 }}>{label} <span style={{ color: '#475569', fontWeight: 400 }}>— {sub}</span></div>
                <div style={{ color: '#94a3b8', marginTop: 4 }}>Debt-free in <strong style={{ color: '#e2e8f0' }}>{r.months >= 600 ? '50+ yrs' : `${Math.floor(r.months / 12)}y ${r.months % 12}m`}</strong> · interest {fmtCur(r.interest)}{r.interestSaved != null ? <> · saves <strong style={{ color: '#10b981' }}>{fmtCur(r.interestSaved)}</strong></> : null}</div>
                {r.order && <div style={{ fontSize: 10, color: '#475569', marginTop: 2 }}>order: {r.order.join(' → ')}</div>}
              </div>
            ))}
          </div>
          <div style={{ marginTop: 10, border: `1px solid ${S.investInstead.wins ? 'rgba(16,185,129,0.4)' : '#1e2a3a'}`, borderRadius: 8, padding: '10px 12px', fontSize: 11 }}>
            <div style={{ color: '#e2e8f0', fontWeight: 600 }}>Invest the extra instead {S.investInstead.wins ? <span style={{ color: '#10b981' }}>— wins</span> : <span style={{ color: '#f59e0b' }}>— loses to the avalanche</span>}</div>
            <div style={{ color: '#94a3b8', marginTop: 4 }}>{fmtCur(S.investInstead.contributed)} contributed over {S.investInstead.months} months → {fmtCur(S.investInstead.futureValue)}, an after-tax gain of <strong style={{ color: '#e2e8f0' }}>{fmtCur(S.investInstead.afterTaxGain)}</strong> vs {fmtCur(S.investInstead.vsAvalancheInterestSaved)} of interest the avalanche saves.</div>
            <div style={{ fontSize: 10, color: '#475569', marginTop: 2 }}>{S.investInstead.note}.</div>
          </div>
          {S.skipped.length > 0 && <div style={{ fontSize: 10, color: '#475569', marginTop: 6 }}>Not attacked: {S.skipped.map(x => `${x.name} (${x.why})`).join(' · ')}.</div>}
        </div>
      )}
    </div>
  );
}

window.FinanceViews = Object.assign(window.FinanceViews || {}, { Debt });
