// Visão Geral → seção "Canais de recuperação" (spec 2026-08-28-recuperacao-sobre-gross):
// % de Logicall/SMS/Salesbound/E-mail sobre o gross direto CONSOLIDADO + tabela por
// família. Fetch próprio (/channels/recovery) seguindo período+Reembolso globais;
// produto/plataforma NÃO se aplicam (nota na tela). Sem mock: dado operacional —
// offline mostra nota com auto-retry (spec 2026-07-30-reconexao). Prefixo: rcv.
const RCV_CANAIS = [
  { key: 'logicall', label: 'Logicall' }, { key: 'sms', label: 'SMS' },
  { key: 'salesbound', label: 'Salesbound' }, { key: 'email', label: 'E-mail' },
];
const rcvPct = (v) => (v == null ? '—' : PCT(v));

const RcvRecoverySection = ({ period, customRange, refundBy }) => {
  const [data, setData] = React.useState(null);
  const [err, setErr] = React.useState(false);
  const [loading, setLoading] = React.useState(false);
  const retry = useAutoRetry(err);
  const [sortKey, setSortKey] = React.useState('grossDireto');
  const [dir, setDir] = React.useState(-1);

  React.useEffect(() => {
    let cancelled = false;
    setLoading(true);
    fetchRecoveryAPI({ period, refundBy, start: customRange?.start, end: customRange?.end })
      .then(d => { if (!cancelled) { setData(d); setErr(false); } })
      .catch(() => { if (!cancelled) setErr(true); })
      .finally(() => { if (!cancelled) setLoading(false); });
    return () => { cancelled = true; };
  }, [period, customRange, refundBy, retry]);

  const sortBy = (k) => (k === sortKey ? setDir(-dir) : (setSortKey(k), setDir(-1)));
  const ind = (k) => (sortKey === k ? (dir < 0 ? ' ▾' : ' ▴') : '');
  const sortVal = (r) =>
    sortKey === 'familia' ? r.familia
    : sortKey === 'grossDireto' ? r.grossDireto
    : sortKey === 'recPct' ? (r.recPct ?? -1)
    : (r[sortKey] ? r[sortKey].gross : 0);

  const header = (
    <div style={rcv.head}>
      <div>
        <div style={rcv.eye}>Recuperação</div>
        <div style={rcv.title}>Canais de recuperação · % sobre o gross direto</div>
        {loading && data && <span style={rcv.updating}>atualizando…</span>}
      </div>
    </div>
  );
  if (!data) {
    return (
      <div style={rcv.panel}>{header}
        <div style={rcv.waiting}>
          {err ? 'Sem conexão com a API — a seção volta sozinha quando ela responder.' : 'Carregando…'}
        </div>
      </div>
    );
  }
  const t = data.totais;
  const rows = (data.porProduto || []).slice()
    .sort((a, b) => {
      const av = sortVal(a), bv = sortVal(b);
      if (typeof av === 'string') return av.localeCompare(bv) * dir;
      return (av - bv) * dir;
    });

  return (
    <div style={rcv.panel}>
      {header}
      {err && data && <div style={rcv.notice}><Icon name="alert" size={14} color="currentColor"/>Falha ao atualizar — mostrando o último dado carregado.</div>}
      <div className="kpi-grid" style={rcv.chips}>
        <DotKpi eye="Recuperação total · Logicall + SMS + Salesbound + E-mail" color="var(--fenix-orange)"
          value={USDk(t.recuperacaoTotal.gross)}
          sub={`${rcvPct(t.recuperacaoTotal.pct)} do gross direto`} subColor="var(--fenix-orange)" hoverable />
        {RCV_CANAIS.map(c => (
          <DotKpi key={c.key} eye={c.label} color={CH[c.key].color}
            value={USDk(t.canais[c.key].gross)}
            sub={`${rcvPct(t.canais[c.key].pct)} do gross${c.key === 'email' ? ' · cobertura parcial' : ''}`}
            hoverable />
        ))}
      </div>
      <div style={rcv.scroll}>
        <table style={rcv.tbl}>
          <thead><tr>
            <th onClick={() => sortBy('familia')} style={{ ...rcv.th, textAlign: 'left' }}>Família{ind('familia')}</th>
            <th onClick={() => sortBy('grossDireto')} style={rcv.th}>Gross direto{ind('grossDireto')}</th>
            {RCV_CANAIS.map(c => (
              <th key={c.key} onClick={() => sortBy(c.key)} style={rcv.th}>{c.label}{ind(c.key)}</th>
            ))}
            <th onClick={() => sortBy('recPct')} style={rcv.th}>Rec. %{ind('recPct')}</th>
          </tr></thead>
          <tbody>
            {rows.map(r => (
              <tr key={r.familia}
                onMouseEnter={e => { e.currentTarget.style.background = 'var(--gray-50)'; }}
                onMouseLeave={e => { e.currentTarget.style.background = 'transparent'; }}>
                <td style={{ ...rcv.td, textAlign: 'left', fontWeight: 700 }}>{r.familia}</td>
                <td style={rcv.td} className="fenix-num">{USDk(r.grossDireto)}</td>
                {RCV_CANAIS.map(c => (
                  <td key={c.key} style={rcv.td} className="fenix-num">
                    <div>{r[c.key].gross ? USDk(r[c.key].gross) : '—'}</div>
                    <div style={rcv.tdPct}>{r[c.key].gross ? rcvPct(r[c.key].pct) : ''}</div>
                  </td>
                ))}
                <td style={{ ...rcv.td, fontWeight: 700, color: 'var(--fenix-orange)' }} className="fenix-num">
                  {rcvPct(r.recPct)}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
      <div style={rcv.note}>
        SMS e E-mail são fatias do próprio gross direto (vendas buygoods marcadas no codename;
        cobertura do E-mail é parcial). Logicall e Salesbound são receita adicional às vendas
        diretas. Janela segue período e Reembolso; filtros de produto/plataforma não se aplicam.
        Tauk fica de fora (canal descontinuado em 03/jul) — o KPI "Recuperação" da fileira de
        KPIs no topo da página inclui Tauk e usa a régua bruta própria, por isso os dois números
        diferem.
      </div>
    </div>
  );
};

const rcv = {
  panel: { background: '#fff', border: '1px solid var(--border-1)', borderRadius: 'var(--r-lg)', padding: '20px 22px', boxShadow: 'var(--shadow-sm)' },
  head: { display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', marginBottom: 14, gap: 16 },
  eye: { font: 'var(--text-label)', letterSpacing: '.05em', textTransform: 'uppercase', color: 'var(--fg-3)' },
  title: { font: 'var(--text-h3)', color: 'var(--fg-1)', marginTop: 4 },
  chips: { display: 'grid', gridTemplateColumns: 'repeat(5,minmax(0,1fr))', gap: 12, marginBottom: 16 },
  scroll: { overflowX: 'auto' },
  tbl: { width: '100%', borderCollapse: 'collapse' },
  th: { font: '600 10px/1 var(--font-sans)', letterSpacing: '.05em', textTransform: 'uppercase', color: 'var(--fg-4)', textAlign: 'right', padding: '6px 8px', borderBottom: '1px solid var(--border-1)', cursor: 'pointer', whiteSpace: 'nowrap', userSelect: 'none' },
  td: { font: '600 12.5px/1.25 var(--font-num)', color: 'var(--fg-1)', textAlign: 'right', padding: '9px 8px', borderBottom: '1px solid var(--border-1)', fontVariantNumeric: 'tabular-nums', whiteSpace: 'nowrap' },
  tdPct: { font: '600 10.5px/1 var(--font-mono)', color: 'var(--fg-3)', marginTop: 3 },
  waiting: { display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: 96, color: 'var(--fg-3)', font: '600 13px/1.4 var(--font-sans)', border: '1px dashed var(--border-2)', borderRadius: 'var(--r-md)', padding: 12, textAlign: 'center' },
  notice: { display: 'flex', alignItems: 'center', gap: 8, font: '600 12px/1.4 var(--font-sans)', color: 'var(--warning)', background: 'var(--warning-bg)', borderRadius: 'var(--r-md)', padding: '8px 12px', marginBottom: 12 },
  updating: { font: '600 10.5px/1 var(--font-mono)', color: 'var(--fg-4)', marginTop: 6, display: 'inline-block' },
  note: { font: '500 11.5px/1.5 var(--font-sans)', color: 'var(--fg-4)', marginTop: 12 },
};

Object.assign(window, { RcvRecoverySection });
