// ── Vendor Settlement Analytics — full-screen BI dashboard ─────────────────
// Every chart/table here filters every other one (aging bucket ↔ ranking ↔
// search ↔ table), all derived from window.SettlementIntel over live
// Store('vendorSettlements') data. Lazy-mounted only when the user opens it
// from the Settlement Performance Center (see settlement-performance-center.jsx).
// Every KPI / chart element opens a dedicated analytics popup (see
// settlement-popups.jsx) instead of scrolling to the ledger.
const { useState: vaSt, useMemo: vaMemo, useRef: vaRef } = React;

function VendorSettlementAnalytics({ vendorSettlements, companyId, onBack, onClose }) {
  const C = window.fmtCur;
  const SE = window.SettlementIntel;
  const [bucketFilter, setBucketFilter] = vaSt(null);
  const [vendorFilter, setVendorFilter] = vaSt(null);
  const [search, setSearch] = vaSt('');
  const [statusFilter, setStatusFilter] = vaSt(null); // 'settled' | 'pending' | 'overdue' | null
  const [period, setPeriod] = vaSt('all');
  const [custom, setCustom] = vaSt({ from: '', to: '' });
  const [grain, setGrain] = vaSt('monthly');
  const [visible, setVisible] = vaSt({ a: true, b: true });
  const [sort, setSort] = vaSt({ key: 'pendingAmount', dir: 'desc' });
  const [popup, setPopup] = vaSt(null); // { kind, payload }
  const tableRef = vaRef(null);

  const range = vaMemo(() => SE.periodRange(period, custom.from, custom.to), [period, custom]);
  const scopedByCompany = vaMemo(() => (vendorSettlements || []).filter(s => !companyId || companyId === 'group' || s.companyId === companyId), [vendorSettlements, companyId]);
  const live = vaMemo(() => SE.filterByPeriod(scopedByCompany, range), [scopedByCompany, range]);
  const prevRange = vaMemo(() => SE.shiftedPreviousRange(range), [range]);
  const prevLive = vaMemo(() => SE.filterByPeriod(scopedByCompany, prevRange), [scopedByCompany, prevRange]);

  const stats = vaMemo(() => SE.streamStats(live, {}), [live]);
  const prevStats = vaMemo(() => SE.streamStats(prevLive, {}), [prevLive]);
  const trend = vaMemo(() => SE.trendByGranularity(live, grain), [live, grain]);
  const aging = vaMemo(() => SE.agingBuckets(live), [live]);
  const table = vaMemo(() => SE.partyTable(live, 'vendorId', 'vendorName'), [live]);
  const rankRows = vaMemo(() => table.filter(r => r.pendingAmount > 0).slice(0, 8), [table]);
  const execSplit = vaMemo(() => SE.execSplit(live), [live]);
  const execStrip = vaMemo(() => SE.buildExecStrip(stats, prevStats, table, 'vendor'), [stats, prevStats, table]);

  const filteredTable = vaMemo(() => {
    let rows = table.filter(r => {
      if (search && !(r.name || '').toLowerCase().includes(search.toLowerCase())) return false;
      if (vendorFilter && r.id !== vendorFilter) return false;
      if (statusFilter === 'settled' && r.pending > 0) return false;
      if (statusFilter === 'pending' && r.pending === 0) return false;
      if (statusFilter === 'overdue' && !r.overdue) return false;
      if (bucketFilter) {
        const b = SE.AGING_BUCKETS.find(x => x.id === bucketFilter);
        const recs = live.filter(s => s.vendorId === r.id && !SE.isCancelled(s) && !SE.isFullySettled(s));
        const hit = recs.some(s => { const d = SE.daysBetween(SE.periodEnd(s), SE.todayStr()); return d >= b.min && d <= b.max; });
        if (!hit) return false;
      }
      return true;
    });
    const dir = sort.dir === 'asc' ? 1 : -1;
    rows = [...rows].sort((a, b) => {
      const av = a[sort.key], bv = b[sort.key];
      if (typeof av === 'string') return av.localeCompare(bv) * dir;
      return ((av || 0) - (bv || 0)) * dir;
    });
    return rows;
  }, [table, search, vendorFilter, bucketFilter, statusFilter, live, sort]);

  const footTotals = vaMemo(() => filteredTable.reduce((a, r) => {
    a.bills += r.bills; a.settled += r.settled; a.pending += r.pending; a.pendingAmount += r.pendingAmount;
    a.daysSum += r.avgDays > 0 ? r.avgDays : 0; a.daysN += r.avgDays > 0 ? 1 : 0;
    return a;
  }, { bills: 0, settled: 0, pending: 0, pendingAmount: 0, daysSum: 0, daysN: 0 }), [filteredTable]);

  const [expandId, setExpandId] = vaSt(null);
  const accent = '#7C3AED';

  const ctx = { C, SE, accent, partyLabel: 'Vendor', idKey: 'vendorId', nameKey: 'vendorName', live, scoped: scopedByCompany, table, stats, prevStats, aging, rankRows, execSplit, companyId: companyId || 'group', range, prevRange, grain };
  function openPopup(kind, payload) { setPopup({ kind, payload: payload || {} }); }
  function closePopup() { setPopup(null); }

  function toggleLegend(which) {
    setVisible(v => {
      if (which === 'both') return { a: true, b: true };
      const nv = { ...v, [which]: !v[which] };
      return nv;
    });
  }
  React.useEffect(() => {
    if (visible.a && !visible.b) setStatusFilter('settled');
    else if (!visible.a && visible.b) setStatusFilter('pending');
    else if (visible.a && visible.b) setStatusFilter(s => (s === 'settled' || s === 'pending') ? null : s);
    // eslint-disable-next-line
  }, [visible]);

  function onOldestPending() { openPopup('oldest'); }
  function exportCsv() {
    const head = ['Vendor', 'Bills', 'Settled', 'Pending', 'Pending Amount', 'Settlement %', 'Avg Days', 'Last Settlement', 'Status'];
    const lines = [head.join(',')].concat(filteredTable.map(r => [r.name, r.bills, r.settled, r.pending, r.pendingAmount.toFixed(2), r.settlementPct.toFixed(1), r.avgDays, r.lastSettlement || '', r.status].map(v => `"${String(v).replace(/"/g, '""')}"`).join(',')));
    const blob = new Blob([lines.join('\n')], { type: 'text/csv' });
    const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = 'vendor-settlement-ledger.csv'; a.click();
  }
  function sortBy(key) { setSort(s => s.key === key ? { key, dir: s.dir === 'asc' ? 'desc' : 'asc' } : { key, dir: 'desc' }); }
  const sortArrow = key => sort.key === key ? (sort.dir === 'asc' ? ' ▲' : ' ▼') : '';

  const meta = popup ? window.SE_POPUP_META(popup.kind, popup.payload, ctx) : null;

  return ReactDOM.createPortal(
    <div className="se-full">
      <div className="se-full-hd">
        <button className="se-full-back" onClick={onBack}><SEIcon name="ChevronLeft" size={16} /> Performance Center</button>
        <div className="se-full-hdtitle"><SEIcon name="Building2" size={18} color={accent} /> Vendor Settlement Analytics</div>
        <button className="mod-x" onClick={onClose}>×</button>
      </div>
      <div className="se-full-body">
        <SETimeBar period={period} setPeriod={setPeriod} custom={custom} setCustom={setCustom} accent={accent} />

        <div className="se-kpi-strip">
          <SEKpiTile label="Total Vendor Payable" numeric={stats.totalPayable} numericFmt={C} icon="Wallet" onClick={() => openPopup('payable')} />
          <SEKpiTile label="Settled Amount" numeric={stats.settledAmount} numericFmt={C} color="var(--ok)" icon="CheckCircle2" onClick={() => openPopup('settled')} active={statusFilter === 'settled'} />
          <SEKpiTile label="Pending Amount" numeric={stats.pendingAmount} numericFmt={C} color="#B45309" icon="Clock" onClick={() => openPopup('pending')} active={statusFilter === 'pending'} />
          <SEKpiTile label="Settlement Efficiency" value={stats.efficiencyPct.toFixed(1) + '%'} numeric={Math.round(stats.efficiencyPct * 10) / 10} suffix="%" color={accent} icon="Gauge" onClick={() => openPopup('efficiency')} />
          <SEKpiTile label="Avg Settlement Days" value={stats.avgSettlementDays.toFixed(1) + 'd'} numeric={Math.round(stats.avgSettlementDays * 10) / 10} suffix="d" icon="CalendarClock" onClick={() => openPopup('avgdays')} />
          <SEKpiTile label="Oldest Pending Bill" value={stats.oldestPendingDays + 'd'} sub={stats.oldestPendingRec ? (stats.oldestPendingRec.vendorName || '—') : '—'} color={stats.oldestPendingDays > SE.TARGET_DAYS ? '#DC2626' : 'var(--txt)'} icon="AlertTriangle" onClick={onOldestPending} />
          <SEKpiTile label="Pending Vendors" numeric={stats.pendingPartyCount} value={stats.pendingPartyCount} icon="Users" onClick={() => openPopup('pendingvendors')} active={statusFilter === 'pending'} />
          <SEKpiTile label="Settlement Accuracy" value={stats.accuracyPct.toFixed(1) + '%'} numeric={Math.round(stats.accuracyPct * 10) / 10} suffix="%" icon="ShieldCheck" onClick={() => openPopup('accuracy')} />
        </div>

        <SEExecStrip items={execStrip} accent={accent} onOpen={(kind, payload) => openPopup(kind, payload)} />

        <div className="se-chart-grid">
          <div className="se-chart-card" style={{ gridColumn: 'span 2' }}>
            <div className="se-chart-hd">Vendor Settlement Trend — Settled vs Pending (click a bar to drill in)</div>
            <SEGrainChart grain={grain} setGrain={setGrain} data={trend} C={C} aColor="#38BDF8" bColor="#FB923C" aLabel="Settled" bLabel="Pending" onBarClick={pt => openPopup('period', { point: pt })} />
          </div>
          <div className="se-chart-card se-chart-card-donut">
            <div className="se-chart-hd">Pending vs Settled</div>
            <SEDonutRing settled={stats.settledAmount} pending={stats.pendingAmount} C={C} visible={visible} onToggle={toggleLegend} onSliceClick={k => openPopup(k)} />
          </div>
          <div className="se-chart-card">
            <div className="se-chart-hd">Settlement Aging {bucketFilter && <span className="se-chip-clear" onClick={() => setBucketFilter(null)}>clear filter</span>}</div>
            <SEAgingBars buckets={aging} onClick={id => { setBucketFilter(id); const b = SE.AGING_BUCKETS.find(x => x.id === id); if (b) openPopup('aging', { bucket: b }); }} activeId={bucketFilter} C={C} />
          </div>
          <div className="se-chart-card">
            <div className="se-chart-hd">Largest Pending Vendors {vendorFilter && <span className="se-chip-clear" onClick={() => setVendorFilter(null)}>clear filter</span>}</div>
            <SERankBars rows={rankRows} onClick={id => { setVendorFilter(id); const row = table.find(r => r.id === id); if (row) openPopup('profile', { party: row }); }} activeId={vendorFilter} C={C} accent={accent} />
          </div>
        </div>

        <div className="se-table-card" ref={tableRef}>
          <div className="se-chart-hd se-toolbar" style={{ justifyContent: 'space-between' }}>
            <span>Vendor Settlement Ledger ({filteredTable.length})</span>
            <div className="se-toolbar">
              {['settled', 'pending', 'overdue'].map(s => (
                <button key={s} className={`se-statuschip ${statusFilter === s ? 'se-statuschip-on' : ''}`} style={statusFilter === s ? { background: accent, borderColor: accent } : null} onMouseDown={window.seRipple} onClick={() => setStatusFilter(v => v === s ? null : s)}>{s[0].toUpperCase() + s.slice(1)}</button>
              ))}
              <input className="se-search" placeholder="Search vendor…" value={search} onChange={e => setSearch(e.target.value)} />
              <button className="se-exportbtn" onMouseDown={window.seRipple} onClick={exportCsv}><SEIcon name="Download" size={13} /> Export CSV</button>
            </div>
          </div>
          <div className="se-table-scroll">
            <table className="se-table">
              <thead><tr>
                <th className="se-th-sort" onClick={() => sortBy('name')}>Vendor{sortArrow('name')}</th>
                <th className="r se-th-sort" onClick={() => sortBy('bills')}>Bills{sortArrow('bills')}</th>
                <th className="r se-th-sort" onClick={() => sortBy('settled')}>Settled{sortArrow('settled')}</th>
                <th className="r se-th-sort" onClick={() => sortBy('pending')}>Pending{sortArrow('pending')}</th>
                <th className="r se-th-sort" onClick={() => sortBy('pendingAmount')}>Pending Amount{sortArrow('pendingAmount')}</th>
                <th className="r se-th-sort" onClick={() => sortBy('settlementPct')}>Settlement %{sortArrow('settlementPct')}</th>
                <th className="r se-th-sort" onClick={() => sortBy('avgDays')}>Avg Days{sortArrow('avgDays')}</th>
                <th>Last Settlement</th><th>Status</th>
              </tr></thead>
              <tbody>
                {filteredTable.length === 0 && <tr><td colSpan={9} style={{ padding: 16, color: 'var(--txt3)', fontStyle: 'italic' }}>No vendor settlements match the current filters.</td></tr>}
                {filteredTable.map(r => (
                  <React.Fragment key={r.id}>
                    <tr className="se-row" onClick={() => setExpandId(expandId === r.id ? null : r.id)}>
                      <td style={{ fontWeight: 700 }}>{r.name}</td>
                      <td className="r">{r.bills}</td>
                      <td className="r">{r.settled}</td>
                      <td className="r">{r.pending}</td>
                      <td className="r" style={{ fontWeight: 700, color: r.pendingAmount > 0 ? '#B45309' : 'var(--txt3)' }}>{C(r.pendingAmount)}</td>
                      <td className="r">{r.settlementPct.toFixed(0)}%</td>
                      <td className="r">{r.avgDays || '—'}</td>
                      <td>{r.lastSettlement ? window.fmtDate(r.lastSettlement) : '—'}</td>
                      <td><SEStatusPill status={r.status} /></td>
                    </tr>
                    {expandId === r.id && (
                      <tr><td colSpan={9} style={{ background: '#FAFAFA', padding: '10px 14px' }}>
                        <div style={{ fontSize: 10.5, fontWeight: 700, color: 'var(--txt2)', marginBottom: 6, textTransform: 'uppercase', letterSpacing: '.04em' }}>Settlement History — {r.name}</div>
                        <table className="se-table" style={{ background: '#fff' }}>
                          <thead><tr><th>Period</th><th className="r">Net Payable</th><th className="r">Outstanding</th><th>Created</th><th>Status</th></tr></thead>
                          <tbody>
                            {live.filter(s => s.vendorId === r.id).sort((a, b) => (b.createdDate || '').localeCompare(a.createdDate || '')).map(s => (
                              <React.Fragment key={s.id}>
                                <tr>
                                  <td>{window.fmtDate(s.periodFrom)} – {window.fmtDate(s.periodTo)}</td>
                                  <td className="r">{C(s.netPayable || 0)}</td>
                                  <td className="r" style={{ color: (s.outstandingBalance || 0) > 0 ? '#B45309' : 'var(--txt3)' }}>{C(s.outstandingBalance || 0)}</td>
                                  <td>{s.createdDate ? window.fmtDate(s.createdDate) : '—'}</td>
                                  <td><window.VsBadge s={s.status} /></td>
                                </tr>
                                {s.purchaseRows && s.purchaseRows.length > 0 && (
                                  <tr><td colSpan={5} style={{ background: '#fff', padding: '4px 0 10px 14px' }}>
                                    <div style={{ fontSize: 9.5, fontWeight: 700, color: 'var(--txt3)', textTransform: 'uppercase', letterSpacing: '.04em', marginBottom: 4 }}>Linked Original Bills</div>
                                    <table className="se-table" style={{ fontSize: 11 }}>
                                      <thead><tr><th>PO / Challan</th><th>Date</th><th>Material</th><th className="r">Amount</th><th>Bill Status</th></tr></thead>
                                      <tbody>
                                        {s.purchaseRows.map((pr, i) => (
                                          <tr key={i}><td style={{ fontFamily: 'var(--font)', fontWeight: 700, color: accent }}>{pr.poNo}</td><td>{pr.date ? window.fmtDate(pr.date) : '—'}</td><td>{pr.material}</td><td className="r">{C(pr.amountWithGst || pr.amount || 0)}</td><td>{pr.settlementStatus || '—'}</td></tr>
                                        ))}
                                      </tbody>
                                    </table>
                                  </td></tr>
                                )}
                              </React.Fragment>
                            ))}
                          </tbody>
                        </table>
                      </td></tr>
                    )}
                  </React.Fragment>
                ))}
              </tbody>
              <tfoot>
                <tr className="se-table-foot">
                  <td>Total ({filteredTable.length})</td>
                  <td className="r">{footTotals.bills}</td>
                  <td className="r">{footTotals.settled}</td>
                  <td className="r">{footTotals.pending}</td>
                  <td className="r" style={{ color: '#B45309' }}>{C(footTotals.pendingAmount)}</td>
                  <td className="r">{footTotals.bills > 0 ? (footTotals.settled / footTotals.bills * 100).toFixed(0) : 0}%</td>
                  <td className="r">{footTotals.daysN > 0 ? Math.round(footTotals.daysSum / footTotals.daysN) : '—'}</td>
                  <td colSpan={2}></td>
                </tr>
              </tfoot>
            </table>
          </div>
        </div>
      </div>

      {popup && (
        <SEKpiPopup title={meta.title} subtitle={meta.subtitle} icon={meta.icon} accent={accent} onClose={closePopup} onExport={exportCsv} onPrint={() => window.print()} wide={popup.kind === 'pendingvendors' || popup.kind === 'profile'}>
          {window.SERenderKpiPopup({ kind: popup.kind, payload: popup.payload, ctx })}
        </SEKpiPopup>
      )}
    </div>,
    document.body
  );
}
window.VendorSettlementAnalytics = VendorSettlementAnalytics;
