// Canais → Acompanhamento (spec 2026-07-14): filtro de plataforma + KPIs + série + tabela
// metadata-driven (colunas vêm do backend) + export. Self-contained. Uma tela p/ as 4 fontes.

const acFmtDate = (iso) => iso
  ? new Date(iso).toLocaleDateString('pt-BR', { day: '2-digit', month: 'short', year: 'numeric' })
  : '—';
// Busca da tabela: case/acento-insensível, sobre TODAS as colunas (o backend do export
// replica esta regra em _acomp_search_rows — mudou aqui, mude lá).
const acNorm = (v) => String(v).toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '');
const AC_SOURCES = [
  { key: 'logicall', label: 'Logicall' }, { key: 'salesbound', label: 'Salesbound' },
  { key: 'tauk', label: 'Tauk' }, { key: 'direto', label: 'Receita Direta' },
];
const AC_TONE = { blue: 'var(--fenix-blue)', muted: 'var(--fg-3)', neg: 'var(--negative)', orange: 'var(--fenix-orange)' };
const AC_SRC_LABEL = { logicall: 'Logicall', salesbound: 'Salesbound', tauk: 'Tauk', direto: 'Receita Direta' };
const AC_SRC_COLOR = { logicall: '#3B82F6', salesbound: '#8A5BD6', tauk: '#1F9D6B', direto: '#FD7119' };

