/* screen_comercial_previsao_vendas.jsx — Previsão de Vendas · Consumíveis
 * Mapa Previsto vs. Realizado: BP + RPC + Primavera
 * Data: comercial_bp_targets + rpc_encomendas + comercial_ytd_snap
 * Todos os helpers prefixados com PV_ para evitar conflitos Babel eval() scope.
 */

const PV_MESES = ['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'];

const PV_EQUIPAS = [
  { id: null,          label: 'Todas' },
  { id: 'equip',       label: 'Mimaki PT' },
  { id: 'mimaki_gc',   label: 'Mimaki GC' },
  { id: 'mimaki_es',   label: 'Mimaki ES Dim' },
  { id: 'mimaki_tec',  label: 'Mimaki TEC PT' },
  { id: 'export',      label: 'Decal EX' },
  { id: 'cons_pt',     label: 'Decal PT' },
  { id: 'decal_es',    label: 'Decal ES Dim' },
  { id: 'decal_sk',    label: 'Decal SK' },
  { id: 'sede',        label: 'Sede' },
];

const PV_TENANTS = [
  { id: 'pt', label: 'Digidelta PT' },
  { id: 'es', label: 'Dimensión ES' },
];

// Mapeamento equipa → tipo de mapa RPC + empresa BD + tenant FM
const PV_EQUIPA_CONFIG = {
  equip:      { type: 'equip', empresa: 'PTDIG',     fmEmpresa: 'PTDIG'  },
  mimaki_gc:  { type: 'equip', empresa: 'MIMAKI_GC', fmEmpresa: 'PTDIG'  },
  mimaki_es:  { type: 'equip', empresa: 'MIMAKI_ES', fmEmpresa: 'DIGES'  },
  mimaki_tec: { type: 'equip', empresa: 'PTDIG',     fmEmpresa: 'PTDIG'  },
  cons_pt:    { type: 'cons',  empresa: 'DECAL_PT',  fmEmpresa: 'PTDIG'  },
  export:     { type: 'cons',  empresa: 'DECAL_EX',  fmEmpresa: 'PTDIG'  },
  decal_es:   { type: 'cons',  empresa: 'DECAL_ES',  fmEmpresa: 'DIGES'  },
  decal_sk:   { type: 'cons',  empresa: 'DECAL_SK',  fmEmpresa: 'PTDIG'  },
  sede:       { type: 'equip', empresa: 'PTDIG',     fmEmpresa: 'PTDIG'  },
};

// Gestora do briefing de equipa (bloco 1), por separador da Previsão
const PV_EQUIPA_MANAGER = {
  equip:   86, // Gonçalo Penha — Mimaki PT
  cons_pt: 62, // Cláudia Monteiro — Decal PT
  export:  47, // António Costa — Decal EX
};

const PV_eur = (v, decimals = 0) => {
  if (v == null || isNaN(v)) return '—';
  return new Intl.NumberFormat('pt-PT', { style: 'currency', currency: 'EUR', maximumFractionDigits: decimals, minimumFractionDigits: decimals }).format(v);
};

const PV_k = (v) => {
  if (v == null || isNaN(v)) return '—';
  return Math.round(v / 1000) + 'k€';
};

const PV_pct = (v) => v == null ? '—' : v.toFixed(1) + '%';

const PV_desvColor = (v) => {
  if (v == null) return {};
  if (v > 0) return { color: 'var(--dgd-green-500, #16a34a)' };
  if (v < 0) return { color: 'var(--dgd-red-500, #dc2626)' };
  return {};
};

// ── KPI card ────────────────────────────────────────────────────────────────
const PVKpiCard = ({ label, value, sub, accent }) => (
  <div style={{
    background: 'var(--dgd-bg-surface)', border: '1px solid var(--dgd-border-1)',
    borderRadius: 12, padding: '14px 16px', display: 'flex', flexDirection: 'column', gap: 4,
  }}>
    <span style={{ fontSize: 10, letterSpacing: '0.12em', textTransform: 'uppercase', color: 'var(--dgd-fg-3)', fontWeight: 600 }}>{label}</span>
    <span style={{ fontSize: 22, fontWeight: 700, color: accent || 'var(--dgd-fg-1)', fontVariantNumeric: 'tabular-nums' }}>{value}</span>
    {sub && <span style={{ fontSize: 11.5, color: 'var(--dgd-fg-3)' }}>{sub}</span>}
  </div>
);

