// ════════════════════════════════════════════════════════════════════════
// PropMystro · Phase D · pm-d-finance.jsx
// Rent ledger & arrears — the first PAID module. Demonstrates the Phase F
// double-lock: the UI checks account.features.ledger and shows an upgrade
// prompt if absent, AND the database refuses writes to `payments` without the
// feature (RLS write_feature='ledger' from migration 0006). Records payments,
// computes expected-vs-received and the arrears balance. → window.PMFinance.
// ════════════════════════════════════════════════════════════════════════
(function () {
  const { useState, useEffect, useCallback } = React;

  const METHODS = [
    { v: 'bank_transfer', l: 'Bank transfer' }, { v: 'standing_order', l: 'Standing order' },
    { v: 'card', l: 'Card' }, { v: 'cash', l: 'Cash' },
  ];
  const fmt = (d) => d ? new Date(d).toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric' }) : '—';
  const gbp = (n) => '£' + Number(n || 0).toLocaleString('en-GB', { minimumFractionDigits: 0, maximumFractionDigits: 2 });

  function Spin() { return <span className="spin dark" />; }

  // months elapsed (inclusive) between a start date and today, capped sensibly
  function monthsElapsed(start) {
    if (!start) return 0;
    const s = new Date(start), n = new Date();
    let m = (n.getFullYear() - s.getFullYear()) * 12 + (n.getMonth() - s.getMonth());
    if (n.getDate() >= s.getDate()) m += 1;            // count the current month once due
    return Math.max(0, m);
  }

  function FinancePanel({ sb, property, account, toast, openBilling }) {
    const entitled = account.features && account.features.ledger === true;
    const [tenancy, setTenancy] = useState(undefined);   // undefined=loading, null=none
    const [payments, setPayments] = useState([]);
    const [adding, setAdding] = useState(false);
    const [busy, setBusy] = useState(false);
    const [err, setErr] = useState('');
    const today = new Date().toISOString().slice(0, 10);
    const [p, setP] = useState({ date: today, amount: '', method: 'bank_transfer', ref: '' });

    const load = useCallback(async () => {
      if (!entitled) return;
      const ty = await sb.from('tenancies').select('*').eq('property_id', property.id).eq('status', 'active').limit(1);
      const active = ty.data && ty.data[0];
      setTenancy(active || null);
      if (active) {
        const pay = await sb.from('payments').select('*').eq('tenancy_id', active.id).order('date', { ascending: false });
        setPayments(pay.data || []);
      }
    }, [sb, property.id, entitled]);
    useEffect(() => { load(); }, [load]);

    // ── locked (not on plan) ──────────────────────────────────────────────
    if (!entitled) return <div className="card-pad">
      <div className="locked">
        <div className="lock-ico">🔒</div>
        <h3>Rent ledger is a Professional feature</h3>
        <p>Track rent received, see arrears at a glance, and reconcile against your bank. Upgrade your plan to switch it on for every property.</p>
        <button className="btn btn-primary btn-sm" onClick={() => openBilling ? openBilling() : toast('Open Plans to upgrade')} style={{ width: 'auto' }}>Upgrade to Professional</button>
        <div className="lock-foot">Your data stays exactly as it is — upgrading just unlocks the module.</div>
      </div>
    </div>;

    if (tenancy === undefined) return <div className="card-pad"><Spin /></div>;
    if (!tenancy) return <div className="empty"><div className="ico">💷</div><h3>No active tenancy</h3><p>Create a tenancy on the Tenancy tab first — the ledger tracks rent against it.</p></div>;

    const rent = Number(tenancy.rent_pcm || 0);
    const months = monthsElapsed(tenancy.start_date);
    const expected = rent * months;
    const received = payments.reduce((s, x) => s + Number(x.amount || 0), 0);
    const balance = received - expected;          // negative = in arrears
    const arrears = balance < 0;

    const record = async () => {
      setErr('');
      if (!p.amount || Number(p.amount) <= 0) return setErr('Enter the amount received.');
      setBusy(true);
      const { error } = await sb.from('payments').insert({
        tenancy_id: tenancy.id, property_id: property.id, date: p.date, amount: Number(p.amount),
        kind: 'payment', method: p.method, ref: p.ref.trim() || null,
      });
      setBusy(false);
      if (error) return setErr(/ledger/.test(error.message) ? 'This needs the Professional plan.' : error.message);
      setP({ date: today, amount: '', method: 'bank_transfer', ref: '' }); setAdding(false);
      toast('Payment recorded'); load();
    };

    return <React.Fragment>
      <div className="card-pad" style={{ borderBottom: '1px solid var(--line-soft)' }}>
        <div className="summary" style={{ marginBottom: 0 }}>
          <div className="sumcard"><div className="n">{gbp(rent)}</div><div className="l">Rent pcm</div></div>
          <div className="sumcard"><div className="n">{gbp(received)}</div><div className="l">Received to date</div></div>
          <div className={'sumcard ' + (arrears ? 'bad' : 'ok')}><div className="n">{arrears ? '−' + gbp(-balance) : gbp(balance)}</div><div className="l">{arrears ? 'In arrears' : 'In credit / square'}</div></div>
        </div>
        <div style={{ fontSize: 12.5, color: 'var(--ink-faint)', marginTop: 10 }}>Expected {gbp(expected)} over {months} month{months === 1 ? '' : 's'} since {fmt(tenancy.start_date)}.</div>
      </div>

      <div className="card-head">
        <div><h3>Rent ledger</h3><div className="sub">{payments.length} payment{payments.length === 1 ? '' : 's'} recorded</div></div>
        {!adding && <button className="btn btn-ghost btn-sm" onClick={() => { setAdding(true); setErr(''); }}>+ Record payment</button>}
      </div>

      {adding && <div className="card-pad" style={{ borderBottom: '1px solid var(--line-soft)' }}>
        {err && <div className="alert alert-err"><span className="ic">⚠</span><div>{err}</div></div>}
        <div className="inline-form">
          <div className="field"><label>Date</label><input type="date" value={p.date} onChange={e => setP({ ...p, date: e.target.value })} /></div>
          <div className="field"><label>Amount (£)</label><input value={p.amount} onChange={e => setP({ ...p, amount: e.target.value.replace(/[^\d.]/g, '') })} placeholder={String(rent || '')} /></div>
          <div className="field"><label>Method</label><select value={p.method} onChange={e => setP({ ...p, method: e.target.value })}>{METHODS.map(x => <option key={x.v} value={x.v}>{x.l}</option>)}</select></div>
          <div className="field grow"><label>Reference</label><input value={p.ref} onChange={e => setP({ ...p, ref: e.target.value })} placeholder="optional" /></div>
          <button className="btn btn-primary btn-sm" onClick={record} disabled={busy}>{busy ? <Spin /> : 'Record'}</button>
          <button className="btn btn-ghost btn-sm" onClick={() => { setAdding(false); setErr(''); }}>Cancel</button>
        </div>
      </div>}

      {payments.length === 0 && !adding && <div className="empty"><div className="ico">💷</div><h3>No payments yet</h3><p>Record rent as it comes in and PropMystro keeps a running arrears balance for you.</p><button className="btn btn-primary btn-sm" onClick={() => setAdding(true)}>+ Record a payment</button></div>}

      {payments.map(x => <div className="row" key={x.id}>
        <span className="avatar" style={{ background: 'var(--brand-soft)', color: 'var(--brand-deep)' }}>£</span>
        <div className="main">
          <div className="t">{gbp(x.amount)}{x.kind === 'credit' ? ' · credit' : ''}</div>
          <div className="s">{fmt(x.date)} · {(METHODS.find(m => m.v === x.method) || {}).l || x.method}{x.ref ? ' · ' + x.ref : ''}</div>
        </div>
      </div>)}
    </React.Fragment>;
  }

  window.PMFinance = FinancePanel;
})();