const AcompanhamentoView = ({ families: appFamilies = [] }) => {
  const [source, setSource] = React.useState('logicall');
  const [period, setPeriod] = React.useState('30d');
  const [customRange, setCustomRange] = React.useState(null);
  const [product, setProduct] = React.useState('todos');
  const [agent, setAgent] = React.useState('todos');
  const [mode, setMode] = React.useState('bruto');
  const [q, setQ] = React.useState('');
  const [sortKey, setSortKey] = React.useState('date');
  const [dir, setDir] = React.useState(-1);
  const [data, setData] = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const fullLoading = useFullLoading();
  const withLoad = (fn) => (...a) => { fullLoading.mark(); fn(...a); };

  // trocar de plataforma reseta produto/agente/modo (nem toda fonte suporta)
  React.useEffect(() => { setProduct('todos'); setAgent('todos'); setMode('bruto'); }, [source]);

  React.useEffect(() => {
    const began = fullLoading.begin();
    let cancelled = false; setLoading(true);
    fetchAcompanhamento({ source, period, product, agent, mode, start: customRange?.start, end: customRange?.end })
      .then(d => { if (!cancelled) { setData(d); setLoading(false); } })
      .catch(() => { if (!cancelled) { setData(null); setLoading(false); } })
      .finally(() => { fullLoading.end(began); });
    return () => { cancelled = true; };
  }, [source, period, product, agent, mode, customRange]);

  const columns = (data && data.columns) || [];
  const rows = (data && data.rows) || [];
  const kpis = (data && data.kpis) || [];
  const supports = (data && data.supports) || { product: false, agent: false };
  const agents = (data && data.agents) || [];
  // Direto: usa famílias do app; demais: as famílias que a fonte devolve.
  const families = source === 'direto' ? appFamilies.map(f => f.name || f) : ((data && data.families) || []);
  const truncated = data && data.truncated;

  const fmtCell = (col, v) => {
    if (col.type === 'date') return acFmtDate(v);
    if (col.type === 'money') return v ? USD(v) : '—';
    if (col.type === 'num') return NUM(v || 0);
    return (v == null || v === '') ? '—' : String(v);
  };
  const fmtKpi = (k) => k.format === 'money' ? USD(k.value) : NUM(k.value);

  const sortBy = (k) => k === sortKey ? setDir(-dir) : (setSortKey(k), setDir(-1));
  const list = React.useMemo(() => {
    let l = rows.slice();
    const s = acNorm(q.trim());
    if (s) l = l.filter(r => columns.some(c => {
      const v = r[c.key];
      if (v == null || v === '') return false;
      return acNorm(v).includes(s) || (c.type === 'date' && acNorm(acFmtDate(v)).includes(s));
    }));
    l.sort((a, b) => {
      const av = a[sortKey], bv = b[sortKey];
      if (av == null && bv == null) return 0;
      if (av == null) return 1; if (bv == null) return -1;
      if (typeof av === 'string') return av.localeCompare(bv) * dir;
      return (av - bv) * dir;
    });
    return l;
  }, [rows, q, sortKey, dir, columns]);

  const ind = (k) => sortKey === k ? (dir < 0 ? ' ▾' : ' ▴') : '';
  const exportUrl = () => acompanhamentoExportUrl({ source, period, product, agent, mode, q: q.trim(), start: customRange?.start, end: customRange?.end });
  const canExport = rows.length > 0;

  return (
    <div style={{ position: 'relative' }}>
      <div style={ac.header}>
        <div>
          <div style={ac.eye}>Canais</div>
          <div style={ac.title}>Acompanhamento</div>
        </div>
        <Segmented value={source} onChange={withLoad(setSource)} options={AC_SOURCES} />
      </div>

      <div style={{ ...ac.kpiRow, gridTemplateColumns: `repeat(${Math.max(kpis.length, 1)},minmax(0,1fr))` }}>
        {kpis.map(k => <DotKpi key={k.label} eye={k.label} color={AC_TONE[k.tone] || 'var(--fenix-blue)'} value={fmtKpi(k)} />)}
      </div>

      <div style={ac.chartCard}>
        <div style={ac.cardEye}>Série temporal · {AC_SRC_LABEL[source]}</div>
        <ChannelChart ch={{ key: 'acomp', available: (data?.series || []).length > 0, series: data?.series || [] }}
          meta={{ label: AC_SRC_LABEL[source], color: AC_SRC_COLOR[source] }} fmtVal={USD} fmtTot={USDk}
          subtitle="Receita líquida no período" granularity={data?.granularity || 'day'} height={220} />
      </div>

      <div style={ac.filterRow}>
        <PeriodSelector period={period} setPeriod={withLoad(setPeriod)} customRange={customRange} setCustomRange={withLoad(setCustomRange)} />
        {supports.product && (
          <Dropdown icon="cart" label="Produto" value={product} onChange={withLoad(setProduct)}
            options={[{ key: 'todos', label: 'Todos' }, ...families.map(f => ({ key: f, label: f }))]} />
        )}
        {supports.mode && (
          <div title="Bruto: funil completo do produto — inclui upsells de outro produto e frete comprados no mesmo funil (bate com o export da plataforma). Filtrado: só pedidos com o nome literal do produto. Com produto 'Todos' as duas visões trazem os mesmos pedidos.">
            <Segmented value={mode} onChange={withLoad(setMode)}
              options={[{ key: 'bruto', label: 'Bruto' }, { key: 'filtrado', label: 'Filtrado' }]} />
          </div>
        )}
        {supports.agent && (
          <Dropdown icon="user" label="Agente" value={agent} onChange={withLoad(setAgent)}
            options={[{ key: 'todos', label: 'Todos' }, ...agents.map(a => ({ key: a.code, label: a.affiliate ? `${a.code} · ${a.affiliate}` : a.code }))]} />
        )}
        <div style={ac.search}>
          <Icon name="search" size={15} color="var(--fg-3)" />
          <input value={q} onChange={e => setQ(e.target.value)} placeholder="Buscar na tabela…" style={ac.searchInput} />
        </div>
        {/* download via fetch autenticado — window.open não manda o Bearer (spec 2026-08-05) */}
        <button onClick={() => canExport && window.FenixAuth.download(exportUrl()).catch(e=>alert(e.message))}
          title={canExport ? 'Baixar xlsx dos pedidos filtrados' : 'Sem dados para exportar'}
          style={{ ...ac.exportBtn, ...(canExport ? {} : { opacity: .45, cursor: 'default' }) }}
          onMouseEnter={e => { if (canExport) { e.currentTarget.style.borderColor = 'var(--fenix-orange)'; e.currentTarget.style.color = 'var(--fenix-orange)'; } }}
          onMouseLeave={e => { e.currentTarget.style.borderColor = 'var(--border-2)'; e.currentTarget.style.color = 'var(--fg-2)'; }}>
          <Icon name="download" size={15} color="currentColor" /> Baixar relatório
        </button>
      </div>

      {truncated && (
        <div style={ac.notice}><Icon name="alert" size={14} color="currentColor" />
          Mostrando os 1.000 pedidos mais recentes — refine o período ou o produto. O export traz o que está na tela.</div>
      )}

      <div style={ac.wrap}>
        <div style={ac.scroll}>
          <table style={ac.table}>
            <thead><tr>
              {columns.map(c => (
                <th key={c.key} onClick={() => sortBy(c.key)} style={{ ...ac.th, textAlign: c.align || 'left' }}>{c.label}{ind(c.key)}</th>
              ))}
            </tr></thead>
            <tbody>
              {list.map((r, i) => (
                <tr key={r.orderId || i}
                  onMouseEnter={e => { e.currentTarget.style.background = 'var(--gray-50)'; }}
                  onMouseLeave={e => { e.currentTarget.style.background = 'transparent'; }}>
                  {columns.map(c => (
                    <td key={c.key} style={{
                      ...ac.td, textAlign: c.align || 'left',
                      ...(c.type === 'mono' ? { font: '500 12px/1 var(--font-mono)', color: 'var(--fg-2)' } : {}),
                      ...(c.type === 'money' ? { fontWeight: c.key === 'gross' ? 700 : 400 } : {}),
                      // longhands DEPOIS do shorthand `font:` do ac.td — inline vence a classe .fenix-num
                      ...(c.type === 'money' || c.type === 'num' || c.type === 'date'
                        ? { fontFamily: 'var(--font-num)', fontVariantNumeric: 'tabular-nums' } : {}),
                    }} className={c.type === 'money' || c.type === 'num' || c.type === 'date' ? 'fenix-num' : undefined}>
                      {c.type === 'badge'
                        ? <span style={ac.badge}>{fmtCell(c, r[c.key])}</span>
                        : fmtCell(c, r[c.key])}
                    </td>
                  ))}
                </tr>
              ))}
              {!loading && list.length === 0 && (
                <tr><td colSpan={Math.max(columns.length, 1)} style={ac.empty}>
                  {q ? 'Nenhum pedido casa com a busca.' : 'Sem pedidos no período.'}
                </td></tr>
              )}
            </tbody>
          </table>
        </div>
      </div>
      <FullLoadingOverlay show={fullLoading.show && !!data} conn="connecting"/>
    </div>
  );
};