// ── Card wrapper ─────────────────────────────────────────────────────────────
const PVCard = ({ title, children }) => (
  <div style={{ background: 'var(--dgd-bg-surface)', border: '1px solid var(--dgd-border-1)', borderRadius: 14, overflow: 'hidden' }}>
    {title && <div style={{ fontSize: 10.5, letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--dgd-fg-3)', fontWeight: 600, padding: '14px 18px 0' }}>{title}</div>}
    {children}
  </div>
);

// ── Tabela mensal por comercial ──────────────────────────────────────────────
const PVTabelaMes = ({ comerciais }) => {
  const totBP  = comerciais.reduce((s, c) => s + (c.bp  || 0), 0);
  const totRPC = comerciais.reduce((s, c) => s + (c.rpc || 0), 0);
  const totFat = comerciais.reduce((s, c) => s + (c.fat || 0), 0);
  const totMar = comerciais.reduce((s, c) => s + (c.margem || 0), 0);
  const totMarPct = totFat > 0 ? Math.round((totMar / totFat) * 1000) / 10 : null;

  const thBase = { padding: '8px 10px', fontSize: 11.5, fontWeight: 600, color: 'var(--dgd-fg-3)', borderBottom: '1px solid var(--dgd-border-1)', whiteSpace: 'nowrap' };
  const tdBase = { padding: '8px 10px', fontSize: 12.5, fontVariantNumeric: 'tabular-nums', whiteSpace: 'nowrap', borderBottom: '1px solid color-mix(in oklch, var(--dgd-border-1) 50%, transparent)' };

  return (
    <div style={{ overflowX: 'auto', padding: '6px 0 12px' }}>
      <table style={{ borderCollapse: 'collapse', width: '100%', minWidth: 700 }}>
        <thead>
          <tr>
            <th style={{ ...thBase, textAlign: 'left' }}>ID</th>
            <th style={{ ...thBase, textAlign: 'left' }}>Comercial</th>
            <th style={{ ...thBase, textAlign: 'right', color: 'var(--dgd-purple-500, #7c3aed)' }}>Obj. BP</th>
            <th style={{ ...thBase, textAlign: 'right', color: 'var(--dgd-primary-500)', borderLeft: '1px solid var(--dgd-border-1)' }}>Previsão RPC ¹</th>
            <th style={{ ...thBase, textAlign: 'right' }}>Desvio Prev−BP</th>
            <th style={{ ...thBase, textAlign: 'right' }}>Faturado</th>
            <th style={{ ...thBase, textAlign: 'right' }}>Margem</th>
          </tr>
        </thead>
        <tbody>
          {comerciais.map(c => {
            const desv = c.bp != null && c.rpc != null ? c.rpc - c.bp : null;
            return (
              <tr key={c.id}>
                <td style={{ ...tdBase, textAlign: 'left', color: 'var(--dgd-fg-3)', width: 48 }}>{c.id}</td>
                <td style={{ ...tdBase, textAlign: 'left', fontWeight: 600, minWidth: 160, position: 'sticky', left: 0, background: 'var(--dgd-bg-surface)' }}>{c.nome}</td>
                <td style={{ ...tdBase, textAlign: 'right', color: 'var(--dgd-purple-500, #7c3aed)', background: 'color-mix(in oklch, var(--dgd-purple-500, #7c3aed) 6%, transparent)', fontWeight: 500 }}>{PV_eur(c.bp)}</td>
                <td style={{ ...tdBase, textAlign: 'right', color: 'var(--dgd-primary-500)', fontWeight: 600, borderLeft: '1px solid var(--dgd-border-1)' }}>{PV_eur(c.rpc)}</td>
                <td style={{ ...tdBase, textAlign: 'right', ...PV_desvColor(desv) }}>
                  {desv == null ? '—' : (desv > 0 ? '+' : '') + PV_eur(desv)}
                </td>
                <td style={{ ...tdBase, textAlign: 'right', fontWeight: c.fat != null ? 600 : 400, color: c.fat != null && c.fat < 0 ? 'var(--dgd-red-500, #dc2626)' : 'var(--dgd-fg-1)' }}>{PV_eur(c.fat)}</td>
                <td style={{ ...tdBase, textAlign: 'right' }}>{c.margem_pct != null ? PV_pct(c.margem_pct) : '—'}</td>
              </tr>
            );
          })}
        </tbody>
        <tfoot>
          <tr>
            <td style={{ ...tdBase, textAlign: 'left', borderTop: '1px solid var(--dgd-border-1)', borderBottom: 'none' }} />
            <td style={{ ...tdBase, textAlign: 'left', fontWeight: 700, borderTop: '1px solid var(--dgd-border-1)', borderBottom: 'none' }}>Total</td>
            <td style={{ ...tdBase, textAlign: 'right', color: 'var(--dgd-purple-500, #7c3aed)', background: 'color-mix(in oklch, var(--dgd-purple-500, #7c3aed) 6%, transparent)', fontWeight: 700, borderTop: '1px solid var(--dgd-border-1)', borderBottom: 'none' }}>{PV_eur(totBP)}</td>
            <td style={{ ...tdBase, textAlign: 'right', color: 'var(--dgd-primary-500)', fontWeight: 700, borderLeft: '1px solid var(--dgd-border-1)', borderTop: '1px solid var(--dgd-border-1)', borderBottom: 'none' }}>{PV_eur(totRPC)}</td>
            <td style={{ ...tdBase, textAlign: 'right', fontWeight: 700, borderTop: '1px solid var(--dgd-border-1)', borderBottom: 'none', ...PV_desvColor(totRPC - totBP) }}>{totRPC && totBP ? (totRPC - totBP > 0 ? '+' : '') + PV_eur(totRPC - totBP) : '—'}</td>
            <td style={{ ...tdBase, textAlign: 'right', fontWeight: 700, borderTop: '1px solid var(--dgd-border-1)', borderBottom: 'none' }}>{PV_eur(totFat)}</td>
            <td style={{ ...tdBase, textAlign: 'right', fontWeight: 700, borderTop: '1px solid var(--dgd-border-1)', borderBottom: 'none' }}>{PV_pct(totMarPct)}</td>
          </tr>
        </tfoot>
      </table>
    </div>
  );
};

// ── Grelha anual ────────────────────────────────────────────────────────────
const PVGrelhaAnual = ({ annual }) => {
  const pvRows = [
    { label: 'Objectivo BP', key: 'bp', color: 'var(--dgd-purple-500, #7c3aed)', bg: 'color-mix(in oklch, var(--dgd-purple-500, #7c3aed) 6%, transparent)' },
    { label: 'Previsão RPC ¹', key: 'rpc', color: 'var(--dgd-primary-500)', forecast: true },
    { label: 'Vendas Fact.', key: 'fat', bold: true },
    { label: 'Desvio Acum. vs BP', key: 'desvio_acum', delta: true },
  ];

  const pvFiab = annual.map(m => {
    if (!m.fechado || !m.rpc || m.rpc === 0) return null;
    return Math.round((m.fat / m.rpc) * 1000) / 10;
  });

  const pvYtd = (key) => {
    const sum = annual.filter(m => m.fechado).reduce((s, m) => s + (m[key] || 0), 0);
    return sum !== 0 ? sum : null;
  };

  const pvYtdFiab = (() => {
    const sumFat = annual.filter(m => m.fechado && m.rpc > 0).reduce((s, m) => s + (m.fat || 0), 0);
    const sumRpc = annual.filter(m => m.fechado && m.rpc > 0).reduce((s, m) => s + (m.rpc || 0), 0);
    return sumRpc > 0 ? Math.round(sumFat / sumRpc * 1000) / 10 : null;
  })();

  const pvThStyle = (m) => ({
    padding: '7px 8px', fontSize: 11, fontWeight: 600,
    color: m.atual ? 'var(--dgd-primary-500)' : m.fechado ? 'var(--dgd-fg-2)' : 'var(--dgd-fg-3)',
    textAlign: 'right', whiteSpace: 'nowrap', borderBottom: '1px solid var(--dgd-border-1)',
    background: m.atual ? 'color-mix(in oklch, var(--dgd-primary-500) 8%, var(--dgd-bg-surface))' : 'var(--dgd-bg-surface)',
  });

  const pvCellStyle = (m, row) => {
    const isFut = !m.fechado && !m.atual;
    const isActual = m.atual;
    return {
      padding: '7px 8px', textAlign: 'right', fontSize: 12, fontVariantNumeric: 'tabular-nums',
      whiteSpace: 'nowrap',
      fontWeight: row.bold || isActual ? 600 : 400,
      background: isActual ? 'color-mix(in oklch, var(--dgd-primary-500) 6%, transparent)' : 'transparent',
      borderBottom: '1px solid color-mix(in oklch, var(--dgd-border-1) 50%, transparent)',
    };
  };

  const pvRenderVal = (row, m) => {
    const v = m[row.key];
    if (row.delta) {
      if (v == null) return <span style={{ color: 'var(--dgd-fg-3)' }}>—</span>;
      const s = { color: v < 0 ? 'var(--dgd-red-500, #dc2626)' : v > 0 ? 'var(--dgd-green-500, #16a34a)' : 'var(--dgd-fg-3)' };
      return <span style={s}>{(v > 0 ? '+' : '') + PV_k(v)}</span>;
    }
    if (!m.fechado && !m.atual && row.key === 'fat') {
      return m.rpc != null ? <span style={{ color: 'var(--dgd-fg-3)', fontStyle: 'italic' }}>{PV_k(m.rpc)}</span> : <span style={{ color: 'var(--dgd-fg-3)' }}>—</span>;
    }
    const color = row.key === 'rpc' && (!m.fechado) ? 'var(--dgd-primary-500)' : (row.color && m.fechado ? row.color : 'var(--dgd-fg-1)');
    const isFut = !m.fechado && !m.atual;
    return <span style={{ color: isFut && row.key !== 'rpc' ? 'var(--dgd-fg-3)' : color }}>{PV_k(v)}</span>;
  };

  return (
    <div style={{ overflowX: 'auto', padding: '6px 0 12px' }}>
      <table style={{ borderCollapse: 'collapse', width: '100%', minWidth: 1100 }}>
        <thead>
          <tr>
            <th style={{ padding: '7px 10px', textAlign: 'left', fontSize: 11, color: 'var(--dgd-fg-3)', borderBottom: '1px solid var(--dgd-border-1)', minWidth: 170, position: 'sticky', left: 0, background: 'var(--dgd-bg-surface)' }}>— valores em k€</th>
            {annual.map(m => (
              <th key={m.mes} style={pvThStyle(m)}>{m.label}</th>
            ))}
            <th style={{ ...pvThStyle({ fechado: false, atual: false }), borderLeft: '1px solid var(--dgd-border-1)' }}>YTD</th>
            <th style={pvThStyle({ fechado: false, atual: false })}>Ano</th>
          </tr>
        </thead>
        <tbody>
          {pvRows.map(row => (
            <tr key={row.key}>
              <td style={{ padding: '7px 10px', textAlign: 'left', fontSize: 12.5, fontWeight: row.bold ? 600 : 400, position: 'sticky', left: 0, background: 'var(--dgd-bg-surface)', color: row.color || 'var(--dgd-fg-1)', borderBottom: '1px solid color-mix(in oklch, var(--dgd-border-1) 50%, transparent)' }}>
                {row.label}
              </td>
              {annual.map(m => (
                <td key={m.mes} style={pvCellStyle(m, row)}>
                  {pvRenderVal(row, m)}
                </td>
              ))}
              <td style={{ padding: '7px 8px', textAlign: 'right', fontSize: 12, fontWeight: 700, fontVariantNumeric: 'tabular-nums', borderLeft: '1px solid var(--dgd-border-1)', borderBottom: '1px solid color-mix(in oklch, var(--dgd-border-1) 50%, transparent)' }}>
                {row.delta
                  ? (() => { const v = pvYtd('desvio_acum'); return v != null ? <span style={{ color: v < 0 ? 'var(--dgd-red-500, #dc2626)' : 'var(--dgd-green-500, #16a34a)' }}>{(v > 0 ? '+' : '') + PV_k(v)}</span> : '—'; })()
                  : PV_k(pvYtd(row.key))}
              </td>
              <td style={{ padding: '7px 8px', textAlign: 'right', fontSize: 12, color: 'var(--dgd-fg-3)', borderBottom: '1px solid color-mix(in oklch, var(--dgd-border-1) 50%, transparent)' }}>—</td>
            </tr>
          ))}
          <tr>
            <td style={{ padding: '7px 10px', textAlign: 'left', fontSize: 12.5, position: 'sticky', left: 0, background: 'var(--dgd-bg-surface)', color: 'var(--dgd-fg-1)', borderBottom: '1px solid color-mix(in oklch, var(--dgd-border-1) 50%, transparent)' }}>Fiabilidade Previsão ²</td>
            {annual.map((m, i) => {
              const v = pvFiab[i];
              const fiabColor = v == null ? {} : v >= 97 ? { color: 'var(--dgd-green-500, #16a34a)' } : v < 90 ? { color: 'var(--dgd-red-500, #dc2626)' } : { color: 'var(--dgd-amber-500, #d97706)' };
              return (
                <td key={m.mes} style={{ padding: '7px 8px', textAlign: 'right', fontSize: 12, fontVariantNumeric: 'tabular-nums', fontWeight: m.fechado ? 600 : 400, borderBottom: '1px solid color-mix(in oklch, var(--dgd-border-1) 50%, transparent)', ...fiabColor }}>
                  {v != null ? PV_pct(v) : <span style={{ color: 'var(--dgd-fg-3)' }}>—</span>}
                </td>
              );
            })}
            <td style={{ padding: '7px 8px', textAlign: 'right', fontSize: 12, fontWeight: 700, borderLeft: '1px solid var(--dgd-border-1)', borderBottom: '1px solid color-mix(in oklch, var(--dgd-border-1) 50%, transparent)', color: pvYtdFiab != null && pvYtdFiab >= 97 ? 'var(--dgd-green-500, #16a34a)' : 'var(--dgd-fg-1)' }}>
              {pvYtdFiab != null ? PV_pct(pvYtdFiab) : '—'}
            </td>
            <td style={{ padding: '7px 8px', textAlign: 'right', fontSize: 12, color: 'var(--dgd-fg-3)', borderBottom: '1px solid color-mix(in oklch, var(--dgd-border-1) 50%, transparent)' }}>—</td>
          </tr>
        </tbody>
      </table>
    </div>
  );
};

// ── Tabela Ibéria (vista "Todos") ────────────────────────────────────────────
const PVTabelaIberia = ({ linhas, ano, totalLabel = 'Total Ibéria', antLabel }) => {
  const anoAnt = ano - 1;
  const colAntLabel = antLabel || String(anoAnt);

  const thS = { padding: '8px 10px', fontSize: 11, fontWeight: 600, color: 'var(--dgd-fg-3)', borderBottom: '1px solid var(--dgd-border-1)', whiteSpace: 'nowrap', textAlign: 'right' };
  const thL = { ...thS, textAlign: 'left' };
  const tdS = { padding: '7px 10px', fontSize: 12, fontVariantNumeric: 'tabular-nums', whiteSpace: 'nowrap', textAlign: 'right', borderBottom: '1px solid color-mix(in oklch, var(--dgd-border-1) 50%, transparent)' };
  const tdL = { ...tdS, textAlign: 'left' };

  const marcas = [...new Set(linhas.map(l => l.marca))];

  const totalize = (rows) => ({
    fat_ant:       rows.reduce((s, r) => s + r.fat_ant, 0),
    fat_atual:     rows.reduce((s, r) => s + r.fat_atual, 0),
    margem_ant:    rows.reduce((s, r) => s + r.margem_ant, 0),
    margem_atual:  rows.reduce((s, r) => s + r.margem_atual, 0),
    bp:            rows.reduce((s, r) => s + r.bp, 0),
    bp_ytd:        rows.reduce((s, r) => s + r.bp_ytd, 0),
    get desvio()   { return this.fat_atual - this.bp; },
    get desvio_ytd() { return this.fat_atual - this.bp_ytd; },
    get margem_pct_ant()   { return this.fat_ant   > 0 ? (this.margem_ant   / this.fat_ant)   * 100 : null; },
    get margem_pct_atual() { return this.fat_atual > 0 ? (this.margem_atual / this.fat_atual) * 100 : null; },
  });

  const grand = totalize(linhas);

  const renderDesv = (v) => {
    if (v == null) return <span style={{ color: 'var(--dgd-fg-3)' }}>—</span>;
    const col = v > 0 ? 'var(--dgd-green-500,#16a34a)' : v < 0 ? 'var(--dgd-red-500,#dc2626)' : 'var(--dgd-fg-3)';
    return <span style={{ color: col }}>{(v > 0 ? '+' : '') + PV_eur(v)}</span>;
  };

  const renderRow = (row, isSubrow) => (
    <tr key={row.label}>
      <td style={{ ...tdL, paddingLeft: isSubrow ? 28 : 12, fontWeight: isSubrow ? 400 : 700, color: isSubrow ? 'var(--dgd-fg-1)' : 'var(--dgd-fg-2)' }}>{row.label}</td>
      <td style={tdS}>{PV_eur(row.fat_ant)}</td>
      <td style={{ ...tdS, fontWeight: 600 }}>{PV_eur(row.fat_atual)}</td>
      <td style={{ ...tdS, color: 'var(--dgd-purple-500,#7c3aed)' }}>{PV_eur(row.bp_ytd)}</td>
      <td style={tdS}>{renderDesv(row.desvio_ytd)}</td>
      <td style={tdS}>{PV_eur(row.margem_ant)}</td>
      <td style={{ ...tdS, fontWeight: 600 }}>{PV_eur(row.margem_atual)}</td>
      <td style={tdS}>{row.margem_pct_ant != null ? PV_pct(row.margem_pct_ant) : '—'}</td>
      <td style={{ ...tdS, fontWeight: 600 }}>{row.margem_pct_atual != null ? PV_pct(row.margem_pct_atual) : '—'}</td>
    </tr>
  );

  const grpHdrStyle = { background: 'color-mix(in oklch, var(--dgd-border-1) 60%, transparent)' };

  return (
    <div style={{ overflowX: 'auto', padding: '6px 0 12px' }}>
      <table style={{ borderCollapse: 'collapse', width: '100%', minWidth: 900 }}>
        <thead>
          <tr>
            <th style={{ ...thL, minWidth: 140 }} rowSpan={2}>Equipa</th>
            <th style={{ ...thS, borderLeft: '1px solid var(--dgd-border-1)' }} colSpan={2}>Valor Líquido</th>
            <th style={{ ...thS, borderLeft: '1px solid var(--dgd-border-1)' }} colSpan={2}>BP</th>
            <th style={{ ...thS, borderLeft: '1px solid var(--dgd-border-1)' }} colSpan={2}>Valor Margem</th>
            <th style={{ ...thS, borderLeft: '1px solid var(--dgd-border-1)' }} colSpan={2}>% Margem</th>
          </tr>
          <tr>
            <th style={{ ...thS, borderLeft: '1px solid var(--dgd-border-1)' }}>{colAntLabel}</th>
            <th style={thS}>{ano}</th>
            <th style={{ ...thS, borderLeft: '1px solid var(--dgd-border-1)', color: 'var(--dgd-purple-500,#7c3aed)' }}>BP</th>
            <th style={thS}>Desvio</th>
            <th style={{ ...thS, borderLeft: '1px solid var(--dgd-border-1)' }}>{colAntLabel}</th>
            <th style={thS}>{ano}</th>
            <th style={{ ...thS, borderLeft: '1px solid var(--dgd-border-1)' }}>{colAntLabel}</th>
            <th style={thS}>{ano}</th>
          </tr>
        </thead>
        <tbody>
          {marcas.map(marca => {
            const rows = linhas.filter(l => l.marca === marca);
            const tot  = totalize(rows);
            return (
              <React.Fragment key={marca}>
                <tr style={grpHdrStyle}>
                  <td colSpan={9} style={{ padding: '5px 12px', fontSize: 11, fontWeight: 700, letterSpacing: '0.1em', textTransform: 'uppercase', color: 'var(--dgd-fg-2)' }}>{marca}</td>
                </tr>
                {renderRow({ ...tot, label: marca + ' Total' }, false)}
                {rows.map(r => renderRow(r, true))}
              </React.Fragment>
            );
          })}
        </tbody>
        <tfoot>
          <tr style={{ borderTop: '2px solid var(--dgd-border-1)' }}>
            <td style={{ ...tdL, fontWeight: 700, fontSize: 12.5 }}>{totalLabel}</td>
            <td style={{ ...tdS, fontWeight: 700 }}>{PV_eur(grand.fat_ant)}</td>
            <td style={{ ...tdS, fontWeight: 700 }}>{PV_eur(grand.fat_atual)}</td>
            <td style={{ ...tdS, fontWeight: 700, color: 'var(--dgd-purple-500,#7c3aed)' }}>{PV_eur(grand.bp_ytd)}</td>
            <td style={{ ...tdS, fontWeight: 700 }}>{renderDesv(grand.desvio_ytd)}</td>
            <td style={{ ...tdS, fontWeight: 700 }}>{PV_eur(grand.margem_ant)}</td>
            <td style={{ ...tdS, fontWeight: 700 }}>{PV_eur(grand.margem_atual)}</td>
            <td style={{ ...tdS, fontWeight: 700 }}>{grand.margem_pct_ant != null ? PV_pct(grand.margem_pct_ant) : '—'}</td>
            <td style={{ ...tdS, fontWeight: 700 }}>{grand.margem_pct_atual != null ? PV_pct(grand.margem_pct_atual) : '—'}</td>
          </tr>
        </tfoot>
      </table>
    </div>
  );
};

// ── Selector de período ──────────────────────────────────────────────────────
const PV_MODOS = [
  { id: 'ytd',   label: 'YTD'   },
  { id: 'total', label: 'Total' },
  { id: 'mensal',label: 'Mensal'},
  { id: 'q1',    label: 'Q1'    },
  { id: 'q2',    label: 'Q2'    },
  { id: 'q3',    label: 'Q3'    },
  { id: 'q4',    label: 'Q4'    },
];

const PVPeriodSel = ({ ano, mes, modo, onChange }) => {
  const pvNow  = new Date();
  const pvAnos = [pvNow.getFullYear() - 1, pvNow.getFullYear()];
  const selSt  = { height: 30, padding: '0 8px', borderRadius: 6, border: '1px solid var(--dgd-border-1)', background: 'var(--dgd-bg-surface)', color: 'var(--dgd-fg-1)', fontSize: 12 };
  const mBtnSt = (active) => ({
    padding: '4px 9px', borderRadius: 6, fontSize: 11.5, fontWeight: 600, cursor: 'pointer', border: 'none', lineHeight: 1,
    background: active ? 'var(--dgd-primary-500)' : 'transparent',
    color: active ? '#fff' : 'var(--dgd-fg-2)',
    transition: 'all .15s',
  });
  const showMes = modo === 'ytd' || modo === 'mensal';
  return (
    <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
      <select value={ano} onChange={e => onChange(parseInt(e.target.value), mes, modo)} style={selSt}>
        {pvAnos.map(y => <option key={y} value={y}>{y}</option>)}
      </select>
      <div style={{ display: 'flex', gap: 2, background: 'var(--dgd-bg-surface)', borderRadius: 8, padding: '3px 4px', boxShadow: '0 0 0 1px var(--dgd-border-1)' }}>
        {PV_MODOS.map(m => (
          <button key={m.id} style={mBtnSt(modo === m.id)} onClick={() => onChange(ano, mes, m.id)}>
            {m.label}
          </button>
        ))}
      </div>
      {showMes && (
        <select value={mes} onChange={e => onChange(ano, parseInt(e.target.value), modo)} style={selSt}>
          {PV_MESES.map((m, i) => <option key={i + 1} value={i + 1}>{m}</option>)}
        </select>
      )}
    </div>
  );
};

// ── Bloco 2 do briefing diário — pipeline · só comercial equip seleccionado ──
const PVBriefBloco2 = ({ vendedorId }) => {
  const [state, setState] = React.useState({ brief: null, loading: true });
  React.useEffect(() => {
    setState({ brief: null, loading: true });
    fetch(`/api/comercial/brief/${encodeURIComponent(vendedorId)}?somente_cache=1`)
      .then(r => r.ok ? r.json() : Promise.reject())
      .then(d => setState({ brief: d.brief, loading: false }))
      .catch(() => setState({ brief: null, loading: false }));
  }, [vendedorId]);

  const MONO = { fontFamily: 'var(--dgd-font-mono, monospace)', letterSpacing: '0.13em', textTransform: 'uppercase', fontWeight: 600 };
  const BODY = { fontFamily: 'var(--dgd-font-body, sans-serif)', lineHeight: 1.6 };
  const mdBold = t => {
    if (!t || typeof t !== 'string' || !t.includes('**')) return t;
    return t.split(/\*\*(.+?)\*\*/g).map((p, i) => i % 2 === 1 ? React.createElement('b', { key: i, style: { fontWeight: 600 } }, p) : p);
  };
  const PVQuadro = ({ titulo, colunas, linhas }) => {
    if (!colunas?.length || !linhas?.length) return null;
    return (
      <div>
        {titulo && <div style={{ ...MONO, fontSize: 10, color: 'var(--dgd-fg-3)', margin: '8px 18px 6px' }}>{titulo}</div>}
        <div style={{ overflowX: 'auto', padding: '0 10px 14px' }}>
          <table style={{ borderCollapse: 'collapse', width: '100%', fontFamily: 'var(--dgd-font-mono, monospace)', fontSize: 12.5 }}>
            <thead>
              <tr>{colunas.map((c, i) => (
                <th key={i} style={{ padding: '8px 10px', textAlign: i === 0 || c === 'Leitura' ? 'left' : 'right', whiteSpace: 'nowrap', borderBottom: '1px solid var(--dgd-border, #e2e6ea)', color: 'var(--dgd-fg-3)', fontSize: 11, fontWeight: 600 }}>{c}</th>
              ))}</tr>
            </thead>
            <tbody>
              {linhas.map((row, ri) => (
                <tr key={ri}>
                  {(row.valores || []).map((v, vi) => (
                    <td key={vi} style={{ padding: '8px 10px', textAlign: vi === 0 ? 'left' : 'right', whiteSpace: 'nowrap', borderBottom: ri < linhas.length - 1 ? '1px solid color-mix(in oklch, var(--dgd-border) 50%, transparent)' : 'none', fontWeight: vi === 0 ? 600 : 400, color: String(v).startsWith('+') ? 'var(--dgd-green-700)' : String(v).startsWith('-') || String(v).startsWith('−') ? 'var(--dgd-red-700)' : 'var(--dgd-fg-1)' }}>{v}</td>
                  ))}
                  {row.leitura && <td style={{ padding: '8px 10px', textAlign: 'left', whiteSpace: 'normal', ...BODY, fontSize: 13, minWidth: 260, color: 'var(--dgd-fg-2)', borderBottom: ri < linhas.length - 1 ? '1px solid color-mix(in oklch, var(--dgd-border) 50%, transparent)' : 'none' }}>{row.leitura}</td>}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    );
  };

  if (state.loading) return <div style={{ padding: '12px 18px', fontSize: 12, color: 'var(--dgd-fg-3)' }}>A carregar briefing…</div>;
  const b2 = state.brief?.bloco2;
  if (!b2) return <div style={{ padding: '12px 18px 14px', fontSize: 12, color: 'var(--dgd-fg-3)', fontStyle: 'italic' }}>Sem briefing de hoje para este comercial.</div>;

  return (
    <div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '14px 18px 0' }}>
        <div style={{ width: 24, height: 24, borderRadius: 7, background: 'color-mix(in oklch, var(--dgd-primary-500,#3b82f6) 15%, transparent)', color: 'var(--dgd-primary-500,#3b82f6)', display: 'grid', placeItems: 'center', ...MONO, fontSize: 12 }}>2</div>
        <div style={{ ...MONO, fontSize: 10.5, color: 'var(--dgd-fg-3)' }}>Pipeline — análise e necessidades de melhoria</div>
      </div>
      <div style={{ padding: '12px 18px 6px' }}>
        <p style={{ ...BODY, fontSize: 13, color: 'var(--dgd-fg-1)', margin: '0 0 10px' }}>{mdBold(b2.narrativa)}</p>
      </div>
      <PVQuadro {...(b2.quadro || {})} />
      {b2.melhorias?.length > 0 && (
        <div style={{ padding: '0 18px 14px' }}>
          <div style={{ ...MONO, fontSize: 10, color: 'var(--dgd-fg-3)', margin: '8px 0 6px' }}>Necessidades de melhoria — acções</div>
          <div style={{ display: 'grid', gap: 8 }}>
            {b2.melhorias.map((m, i) => (
              <div key={i} style={{ display: 'flex', gap: 10, alignItems: 'flex-start' }}>
                <span style={{ flex: '0 0 auto', width: 20, height: 20, borderRadius: 6, background: 'var(--dgd-green-100, #dcfce7)', color: 'var(--dgd-green-800, #166534)', display: 'grid', placeItems: 'center', fontSize: 10.5, fontWeight: 600, marginTop: 2, fontFamily: 'var(--dgd-font-mono, monospace)' }}>{m.key}</span>
                <span style={{ ...BODY, fontSize: 13, color: 'var(--dgd-fg-1)' }}><b style={{ fontWeight: 600 }}>{m.titulo}</b> {m.detalhe}</span>
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
};

// ── Bloco 1 do briefing da gestora — posição da equipa, na vista Totais ──────
const PVBriefGestorBloco1 = ({ managerId }) => {
  const [state, setState] = React.useState({ bloco1: null, canal: null, loading: true });
  React.useEffect(() => {
    let cancel = false;
    setState({ bloco1: null, canal: null, loading: true });
    fetch(`/api/comercial/brief-gestor/today?managerId=${managerId}&somente_cache=1`, { credentials: 'include' })
      .then(r => r.ok ? r.json() : Promise.reject())
      .then(d => { if (!cancel) setState({ bloco1: d.brief_json?.bloco1 || null, canal: d.canal, loading: false }); })
      .catch(() => { if (!cancel) setState({ bloco1: null, canal: null, loading: false }); });
    return () => { cancel = true; };
  }, [managerId]);

  const MONO = { fontFamily: 'var(--dgd-font-mono, monospace)', letterSpacing: '0.13em', textTransform: 'uppercase', fontWeight: 600 };
  const BODY = { fontFamily: 'var(--dgd-font-body, sans-serif)', lineHeight: 1.65 };

  if (state.loading) return <div style={{ padding: '12px 18px', fontSize: 12, color: 'var(--dgd-fg-3)' }}>A carregar briefing…</div>;
  const b1 = state.bloco1;
  if (!b1?.narrativa) return <div style={{ padding: '12px 18px 14px', fontSize: 12, color: 'var(--dgd-fg-3)', fontStyle: 'italic' }}>Sem briefing de hoje para esta equipa.</div>;

  return (
    <div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '14px 18px 0' }}>
        <div style={{ width: 24, height: 24, borderRadius: 7, background: 'color-mix(in oklch, var(--dgd-primary-500,#3b82f6) 15%, transparent)', color: 'var(--dgd-primary-500,#3b82f6)', display: 'grid', placeItems: 'center', ...MONO, fontSize: 12 }}>1</div>
        <div style={{ ...MONO, fontSize: 10.5, color: 'var(--dgd-fg-3)' }}>Resumo — posição da equipa e acções</div>
      </div>
      <div style={{ padding: '12px 18px 14px' }}>
        {String(b1.narrativa).split('\n').filter(Boolean).map((p, i) => (
          <p key={i} style={{ ...BODY, fontSize: 13.5, color: 'var(--dgd-fg-1)', margin: '0 0 10px' }}>{p}</p>
        ))}
        {b1.acoes?.length > 0 && (
          <div style={{ display: 'grid', gap: 10, marginTop: 4 }}>
            {b1.acoes.map((a, i) => (
              <div key={i} style={{ display: 'flex', gap: 10, alignItems: 'flex-start' }}>
                <span style={{ flex: '0 0 auto', width: 20, height: 20, borderRadius: 6, background: 'var(--dgd-green-100, #dcfce7)', color: 'var(--dgd-green-800, #166534)', display: 'grid', placeItems: 'center', fontSize: 10.5, fontWeight: 600, marginTop: 2, fontFamily: 'var(--dgd-font-mono, monospace)' }}>{a.num || i + 1}</span>
                <span style={{ ...BODY, fontSize: 13.5, color: 'var(--dgd-fg-1)' }}><b style={{ fontWeight: 600 }}>{a.titulo}.</b> {a.detalhe}</span>
              </div>
            ))}
          </div>
        )}
        {state.canal === 'equipamentos' && b1.tabela_posicao?.length > 0 && (
          <div style={{ overflowX: 'auto', marginTop: 12 }}>
            <div style={{ ...MONO, fontSize: 10, color: 'var(--dgd-fg-3)', margin: '0 0 6px' }}>Quadro auxiliar — posição nominal vs. credível</div>
            <table style={{ borderCollapse: 'collapse', width: '100%', fontFamily: 'var(--dgd-font-mono, monospace)', fontSize: 12.5 }}>
              <thead>
                <tr>
                  {['Horizonte','Objetivo','Realizado','Prev. Nominal','Prev. Credível','Gap','Leitura'].map(h => (
                    <th key={h} style={{ padding: '7px 10px', textAlign: h === 'Horizonte' || h === 'Leitura' ? 'left' : 'right', fontSize: 10.5, fontWeight: 600, color: 'var(--dgd-fg-3)', whiteSpace: 'nowrap', borderBottom: '1px solid var(--dgd-border-1)' }}>{h}</th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {b1.tabela_posicao.map((row, i) => (
                  <tr key={i}>
                    <td style={{ padding: '8px 10px', fontWeight: 600, whiteSpace: 'nowrap' }}>{row.horizonte}</td>
                    <td style={{ padding: '8px 10px', textAlign: 'right' }}>{row.objetivo != null ? PV_eur(row.objetivo) : '—'}</td>
                    <td style={{ padding: '8px 10px', textAlign: 'right' }}>{row.realizado != null ? PV_eur(row.realizado) : '—'}</td>
                    <td style={{ padding: '8px 10px', textAlign: 'right' }}>{row.prev_nominal != null ? PV_eur(row.prev_nominal) : '—'}</td>
                    <td style={{ padding: '8px 10px', textAlign: 'right' }}>{row.prev_credivel != null ? PV_eur(row.prev_credivel) : '—'}</td>
                    <td style={{ padding: '8px 10px', textAlign: 'right', ...PV_desvColor(row.gap) }}>{row.gap != null ? PV_eur(row.gap) : '—'}</td>
                    <td style={{ padding: '8px 10px', textAlign: 'left', ...BODY, fontSize: 12, color: 'var(--dgd-fg-2)', minWidth: 200 }}>{row.leitura}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>
    </div>
  );
};

// ── Gráfico Anual Ibéria (linha) ─────────────────────────────────────────────
const PVChartIberia = ({ mensal, ano, mesFecho }) => {
  const [tooltip, setTooltip] = React.useState(null);

  const W = 920, H = 260, PAD_L = 62, PAD_R = 20, PAD_T = 20, PAD_B = 40;
  const chartW = W - PAD_L - PAD_R;
  const chartH = H - PAD_T - PAD_B;

  const n = 12;
  const xOf = i => PAD_L + (i / (n - 1)) * chartW;

  const allVals = mensal.flatMap(m => [m.fat_atual, m.fat_ant, m.bp]).filter(v => v != null && v > 0);
  const maxVal  = allVals.length ? Math.max(...allVals) : 1;
  const roundTo = maxVal > 10e6 ? 5e6 : maxVal > 5e6 ? 2e6 : maxVal > 2e6 ? 1e6 : 500000;
  const yMax    = Math.ceil(maxVal / roundTo) * roundTo;
  const yOf     = v => PAD_T + chartH - (v / yMax) * chartH;

  const yTicks = [];
  for (let v = 0; v <= yMax; v += roundTo) yTicks.push(v);

  const fmtY = v => v >= 1e6
    ? (v / 1e6 % 1 === 0 ? v / 1e6 : (v / 1e6).toFixed(1)) + 'M'
    : (v / 1000) + 'k';

  const smoothPath = (points) => {
    if (points.length < 2) return '';
    return points.map((p, i) => (i === 0 ? `M${p.x},${p.y}` : `L${p.x},${p.y}`)).join(' ');
  };

  const areaPath = (linePath, pts) => {
    if (!pts.length) return '';
    const base = yOf(0);
    return `${linePath} L${pts[pts.length - 1].x},${base} L${pts[0].x},${base} Z`;
  };

  const ptsAtual = mensal.map((m, i) => m.fat_atual != null ? { x: xOf(i), y: yOf(m.fat_atual), val: m.fat_atual, i } : null).filter(Boolean);
  const ptsAnt   = mensal.map((m, i) => m.fat_ant   != null ? { x: xOf(i), y: yOf(m.fat_ant),   val: m.fat_ant,   i } : null).filter(Boolean);
  const ptsBP    = mensal.map((m, i) => m.bp         != null ? { x: xOf(i), y: yOf(m.bp),         val: m.bp,         i } : null).filter(Boolean);

  const lineAtual = smoothPath(ptsAtual);
  const lineAnt   = smoothPath(ptsAnt);
  const lineBP    = smoothPath(ptsBP);

  const uid = 'pvc'; // prefix para gradients

  return (
    <div style={{ overflowX: 'auto', padding: '4px 0 8px', position: 'relative' }}>
      <svg width="100%" viewBox={`0 0 ${W} ${H}`} style={{ display: 'block', minWidth: 580 }}
        onMouseLeave={() => setTooltip(null)}>
        <defs>
          <linearGradient id={`${uid}-g1`} x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor="var(--dgd-primary-500)" stopOpacity="0.18" />
            <stop offset="100%" stopColor="var(--dgd-primary-500)" stopOpacity="0.01" />
          </linearGradient>
          <linearGradient id={`${uid}-g2`} x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor="#94a3b8" stopOpacity="0.12" />
            <stop offset="100%" stopColor="#94a3b8" stopOpacity="0.01" />
          </linearGradient>
          <clipPath id={`${uid}-clip`}>
            <rect x={PAD_L} y={PAD_T} width={chartW} height={chartH} />
          </clipPath>
        </defs>

        {/* Grid Y */}
        {yTicks.map(v => {
          const y = yOf(v);
          return (
            <g key={v}>
              <line x1={PAD_L} x2={W - PAD_R} y1={y} y2={y}
                stroke="var(--dgd-border-1)" strokeWidth={v === 0 ? 1 : 0.5}
                strokeDasharray={v === 0 ? '' : '4,4'} opacity={0.7} />
              <text x={PAD_L - 8} y={y + 3.5} textAnchor="end" fontSize={9.5}
                fill="var(--dgd-fg-3)" fontVariantNumeric="tabular-nums">{fmtY(v)}</text>
            </g>
          );
        })}

        {/* Labels X */}
        {mensal.map((_, i) => (
          <text key={i} x={xOf(i)} y={H - 10} textAnchor="middle" fontSize={9.5}
            fill={i + 1 === mesFecho ? 'var(--dgd-primary-500)' : 'var(--dgd-fg-3)'}
            fontWeight={i + 1 === mesFecho ? 700 : 400}>
            {PV_MESES[i]}
          </text>
        ))}

        {/* Coluna vertical do mês actual */}
        <line x1={xOf(mesFecho - 1)} x2={xOf(mesFecho - 1)} y1={PAD_T} y2={PAD_T + chartH}
          stroke="var(--dgd-primary-500)" strokeWidth={1} strokeDasharray="3,4" opacity={0.3} />

        <g clipPath={`url(#${uid}-clip)`}>
          {/* Área 2025 */}
          {ptsAnt.length > 1 && <path d={areaPath(lineAnt, ptsAnt)} fill={`url(#${uid}-g2)`} />}
          {/* Área 2026 */}
          {ptsAtual.length > 1 && <path d={areaPath(lineAtual, ptsAtual)} fill={`url(#${uid}-g1)`} />}

          {/* Linha 2025 */}
          {ptsAnt.length > 1 && <path d={lineAnt} fill="none" stroke="#94a3b8" strokeWidth={2} strokeLinejoin="round" strokeLinecap="round" />}
          {/* Linha BP */}
          {ptsBP.length > 1 && <path d={lineBP} fill="none" stroke="var(--dgd-purple-500,#7c3aed)" strokeWidth={1.5} strokeDasharray="5,4" strokeLinejoin="round" strokeLinecap="round" opacity={0.85} />}
          {/* Linha 2026 */}
          {ptsAtual.length > 1 && <path d={lineAtual} fill="none" stroke="var(--dgd-primary-500)" strokeWidth={2.5} strokeLinejoin="round" strokeLinecap="round" />}
        </g>

        {/* Pontos interactivos (zona hover invisível por mês) */}
        {mensal.map((m, i) => (
          <rect key={i}
            x={xOf(i) - chartW / n / 2} y={PAD_T} width={chartW / n} height={chartH}
            fill="transparent"
            onMouseEnter={e => setTooltip({ i, x: xOf(i), m })}
          />
        ))}

        {/* Pontos visíveis — só meses com dados */}
        {ptsAtual.map(p => <circle key={p.i} cx={p.x} cy={p.y} r={p.i + 1 === mesFecho ? 4 : 3} fill="var(--dgd-primary-500)" stroke="var(--dgd-bg-surface)" strokeWidth={1.5} />)}
        {ptsAnt.map(p   => <circle key={p.i} cx={p.x} cy={p.y} r={2.5} fill="#94a3b8" stroke="var(--dgd-bg-surface)" strokeWidth={1.5} />)}
        {ptsBP.map(p    => <circle key={p.i} cx={p.x} cy={p.y} r={2.5} fill="var(--dgd-purple-500,#7c3aed)" stroke="var(--dgd-bg-surface)" strokeWidth={1.5} opacity={0.85} />)}

        {/* Tooltip */}
        {tooltip && (() => {
          const { x, m, i } = tooltip;
          const lines = [
            m.fat_atual != null ? `${ano}: ${PV_eur(m.fat_atual)}` : null,
            m.fat_ant   != null ? `${ano - 1}: ${PV_eur(m.fat_ant)}` : null,
            m.bp        != null ? `BP: ${PV_eur(m.bp)}` : null,
          ].filter(Boolean);
          const bxW = 148, bxH = lines.length * 16 + 20;
          const bxX = x + bxW + 12 > W ? x - bxW - 8 : x + 8;
          const bxY = PAD_T + 8;
          return (
            <g style={{ pointerEvents: 'none' }}>
              <text x={x} y={PAD_T - 6} textAnchor="middle" fontSize={9} fontWeight={700} fill="var(--dgd-primary-500)">{PV_MESES[i]}</text>
              <rect x={bxX} y={bxY} width={bxW} height={bxH} rx={6}
                fill="var(--dgd-bg-surface)" stroke="var(--dgd-border-1)" strokeWidth={1} filter="drop-shadow(0 2px 8px rgba(0,0,0,0.12))" />
              <text x={bxX + 10} y={bxY + 13} fontSize={9.5} fontWeight={700} fill="var(--dgd-fg-2)">{PV_MESES[i]}</text>
              {lines.map((l, li) => (
                <text key={li} x={bxX + 10} y={bxY + 13 + (li + 1) * 16} fontSize={10} fill="var(--dgd-fg-1)" fontVariantNumeric="tabular-nums">{l}</text>
              ))}
            </g>
          );
        })()}
      </svg>

      {/* Legenda */}
      <div style={{ display: 'flex', gap: 20, padding: '2px 0 0 62px', flexWrap: 'wrap' }}>
        {[
          { stroke: 'var(--dgd-primary-500)', label: String(ano), w: 2.5 },
          { stroke: '#94a3b8', label: String(ano - 1), w: 2 },
          { stroke: 'var(--dgd-purple-500,#7c3aed)', label: 'BP', w: 1.5, dash: '5,4' },
        ].map(({ stroke, label, w, dash }) => (
          <div key={label} style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 11, color: 'var(--dgd-fg-2)' }}>
            <svg width={22} height={10}>
              <line x1={0} y1={5} x2={22} y2={5} stroke={stroke} strokeWidth={w} strokeDasharray={dash} strokeLinecap="round" />
            </svg>
            {label}
          </div>
        ))}
      </div>
    </div>
  );
};

// ── Main Screen ──────────────────────────────────────────────────────────────
const ScreenPrevisaoVendas = ({ user }) => {
  const pvNow = new Date();
  const [pvAno, setPvAno] = React.useState(pvNow.getFullYear());
  const [pvMes, setPvMes] = React.useState(pvNow.getMonth() + 1);
  const [pvModo, setPvModo] = React.useState('ytd'); // 'ytd'|'total'|'mensal'|'q1'|'q2'|'q3'|'q4'
  const [pvEquipa, setPvEquipa] = React.useState(null);
  const [pvTenant, setPvTenant] = React.useState('pt'); // 'pt'=Digidelta PT, 'es'=Dimensión ES
  const [pvData, setPvData] = React.useState(null);
  const [pvLoading, setPvLoading] = React.useState(true);
  const [pvError, setPvError] = React.useState(null);
  const [pvComercial, setPvComercial] = React.useState(null); // vendedor code ou null=Todos
  const [pvIberia, setPvIberia] = React.useState(null);

  // Mês efectivo que vai ao API (Quarters e Total têm mês fixo)
  const PV_Q_MES = { q1: 3, q2: 6, q3: 9, q4: 12 };
  const pvMesAPI = pvModo === 'total' ? 12 : (PV_Q_MES[pvModo] ?? pvMes);

  // Fetch dados por comercial
  React.useEffect(() => {
    if (pvTenant === 'es') return;
    setPvLoading(true);
    setPvError(null);
    const equipaQ = pvEquipa ? `&equipa=${pvEquipa}` : '';
    fetch(`/api/comercial/previsao-vendas?ano=${pvAno}&mes=${pvMesAPI}${equipaQ}`)
      .then(r => r.ok ? r.json() : r.json().then(e => Promise.reject(e.error || 'Erro')))
      .then(d => { setPvData(d); setPvLoading(false); })
      .catch(e => { setPvError(String(e)); setPvLoading(false); });
  }, [pvAno, pvMesAPI, pvEquipa, pvTenant]);

  // Fetch dados agregados por grupos (PT tab)
  React.useEffect(() => {
    if (pvTenant !== 'pt') return;
    setPvIberia(null);
    fetch(`/api/comercial/previsao-vendas/iberia?ano=${pvAno}&mes=${pvMesAPI}&modo=${pvModo}`)
      .then(r => r.ok ? r.json() : Promise.reject())
      .then(d => setPvIberia(d))
      .catch(() => {});
  }, [pvAno, pvMesAPI, pvModo, pvTenant]);

  const kpis = pvData ? pvData.kpis : null;
  const rpcPctBP = kpis && kpis.bp_mes && kpis.rpc_prev ? Math.round((kpis.rpc_prev / kpis.bp_mes) * 100) : null;
  const pvEquipaLabel = PV_EQUIPAS.find(e => e.id === pvEquipa)?.label || 'Todas';

  const pvTabStyle = (active) => ({
    padding: '5px 14px', borderRadius: 20, fontSize: 12, fontWeight: 600, cursor: 'pointer', border: 'none',
    background: active ? 'var(--dgd-primary-500)' : 'var(--dgd-bg-surface)',
    color: active ? '#fff' : 'var(--dgd-fg-2)',
    boxShadow: active ? 'none' : '0 0 0 1px var(--dgd-border-1)',
    transition: 'all .15s',
  });

  return (
    <div style={{ overflowY: 'auto', height: '100%' }}>
      <div style={{ padding: '24px 28px 60px', display: 'flex', flexDirection: 'column', gap: 20, maxWidth: 1440, margin: '0 auto' }}>
        {/* Header */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
          <h1 style={{ fontSize: 16, fontWeight: 700, margin: 0, color: 'var(--dgd-fg-1)' }}>
            Previsão de Vendas
            <span style={{ fontSize: 12, color: 'var(--dgd-fg-3)', marginLeft: 8, fontWeight: 400 }}>
              Consumíveis · {pvData ? `${PV_MESES[pvData.mes - 1]} ${pvData.ano}` : `${PV_MESES[pvMes - 1]} ${pvAno}`}
            </span>
          </h1>
          <div style={{ marginLeft: 'auto' }}>
            <PVPeriodSel ano={pvAno} mes={pvMes} modo={pvModo} onChange={(a, m, md) => { setPvAno(a); setPvMes(m); setPvModo(md); }} />
          </div>
        </div>

        {/* Filtro Tenant (topo) */}
        <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
          {PV_TENANTS.map(t => (
            <button key={t.id} style={pvTabStyle(pvTenant === t.id)} onClick={() => { setPvTenant(t.id); if (t.id !== 'pt') { setPvEquipa(null); setPvComercial(null); } }}>
              {t.label}
            </button>
          ))}
        </div>

        {/* Filtro Equipa — só visível em Digidelta PT */}
        {pvTenant === 'pt' && (
          <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
            {PV_EQUIPAS.map(eq => (
              <button key={eq.id ?? '__all'} style={pvTabStyle(pvEquipa === eq.id)} onClick={() => { setPvEquipa(eq.id); setPvComercial(null); }}>
                {eq.label}
              </button>
            ))}
          </div>
        )}

        {/* Dimensión ES — placeholder */}
        {pvTenant === 'es' && (
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '80px 0', color: 'var(--dgd-fg-3)', fontSize: 14 }}>
            A aguardar dados de Espanha
          </div>
        )}

        {/* Vista Digidelta PT */}
        {pvTenant === 'pt' && (
          <>
            {/* Overview por grupos — KPIs + tabela + gráfico (só quando nenhuma equipa seleccionada) */}
            {!pvEquipa && pvIberia && (() => {
              const linhasPT  = pvIberia.linhas;
              const men       = pvIberia.mensal || [];

              // Agrega valores consoante o modo
              const PV_Q_IDX = { q1:[0,1,2], q2:[3,4,5], q3:[6,7,8], q4:[9,10,11] };
              let totFat, totFatAnt, totBP, totMar;

              if (pvModo === 'ytd' || pvModo === 'total') {
                // Dados já agregados pelo backend (linhas)
                totFat    = linhasPT.reduce((s, r) => s + (r.fat_atual    || 0), 0);
                totFatAnt = linhasPT.reduce((s, r) => s + (r.fat_ant      || 0), 0);
                totBP     = linhasPT.reduce((s, r) => s + (r.bp_ytd       || 0), 0);
                totMar    = linhasPT.reduce((s, r) => s + (r.margem_atual || 0), 0);
              } else if (pvModo === 'mensal') {
                const m   = men[pvMes - 1] || {};
                totFat    = m.fat_atual || 0;
                totFatAnt = m.fat_ant   || 0;
                totBP     = m.bp        || 0;
                totMar    = m.margem    || 0;
              } else {
                // q1/q2/q3/q4 — soma dos meses do quarter
                const idxs = PV_Q_IDX[pvModo] || [];
                totFat    = idxs.reduce((s, i) => s + (men[i]?.fat_atual || 0), 0);
                totFatAnt = idxs.reduce((s, i) => s + (men[i]?.fat_ant   || 0), 0);
                totBP     = idxs.reduce((s, i) => s + (men[i]?.bp        || 0), 0);
                totMar    = idxs.reduce((s, i) => s + (men[i]?.margem    || 0), 0);
              }

              const totMarPct = totFat > 0 ? totMar / totFat * 100 : null;
              const desvio    = totFat - totBP;
              const desvPct   = totBP > 0 ? Math.round(totFat / totBP * 100) : null;
              const vsAnt     = totFatAnt > 0 ? (totFat / totFatAnt - 1) * 100 : null;

              // Labels do período
              const periodoLabel = pvModo === 'ytd'    ? `YTD ${PV_MESES[pvMesAPI - 1]}`
                                 : pvModo === 'total'  ? `Total ${pvIberia.ano}`
                                 : pvModo === 'mensal' ? PV_MESES[pvMes - 1]
                                 : pvModo.toUpperCase();
              const antLabel     = pvModo === 'ytd'    ? `YTD ${PV_MESES[pvMesAPI - 1]} ${pvIberia.ano - 1}`
                                 : pvModo === 'total'  ? String(pvIberia.ano - 1)
                                 : pvModo === 'mensal' ? `${PV_MESES[pvMes - 1]} ${pvIberia.ano - 1}`
                                 : `${pvModo.toUpperCase()} ${pvIberia.ano - 1}`;
              const bpLabel      = pvModo === 'ytd' || pvModo === 'total' ? 'BP acumulado' : 'Objectivo BP';
              const fatLabel     = `Faturado · ${periodoLabel}`;

              return (
                <>
                  <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(190px, 1fr))', gap: 12 }}>
                    <PVKpiCard label={`BP · ${periodoLabel}`} value={PV_eur(totBP)} sub={bpLabel} />
                    <PVKpiCard
                      label={fatLabel}
                      value={PV_eur(totFat)}
                      sub={desvPct != null ? `${desvPct}% do BP` : 'sem dados BP'}
                      accent={desvPct != null && desvPct >= 100 ? 'var(--dgd-green-500,#16a34a)' : undefined}
                    />
                    <PVKpiCard
                      label="Desvio vs BP"
                      value={desvio != null ? (desvio > 0 ? '+' : '') + PV_eur(desvio) : '—'}
                      sub={periodoLabel}
                      accent={desvio >= 0 ? 'var(--dgd-green-500,#16a34a)' : 'var(--dgd-red-500,#dc2626)'}
                    />
                    <PVKpiCard label="Margem" value={totMarPct != null ? PV_pct(totMarPct) : '—'} sub="faturação do período" />
                    <PVKpiCard
                      label={`vs ${pvIberia.ano - 1}`}
                      value={vsAnt != null ? (vsAnt > 0 ? '+' : '') + vsAnt.toFixed(1) + '%' : '—'}
                      sub={PV_eur(totFatAnt) + ` em ${pvIberia.ano - 1}`}
                      accent={vsAnt != null && vsAnt > 0 ? 'var(--dgd-green-500,#16a34a)' : vsAnt != null ? 'var(--dgd-red-500,#dc2626)' : undefined}
                    />
                  </div>
                  <PVCard title={`Digidelta PT · ${periodoLabel} ${pvIberia.ano}`}>
                    <div style={{ padding: '0 10px' }}>
                      <PVTabelaIberia linhas={linhasPT} ano={pvIberia.ano} totalLabel="Total Digidelta PT" antLabel={antLabel} />
                    </div>
                  </PVCard>
                  {pvIberia.mensal && (
                    <PVCard title={`Evolução Anual · Digidelta PT · ${pvIberia.ano} vs ${pvIberia.ano - 1}`}>
                      <div style={{ padding: '8px 14px 4px' }}>
                        <PVChartIberia mensal={pvIberia.mensal} ano={pvIberia.ano} mesFecho={pvMesAPI} />
                      </div>
                    </PVCard>
                  )}
                </>
              );
            })()}

            {pvLoading && !pvIberia && (
              <div style={{ textAlign: 'center', padding: '60px 0', color: 'var(--dgd-fg-3)' }}>A carregar dados...</div>
            )}
            {pvLoading && pvIberia && null}

            {pvError && (
              <div style={{ padding: '16px 18px', background: 'color-mix(in oklch, var(--dgd-red-500, #dc2626) 10%, transparent)', border: '1px solid color-mix(in oklch, var(--dgd-red-500, #dc2626) 30%, transparent)', borderRadius: 10, color: 'var(--dgd-red-500, #dc2626)', fontSize: 13 }}>
                Erro: {pvError}
              </div>
            )}

            {!pvLoading && pvData && kpis && (
              <>
                {/* KPIs */}
                <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(190px, 1fr))', gap: 12 }}>
                  <PVKpiCard label={`Obj. BP · ${PV_MESES[pvData.mes - 1]}`} value={PV_eur(kpis.bp_mes)} sub={`${kpis.n_comerciais} comerciais`} />
                  <PVKpiCard label="Previsão RPC ¹" value={PV_eur(kpis.rpc_prev)} sub={rpcPctBP != null ? `${rpcPctBP}% do objectivo` : 'sem dados RPC'} accent="var(--dgd-primary-500)" />
                  <PVKpiCard label="Faturado até hoje" value={PV_eur(kpis.fat_mes)} sub={kpis.rpc_prev > 0 ? `${Math.round(kpis.fat_mes / kpis.rpc_prev * 100)}% da previsão` : ''} />
                  <PVKpiCard label="Margem" value={PV_pct(kpis.margem_pct)} sub="faturação do mês" />
                  <PVKpiCard label="Fiabilidade YTD ²" value={PV_pct(kpis.fiabilidade_ytd)} sub="meses fechados c/ RPC" accent={kpis.fiabilidade_ytd != null && kpis.fiabilidade_ytd >= 97 ? 'var(--dgd-green-500, #16a34a)' : undefined} />
                </div>

                {/* Tabela mensal — filtrada para comercial seleccionado se aplicável */}
                <PVCard title={`${PV_MESES[pvData.mes - 1]} ${pvData.ano} — por comercial · ${pvEquipaLabel}`}>
                  <div style={{ padding: '0 10px' }}>
                    <PVTabelaMes comerciais={pvComercial ? pvData.comerciais.filter(c => c.id === pvComercial) : pvData.comerciais} />
                  </div>
                </PVCard>

                {/* Selector de comerciais (só quando equipa seleccionada) */}
                {pvEquipa && pvData.comerciais.length > 0 && (
                  <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
                    <button key="__todos" style={pvTabStyle(pvComercial === null)} onClick={() => setPvComercial(null)}>
                      Todos
                    </button>
                    {pvData.comerciais.map(c => (
                      <button key={c.id} style={pvTabStyle(pvComercial === c.id)} onClick={() => setPvComercial(pvComercial === c.id ? null : c.id)}>
                        {c.nome}
                      </button>
                    ))}
                  </div>
                )}

                {/* Mapa RPC completo — quando equipa seleccionada */}
                {pvEquipa && pvData.comerciais.length > 0 && (() => {
                  const cfg = PV_EQUIPA_CONFIG[pvEquipa];
                  if (!cfg) return null;
                  const PVEquipEmbed = window.PVEquipMapaEmbed;
                  const PVConsEmbed  = window.PVConsMapaEmbed;
                  const mapaTitle = pvComercial
                    ? `Mapa RPC · ${pvData.comerciais.find(c => c.id === pvComercial)?.nome || pvComercial}`
                    : `Mapa RPC · ${pvEquipaLabel} · Totais`;
                  return (
                    <PVCard title={mapaTitle}>
                      <div style={{ padding: '8px 18px 18px' }}>
                        {cfg.type === 'equip' && PVEquipEmbed && (
                          <PVEquipEmbed
                            empresa={cfg.empresa}
                            fmEmpresa={cfg.fmEmpresa}
                            equipa={pvEquipa}
                            selVendedor={pvComercial}
                            ano={pvAno}
                            userTipo={user?.tipo}
                          />
                        )}
                        {cfg.type === 'cons' && PVConsEmbed && (
                          <PVConsEmbed
                            empresa={cfg.empresa}
                            fmEmpresa={cfg.fmEmpresa}
                            selVendedor={pvComercial}
                            ano={pvAno}
                            userTipo={user?.tipo}
                          />
                        )}
                      </div>
                    </PVCard>
                  );
                })()}

                {!pvComercial && PV_EQUIPA_MANAGER[pvEquipa] && (
                  <PVCard title="Briefing · Equipa">
                    <PVBriefGestorBloco1 managerId={PV_EQUIPA_MANAGER[pvEquipa]} />
                  </PVCard>
                )}

                {/* Mapa Anual — só visível quando nenhuma equipa seleccionada */}
                {!pvEquipa && pvData.annual && (
                  <PVCard title={`Mapa Anual · Digidelta PT · ${pvAno}`}>
                    <PVGrelhaAnual annual={pvData.annual} />
                  </PVCard>
                )}

                {/* Briefing bloco 2 — só quando comercial de equip seleccionado */}
                {pvComercial && PV_EQUIPA_CONFIG[pvEquipa]?.type === 'equip' && (
                  <PVCard title="Briefing · Pipeline">
                    <PVBriefBloco2 vendedorId={pvComercial} />
                  </PVCard>
                )}
              </>
            )}
          </>
        )}
      </div>
    </div>
  );
};

window.ScreenPrevisaoVendas = ScreenPrevisaoVendas;
