// ── Transport Settlement Analytics — full-screen BI dashboard ──────────────
// Mirrors the Vendor Settlement Analytics structure but is transporter-
// focused (trips, freight, transporter ranking) — a distinct experience per
// spec, not a re-skin. Derived live from window.SettlementIntel over
// Store('settlementRecords'). Every KPI / chart element opens a dedicated
// analytics popup (see settlement-popups.jsx) instead of scrolling to the ledger.
const { useState: taSt, useMemo: taMemo, useRef: taRef } = React;

function TransportSettlementAnalytics({ transportSettlements, companyId, onBack, onClose }) {
  const C = window.fmtCur;
  const SE = window.SettlementIntel;
  const [bucketFilter, setBucketFilter] = taSt(null);
  const [trFilter, setTrFilter] = taSt(null);
  const [search, setSearch] = taSt('');
  const [statusFilter, setStatusFilter] = taSt(null);
  const [period, setPeriod] = taSt('all');
  const [custom, setCustom] = taSt({ from: '', to: '' });
  const [grain, setGrain] = taSt('monthly');
  const [visible, setVisible] = taSt({ a: true, b: true });
  const [sort, setSort] = taSt({ key: 'pendingAmount', dir: 'desc' });
  const [popup, setPopup] = taSt(null);
  const tableRef = taRef(null);

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

  const stats = taMemo(() => SE.streamStats(live, {}), [live]);
  const prevStats = taMemo(() => SE.streamStats(prevLive, {}), [prevLive]);
  const trend = taMemo(() => SE.trendByGranularity(live, grain), [live, grain]);
  const aging = taMemo(() => SE.agingBuckets(live), [live]);
  const table = taMemo(() => SE.partyTable(live, 'transporterId', 'transporterName'), [live]);
  const rankRows = taMemo(() => table.filter(r => r.pendingAmount > 0).slice(0, 8), [table]);
  const transportersSettled = taMemo(() => table.filter(r => r.status === 'Fully Settled').length, [table]);
  const tripsSettled = taMemo(() => live.filter(s => SE.isFullySettled(s)).reduce((s, r) => s + (r.tripCount || 0), 0), [live]);
  const tripsPending = taMemo(() => live.filter(s => !SE.isCancelled(s) && !SE.isFullySettled(s)).reduce((s, r) => s + (r.tripCount || 0), 0), [live]);
  const execSplit = taMemo(() => SE.execSplit(live), [live]);
  const execStrip = taMemo(() => SE.buildExecStrip(stats, prevStats, table, 'transporter'), [stats, prevStats, table]);

  const filteredTable = taMemo(() => {
    let rows = table.filter(r => {
      if (search && !(r.name || '').toLowerCase().includes(search.toLowerCase())) return false;
      if (trFilter && r.id !== trFilter) 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.transporterId === 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, trFilter, bucketFilter, statusFilter, live, sort]);

  const footTotals = taMemo(() => 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] = taSt(null);
  const accent = '#1D4ED8';

  const ctx = { C, SE, accent, partyLabel: 'Transporter', idKey: 'transporterId', nameKey: 'transporterName', 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 => which === 'both' ? { a: true, b: true } : { ...v, [which]: !v[which] }); }
  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 = ['Transporter', 'Trips', 'Settled', 'Pending', 'Pending Amount', 'Settlement %', 'Avg Days', 'Last Settlement', 'Status'];
    const lines = [head.join(',')].concat(filteredTable.map(r => {
      const trips = live.filter(s => s.transporterId === r.id).reduce((s, x) => s + (x.tripCount || 0), 0);
      return [r.name, trips, 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 = 'transport-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="Truck" size={18} color={accent} /> Transport 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 Transport Settlement" numeric={stats.totalPayable} numericFmt={C} icon="Wallet" onClick={() => openPopup('payable')} />
          <SEKpiTile label="Pending Transport Settlement" 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="Transporters Settled" numeric={transportersSettled} value={transportersSettled} color="var(--ok)" icon="CheckCircle2" onClick={() => openPopup('settled')} active={statusFilter === 'settled'} />
          <SEKpiTile label="Pending Transporters" numeric={stats.pendingPartyCount} value={stats.pendingPartyCount} icon="Users" onClick={() => openPopup('pendingvendors')} active={statusFilter === 'pending'} />
          <SEKpiTile label="Average Settlement Time" value={stats.avgSettlementDays.toFixed(1) + 'd'} numeric={Math.round(stats.avgSettlementDays * 10) / 10} suffix="d" icon="CalendarClock" onClick={() => openPopup('avgdays')} />
          <SEKpiTile label="Settlement Accuracy" value={stats.accuracyPct.toFixed(1) + '%'} numeric={Math.round(stats.accuracyPct * 10) / 10} suffix="%" icon="ShieldCheck" onClick={() => openPopup('accuracy')} />
          <SEKpiTile label="Oldest Pending Settlement" value={stats.oldestPendingDays + 'd'} sub={stats.oldestPendingRec ? (stats.oldestPendingRec.transporterName || '—') : '—'} color={stats.oldestPendingDays > SE.TARGET_DAYS ? '#DC2626' : 'var(--txt)'} icon="AlertTriangle" onClick={onOldestPending} />
        </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">Transport 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">Trips Settled vs Pending</div>
            <SEDonutRing settled={tripsSettled} pending={tripsPending} C={v => v.toLocaleString() + ' trips'} 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">Top Pending Transporters {trFilter && <span className="se-chip-clear" onClick={() => setTrFilter(null)}>clear filter</span>}</div>
            <SERankBars rows={rankRows} onClick={id => { setTrFilter(id); const row = table.find(r => r.id === id); if (row) openPopup('profile', { party: row }); }} activeId={trFilter} 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>Transporter 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 transporter…" 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')}>Transporter{sortArrow('name')}</th>
                <th className="r">Trips</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 transport settlements match the current filters.</td></tr>}
                {filteredTable.map(r => {
                  const trips = live.filter(s => s.transporterId === r.id).reduce((s, x) => s + (x.tripCount || 0), 0);
                  return (
                    <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">{trips}</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">Trips</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.transporterId === 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">{s.tripCount || 0}</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.StBadge s={s.status} /></td>
                                  </tr>
                                  {s.challanRows && s.challanRows.length > 0 && (
                                    <tr><td colSpan={6} 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 Challans</div>
                                      <table className="se-table" style={{ fontSize: 11 }}>
                                        <thead><tr><th>Challan</th><th>Date</th><th>Source</th><th className="r">Freight</th><th>Status</th></tr></thead>
                                        <tbody>
                                          {s.challanRows.map((cr, i) => (
                                            <tr key={i}><td style={{ fontFamily: 'var(--font)', fontWeight: 700, color: accent }}>{cr.challanDisplay || cr.challanNumber}</td><td>{cr.date ? window.fmtDate(cr.date) : '—'}</td><td>{cr.sourceLabel || '—'}</td><td className="r">{C(cr.netFreight || cr.grossFreight || 0)}</td><td>{cr.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"></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.TransportSettlementAnalytics = TransportSettlementAnalytics;