const ac = {
  header: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 16, marginBottom: 16, flexWrap: 'wrap' },
  eye: { font: 'var(--text-label)', letterSpacing: '.05em', textTransform: 'uppercase', color: 'var(--fg-3)' },
  title: { font: '800 22px/1.1 var(--font-sans)', color: 'var(--fg-1)', letterSpacing: '-.01em', marginTop: 4 },
  kpiRow: { display: 'grid', gap: 14, marginBottom: 16 },
  chartCard: { background: '#fff', border: '1px solid var(--border-1)', borderRadius: 'var(--r-lg)', boxShadow: 'var(--shadow-sm)', padding: '16px 20px 8px', marginBottom: 16 },
  cardEye: { font: 'var(--text-label)', letterSpacing: '.05em', textTransform: 'uppercase', color: 'var(--fg-3)', marginBottom: 4 },
  filterRow: { display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap', marginBottom: 16 },
  search: { display: 'flex', alignItems: 'center', gap: 8, border: '1px solid var(--border-2)', borderRadius: 'var(--r-md)', padding: '8px 12px', width: 230 },
  searchInput: { border: 0, outline: 0, font: 'var(--text-body-sm)', color: 'var(--fg-1)', flex: 1, background: 'transparent' },
  exportBtn: { display: 'inline-flex', alignItems: 'center', gap: 7, border: '1px solid var(--border-2)', borderRadius: 'var(--r-md)', padding: '8px 13px', background: '#fff', color: 'var(--fg-2)', font: '600 12px/1 var(--font-sans)', cursor: 'pointer', transition: 'border-color .15s, color .15s', whiteSpace: 'nowrap' },
  notice: { display: 'flex', alignItems: 'center', gap: 6, font: '600 12px/1.4 var(--font-sans)', color: 'var(--warning)', background: 'var(--warning-bg)', padding: '10px 16px', borderRadius: 'var(--r-md)', marginBottom: 12 },
  wrap: { background: '#fff', border: '1px solid var(--border-1)', borderRadius: 'var(--r-lg)', boxShadow: 'var(--shadow-sm)', overflow: 'hidden' },
  scroll: { maxHeight: 600, overflowY: 'auto', overflowX: 'auto' },
  table: { width: '100%', borderCollapse: 'collapse', minWidth: 1080 },
  th: { font: '700 10.5px/1 var(--font-sans)', letterSpacing: '.04em', textTransform: 'uppercase', color: 'var(--fg-3)', padding: '12px 14px', background: 'var(--bg-sunken)', borderBottom: '1px solid var(--border-2)', whiteSpace: 'nowrap', userSelect: 'none', cursor: 'pointer', position: 'sticky', top: 0, zIndex: 2 },
  td: { padding: '11px 14px', borderBottom: '1px solid var(--border-1)', font: 'var(--text-body-sm)', color: 'var(--fg-1)', whiteSpace: 'nowrap' },
  badge: { font: '700 11px/1 var(--font-sans)', padding: '5px 10px', borderRadius: 'var(--r-pill)', background: 'var(--fenix-blue-100, #E3EEFC)', color: 'var(--fenix-blue, #3B82F6)', whiteSpace: 'nowrap' },
  empty: { padding: '34px 22px', textAlign: 'center', font: 'var(--text-body-sm)', color: 'var(--fg-4)' },
};

window.AcompanhamentoView = AcompanhamentoView;
