/* screen_comercial_performance.jsx — Dashboard de Performance Comercial
   Drill-down: Ibéria → País → Equipa → Indivíduo
   Spec: docs/specs/2026-07-21-performance-comercial-design.md
*/

// ── Constantes ────────────────────────────────────────────────────────────────
const PERF_SEGS = [
  { id: 'ALL', label: 'Todos' },
  { id: 'SG',  label: 'Sign & Graphics' },
  { id: 'CP',  label: 'Cutting Plotters' },
  { id: 'IP',  label: 'Inkjet Print' },
  { id: 'TA',  label: 'Têxtil' },
  { id: '3D',  label: '3D' },
];

const PERF_SEGS_MEDIA = [
  { id: 'ALL',    label: 'Todos' },
  { id: 'DECAL',  label: 'Decal' },
  { id: 'BIOND',  label: 'Biond' },
  { id: 'OUTROS', label: 'Outros' },
];

const SEMAFORO = (pct) =>
  pct >= 95 ? { icon: '🟢', color: '#16a34a' } :
  pct >= 75 ? { icon: '🟡', color: '#d97706' } :
              { icon: '🔴', color: '#dc2626' };

const fmtQty  = (n) => n == null ? '—' : Number(n) % 1 === 0 ? String(Math.round(n)) : Number(n).toFixed(1);
const fmtEur  = (n) => n == null ? '—' : n >= 1e6 ? (n/1e6).toFixed(1)+'M€' : n >= 1e3 ? Math.round(n/1e3)+'k€' : Math.round(n)+'€';
const fmtPct  = (n) => n == null ? '—' : n.toFixed(1).replace('.', ',') + '%';
const fmtDias = (n) => n == null ? 'N/D' : n + 'd';

// Nível inicial baseado no papel do utilizador
function initNivel(userTipo) {
  if (['admin','ceo','board','superadmin'].includes(userTipo)) return { nivel: 'iberia', id: null };
  if (['manager','team_leader','gestor'].includes(userTipo))   return { nivel: 'equipa', id: null };
  return { nivel: 'vendedor', id: null };
}

const NIVEL_LABELS = { iberia: 'Ibéria', pais: 'País', equipa: 'Equipa', vendedor: 'Indivíduo' };
const NIVEL_NEXT   = { iberia: 'pais', pais: 'equipa', equipa: 'vendedor', vendedor: null };

// ── Bloco Pipeline ────────────────────────────────────────────────────────────
const BloPipeline = ({ pipeline }) => {
  if (!pipeline) return null;
  const { totalLeads, stage80, fechados, avgAgeStage80, avgAgeFecho, ratioConv, stage80Needed, stage80Gap, refMimaki } = pipeline;
  const gapColor   = stage80Gap > 0 ? '#dc2626' : '#16a34a';
  const ratioColor = ratioConv >= refMimaki ? '#16a34a' : ratioConv >= refMimaki * 0.75 ? '#d97706' : '#dc2626';

  const boxSt  = { background: 'var(--dgd-bg-sunken,#f3f4f6)', borderRadius: 8, padding: '10px 14px', flex: 1, minWidth: 90 };
  const labSt  = { fontSize: 10, color: 'var(--dgd-fg-3,#6b7280)', textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 2 };
  const valSt  = { fontSize: 20, fontWeight: 700, color: 'var(--dgd-fg-1,#111)', lineHeight: 1 };

  return (
    <div style={{ background: 'var(--dgd-bg-card,white)', border: '1px solid var(--dgd-border-1,#e5e7eb)', borderRadius: 10, padding: 16, display: 'flex', flexDirection: 'column', gap: 12 }}>
      <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--dgd-fg-3,#6b7280)', textTransform: 'uppercase', letterSpacing: '0.08em' }}>Pipeline</div>

      {/* Funil */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13 }}>
        <div style={{ textAlign: 'center' }}>
          <div style={{ fontSize: 22, fontWeight: 700 }}>{totalLeads}</div>
          <div style={{ fontSize: 10, color: 'var(--dgd-fg-3,#6b7280)' }}>Leads</div>
        </div>
        <div style={{ color: 'var(--dgd-fg-3,#9ca3af)', fontSize: 16 }}>→</div>
        <div style={{ textAlign: 'center' }}>
          <div style={{ fontSize: 22, fontWeight: 700, color: stage80Gap > 0 ? '#d97706' : '#16a34a' }}>{stage80}</div>
          <div style={{ fontSize: 10, color: 'var(--dgd-fg-3,#6b7280)' }}>Stage 80</div>
        </div>
        <div style={{ color: 'var(--dgd-fg-3,#9ca3af)', fontSize: 16 }}>→</div>
        <div style={{ textAlign: 'center' }}>
          <div style={{ fontSize: 22, fontWeight: 700, color: '#16a34a' }}>{fechados}</div>
          <div style={{ fontSize: 10, color: 'var(--dgd-fg-3,#6b7280)' }}>Fechos</div>
        </div>
      </div>

      {/* KPIs */}
      <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
        <div style={boxSt}>
          <div style={labSt}>Gap Stage 80</div>
          <div style={{ ...valSt, color: gapColor, fontSize: 18 }}>{stage80Gap > 0 ? '+' : ''}{stage80Gap}</div>
          <div style={{ fontSize: 10, color: 'var(--dgd-fg-3,#6b7280)' }}>necessário: {stage80Needed}</div>
        </div>
        <div style={boxSt}>
          <div style={labSt}>Tempo → S80</div>
          <div style={valSt}>{fmtDias(avgAgeStage80)}</div>
          <div style={{ fontSize: 10, color: 'var(--dgd-fg-3,#6b7280)' }}>média dias</div>
        </div>
        <div style={boxSt}>
          <div style={labSt}>Conv.</div>
          <div style={{ ...valSt, color: ratioColor }}>{fmtPct(ratioConv)}</div>
          <div style={{ fontSize: 10, color: 'var(--dgd-fg-3,#6b7280)' }}>ref.: {refMimaki}%</div>
        </div>
        <div style={boxSt}>
          <div style={labSt}>Tempo → Fecho</div>
          <div style={valSt}>{fmtDias(avgAgeFecho)}</div>
          <div style={{ fontSize: 10, color: 'var(--dgd-fg-3,#6b7280)' }}>média dias</div>
        </div>
      </div>
    </div>
  );
};

// ── Bloco Resultados (totais + barra + contexto trimestral) ───────────────────
const BloResultados = ({ budget, vendas, fy }) => {
  if (!budget || !vendas) return null;
  const budgetQty = budget.total?.qty || 0;
  const vendasQty = vendas.totalQty || 0;
  const desvio    = vendasQty - budgetQty;
  const pct       = budgetQty > 0 ? Math.round(vendasQty / budgetQty * 100) : 0;
  const sem       = SEMAFORO(pct);

  // Contexto trimestral — só quando há dados quarterly (tipo=mimaki)
  const hoje    = new Date();
  const calMes  = hoje.getMonth() + 1; // 1-12 (mês civil)
  const qAtual  = Math.ceil(calMes / 3); // 1,2,3,4
  const bq      = budget.byQuarter;
  const temQ    = bq && Object.keys(bq).length > 0;

  // Budget esperado acumulado até ao fim de qAtual
  let budgetAcum = 0;
  if (temQ) {
    for (let q = 1; q <= qAtual; q++) budgetAcum += (bq[`Q${q}`] || 0);
  }
  const pctPace = budgetAcum > 0 ? Math.round(vendasQty / budgetAcum * 100) : null;
  const semPace = pctPace != null ? SEMAFORO(pctPace) : null;

  return (
    <div style={{ background: 'var(--dgd-bg-card,white)', border: '1px solid var(--dgd-border-1,#e5e7eb)', borderRadius: 10, padding: 16, display: 'flex', flexDirection: 'column', gap: 12 }}>
      <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--dgd-fg-3,#6b7280)', textTransform: 'uppercase', letterSpacing: '0.08em' }}>Resultados FY{fy}</div>

      {/* Métricas principais */}
      <div style={{ display: 'flex', gap: 16, flexWrap: 'wrap' }}>
        <div>
          <div style={{ fontSize: 10, color: 'var(--dgd-fg-3,#6b7280)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>Budget anual</div>
          <div style={{ fontSize: 22, fontWeight: 700 }}>{fmtQty(budgetQty)} <span style={{ fontSize: 12, color: 'var(--dgd-fg-3,#6b7280)', fontWeight: 400 }}>máq.</span></div>
          <div style={{ fontSize: 11, color: 'var(--dgd-fg-3,#6b7280)' }}>{fmtEur(budget.total?.valor)}</div>
        </div>
        <div>
          <div style={{ fontSize: 10, color: 'var(--dgd-fg-3,#6b7280)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>Vendas YTD</div>
          <div style={{ fontSize: 22, fontWeight: 700 }}>{fmtQty(vendasQty)} <span style={{ fontSize: 12, color: 'var(--dgd-fg-3,#6b7280)', fontWeight: 400 }}>máq.</span></div>
        </div>
        <div>
          <div style={{ fontSize: 10, color: 'var(--dgd-fg-3,#6b7280)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>Desvio anual</div>
          <div style={{ fontSize: 22, fontWeight: 700, color: sem.color }}>{desvio >= 0 ? '+' : ''}{fmtQty(desvio)} máq.</div>
        </div>
      </div>

      {/* Barra anual */}
      <div>
        <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 11, color: 'var(--dgd-fg-3,#6b7280)', marginBottom: 4 }}>
          <span>{sem.icon} {pct}% do budget anual</span>
          <span>Q{qAtual} de 4</span>
        </div>
        <div style={{ background: 'var(--dgd-border-1,#e5e7eb)', borderRadius: 4, height: 8, overflow: 'hidden' }}>
          <div style={{ width: Math.min(pct, 100) + '%', height: '100%', background: sem.color, borderRadius: 4, transition: 'width 0.4s' }} />
        </div>
      </div>

      {/* Contexto trimestral — ritmo esperado */}
      {temQ && pctPace != null && (
        <div style={{ background: 'var(--dgd-bg-sunken,#f3f4f6)', borderRadius: 8, padding: '10px 12px' }}>
          <div style={{ fontSize: 10, color: 'var(--dgd-fg-3,#6b7280)', textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 6 }}>
            Ritmo vs budget acumulado Q1–Q{qAtual}
          </div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <div>
              <div style={{ fontSize: 18, fontWeight: 700, color: semPace.color }}>{semPace.icon} {pctPace}%</div>
              <div style={{ fontSize: 10, color: 'var(--dgd-fg-3,#6b7280)' }}>
                {vendasQty} vendidas / {fmtQty(budgetAcum)} esperadas até Q{qAtual}
              </div>
            </div>
            {/* Mini barras por quarter */}
            <div style={{ flex: 1, display: 'flex', gap: 3 }}>
              {[1,2,3,4].map(q => {
                const bQty = bq[`Q${q}`] || 0;
                const isAtual = q === qAtual;
                const isPast  = q < qAtual;
                return (
                  <div key={q} style={{ flex: bQty, display: 'flex', flexDirection: 'column', gap: 2, opacity: q > qAtual ? 0.35 : 1 }}>
                    <div style={{
                      height: 6, borderRadius: 2,
                      background: isAtual ? semPace.color : isPast ? '#16a34a' : 'var(--dgd-border-1,#d1d5db)',
                    }} />
                    <div style={{ fontSize: 9, color: 'var(--dgd-fg-3,#9ca3af)', textAlign: 'center', lineHeight: 1 }}>Q{q}</div>
                  </div>
                );
              })}
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

// ── Bloco Equipamentos (por segmento + lista) ──────────────────────────────────
const BloEquipamentos = ({ budget, vendas }) => {
  if (!vendas) return null;
  const SEGS_D = ['SG','CP','IP','TA','3D'];
  const temSegs = SEGS_D.some(s => (budget?.bySeg?.[s]?.qty || 0) > 0 || (vendas.bySeg?.[s] || 0) > 0);
  const temProds = vendas.byProduto && Object.keys(vendas.byProduto).length > 0;
  if (!temSegs && !temProds) return null;

  return (
    <div style={{ background: 'var(--dgd-bg-card,white)', border: '1px solid var(--dgd-border-1,#e5e7eb)', borderRadius: 10, padding: 16, display: 'flex', flexDirection: 'column', gap: 14 }}>
      <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--dgd-fg-3,#6b7280)', textTransform: 'uppercase', letterSpacing: '0.08em' }}>Equipamentos</div>

      {/* Por segmento */}
      {temSegs && (
        <div>
          <div style={{ fontSize: 10, color: 'var(--dgd-fg-3,#6b7280)', textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 8 }}>Por segmento</div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
            {SEGS_D.map(s => {
              const bQty = budget?.bySeg?.[s]?.qty || 0;
              const vQty = vendas.bySeg?.[s] || 0;
              if (!bQty && !vQty) return null;
              const sPct = bQty > 0 ? Math.round(vQty / bQty * 100) : null;
              const sSem = sPct != null ? SEMAFORO(sPct) : null;
              return (
                <div key={s} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                  <span style={{ fontSize: 11, fontWeight: 700, color: 'var(--dgd-fg-2,#374151)', width: 24 }}>{s}</span>
                  {bQty > 0 ? (
                    <>
                      <div style={{ flex: 1, height: 6, background: 'var(--dgd-border-1,#e5e7eb)', borderRadius: 3, overflow: 'hidden' }}>
                        <div style={{ width: Math.min(sPct, 100) + '%', height: '100%', background: sSem.color, borderRadius: 3 }} />
                      </div>
                      <span style={{ fontSize: 11, fontWeight: 600, color: sSem.color, width: 36, textAlign: 'right' }}>{sPct}%</span>
                      <span style={{ fontSize: 10, color: 'var(--dgd-fg-3,#6b7280)', width: 48, textAlign: 'right' }}>{vQty} / {fmtQty(bQty)}</span>
                    </>
                  ) : (
                    <>
                      <div style={{ flex: 1 }} />
                      <span style={{ fontSize: 12, fontWeight: 700, color: 'var(--dgd-fg-1,#111)', textAlign: 'right' }}>{vQty}</span>
                    </>
                  )}
                </div>
              );
            })}
          </div>
        </div>
      )}

      {/* Equipamentos vendidos */}
      {temProds && (
        <div>
          <div style={{ fontSize: 10, color: 'var(--dgd-fg-3,#6b7280)', textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 8 }}>Equipamentos vendidos</div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
            {Object.entries(vendas.byProduto)
              .sort((a, b) => b[1] - a[1])
              .map(([prod, qty]) => (
                <div key={prod} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', fontSize: 12, color: 'var(--dgd-fg-2,#374151)' }}>
                  <span>{prod}</span>
                  <span style={{ fontWeight: 700, color: 'var(--dgd-fg-1,#111827)', minWidth: 24, textAlign: 'right' }}>{qty}</span>
                </div>
              ))}
          </div>
        </div>
      )}
    </div>
  );
};

// ── Bloco Predição Prescritiva ────────────────────────────────────────────────
const BloPredição = ({ pipeline, budget, vendas, nivel, id, fy, seg, onNav }) => {
  const [aiResult,  setAiResult]  = React.useState(null);
  const [aiLoading, setAiLoading] = React.useState(false);
  const [aiError,   setAiError]   = React.useState(null);

  if (!pipeline || !budget) return null;

  const { stage80Needed, stage80, stage80Gap, budgetNextQ, previsaoFim, deficitPace, qAtual, qProx } = pipeline;

  // Deadline = fim do quarter actual (para ter pipeline pronto para o quarter seguinte)
  const hoje     = new Date();
  const _qAtual  = qAtual || Math.ceil((hoje.getMonth() + 1) / 3);
  const _qProx   = qProx  || Math.min(_qAtual + 1, 4);
  const qEndMes  = [3, 6, 9, 12][_qAtual - 1]; // Mar / Jun / Set / Dez
  const fimQDate = new Date(hoje.getFullYear(), qEndMes, 0); // último dia do mês
  const fimQStr  = fimQDate.toLocaleDateString('pt-PT', { day: 'numeric', month: 'long' });

  // Previsão realista (pode vir do server ou calcular localmente)
  const _previsaoFim = previsaoFim ?? (vendas?.totalQty + Math.round(stage80 * ((pipeline.ratioConv || 0) / 100)));
  const budgetTotal  = budget?.total?.qty || 0;
  const pctPrevisto  = budgetTotal > 0 ? Math.round(_previsaoFim / budgetTotal * 100) : 0;
  const semPrev      = SEMAFORO(pctPrevisto);

  const handleAnalisar = async () => {
    setAiLoading(true);
    setAiError(null);
    try {
      const resp = await fetch('/api/performance/predict', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ nivel, id, fy, seg, pipeline, budget, vendas }),
      });
      const data = await resp.json();
      if (!resp.ok) throw new Error(data.error || 'Erro na análise AI');
      setAiResult(data);
    } catch (e) {
      setAiError(e.message);
    } finally {
      setAiLoading(false);
    }
  };

  const handleCriarBriefing = () => {
    if (onNav) onNav('briefings');
    else window.location.hash = '#screen=marketing&sub=briefings';
  };

  const urgCor = aiResult?.urgencia === 'alta' ? '#dc2626' : aiResult?.urgencia === 'media' ? '#d97706' : '#16a34a';

  return (
    <div style={{ background: 'var(--dgd-bg-card,white)', border: '1px solid var(--dgd-border-1,#e5e7eb)', borderRadius: 10, padding: 16, display: 'flex', flexDirection: 'column', gap: 10 }}>
      <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--dgd-fg-3,#6b7280)', textTransform: 'uppercase', letterSpacing: '0.08em' }}>Predição Prescritiva</div>

      {/* Predição matemática — pipeline para Q seguinte */}
      <div style={{ background: 'var(--dgd-bg-sunken,#f3f4f6)', borderRadius: 8, padding: '10px 14px', display: 'flex', flexDirection: 'column', gap: 6 }}>
        <div style={{ fontSize: 13, lineHeight: 1.5 }}>
          {stage80Gap > 0
            ? <span>Para Q{_qProx} ({fmtQty(budgetNextQ)} máq.), precisas de <strong>{stage80Needed}</strong> leads em stage 80 até <strong>{fimQStr}</strong>. Tens <strong>{stage80}</strong>. <span style={{ color: '#dc2626', fontWeight: 700 }}>Faltam {stage80Gap}.</span></span>
            : <span style={{ color: '#16a34a' }}>Pipeline para Q{_qProx} suficiente. <strong>{stage80}</strong> leads em S80 ≥ {stage80Needed} necessários. ✓</span>
          }
        </div>
        {/* Previsão de fecho no final do ano */}
        {_previsaoFim != null && budgetTotal > 0 && (
          <div style={{ fontSize: 12, color: 'var(--dgd-fg-2,#4b5563)', borderTop: '1px solid var(--dgd-border-1,#e5e7eb)', paddingTop: 6, display: 'flex', alignItems: 'center', gap: 6 }}>
            <span>Previsão de fecho do ano:</span>
            <span style={{ fontWeight: 700, color: semPrev.color }}>{semPrev.icon} ~{_previsaoFim} máq.</span>
            <span style={{ color: 'var(--dgd-fg-3,#6b7280)' }}>({pctPrevisto}% de {fmtQty(budgetTotal)})</span>
          </div>
        )}
      </div>

      {/* Botão AI ou resultado */}
      {!aiResult && (
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <button
            onClick={handleAnalisar}
            disabled={aiLoading}
            style={{ padding: '7px 16px', borderRadius: 6, border: 'none', background: 'var(--dgd-fg-1,#111)', color: 'white', fontSize: 12, fontWeight: 600, cursor: aiLoading ? 'wait' : 'pointer', opacity: aiLoading ? 0.7 : 1 }}
          >
            {aiLoading ? 'A analisar...' : 'Analisar com AI →'}
          </button>
          {aiError && <span style={{ color: '#dc2626', fontSize: 12 }}>{aiError}</span>}
        </div>
      )}

      {aiResult && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          {/* Diagnóstico */}
          <div style={{ fontSize: 13, color: 'var(--dgd-fg-1,#111)', fontStyle: 'italic', borderLeft: `3px solid ${urgCor}`, paddingLeft: 10, lineHeight: 1.5 }}>
            {aiResult.diagnostico}
          </div>
          {/* Acções */}
          <div style={{ display: 'flex', flexDirection: 'column', gap: 5 }}>
            {[aiResult.accao1, aiResult.accao2, aiResult.accao3].filter(Boolean).map((a, i) => (
              <div key={i} style={{ background: 'var(--dgd-bg-sunken,#f3f4f6)', borderRadius: 6, padding: '7px 12px', fontSize: 12, color: 'var(--dgd-fg-1,#111)', display: 'flex', gap: 6 }}>
                <span style={{ color: 'var(--dgd-fg-3,#6b7280)', flexShrink: 0 }}>{i + 1}.</span>
                <span>{a}</span>
              </div>
            ))}
          </div>
          {/* Footer */}
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
            <button
              onClick={handleCriarBriefing}
              style={{ padding: '6px 14px', borderRadius: 6, border: '1px solid var(--dgd-border-1,#e5e7eb)', background: 'white', fontSize: 12, fontWeight: 600, cursor: 'pointer', color: 'var(--dgd-accent,#3b82f6)' }}
            >
              → Criar Briefing Marketing
            </button>
            <button
              onClick={() => setAiResult(null)}
              style={{ padding: '6px 10px', borderRadius: 6, border: '1px solid var(--dgd-border-1,#e5e7eb)', background: 'white', fontSize: 11, cursor: 'pointer', color: 'var(--dgd-fg-3,#6b7280)' }}
            >
              ↺ Re-analisar
            </button>
            {aiResult.fromCache && <span style={{ fontSize: 10, color: 'var(--dgd-fg-3,#6b7280)' }}>cache (actualiza em 60 min)</span>}
          </div>
        </div>
      )}
    </div>
  );
};

// ── Bloco Ranking ─────────────────────────────────────────────────────────────
const BloRanking = ({ ranking, userVendedorId, budget }) => {
  if (!ranking || ranking.length === 0) return null;
  const budgetPorVendedor = budget?.total?.qty && ranking.length ? budget.total.qty / ranking.length : 0;
  // Verifica se algum vendedor tem objectivo individual (2H FY26)
  const temObjIndividual  = ranking.some(r => r.objQty != null);

  return (
    <div style={{ background: 'var(--dgd-bg-card,white)', border: '1px solid var(--dgd-border-1,#e5e7eb)', borderRadius: 10, padding: 16 }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10 }}>
        <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--dgd-fg-3,#6b7280)', textTransform: 'uppercase', letterSpacing: '0.08em' }}>Ranking da Equipa</div>
        {temObjIndividual && (
          <div style={{ fontSize: 9, color: 'var(--dgd-fg-3,#9ca3af)', fontStyle: 'italic' }}>OBJ = target 2H</div>
        )}
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
        {ranking.map((r, i) => {
          const isMe    = r.vendedor === userVendedorId;
          // Usar objectivo individual se disponível; caso contrário budget/n
          const target  = r.objQty != null ? r.objQty : budgetPorVendedor;
          const pct     = target > 0 ? Math.round(r.fechados / target * 100) : 0;
          const sem     = SEMAFORO(pct);
          return (
            <div key={r.vendedor} style={{
              display: 'flex', alignItems: 'center', gap: 8,
              background: isMe ? 'var(--dgd-accent-bg,#eff6ff)' : 'transparent',
              borderRadius: 6, padding: '5px 8px',
              border: isMe ? '1px solid #bfdbfe' : '1px solid transparent',
            }}>
              <span style={{ fontSize: 11, color: 'var(--dgd-fg-3,#6b7280)', width: 18, textAlign: 'right', flexShrink: 0 }}>#{i+1}</span>
              <span style={{ fontSize: 13, fontWeight: isMe ? 700 : 400, flex: 1, color: 'var(--dgd-fg-1,#111)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                {r.nome || r.vendedor}
                {isMe && <span style={{ fontSize: 10, color: 'var(--dgd-accent,#3b82f6)', marginLeft: 6 }}>← tu</span>}
              </span>
              <span style={{ fontSize: 11, color: 'var(--dgd-fg-2,#4b5563)', flexShrink: 0 }}>
                {r.fechados}{r.objQty != null ? `/${r.objQty}` : ''} máq.
              </span>
              <div style={{ width: 70, height: 5, background: 'var(--dgd-border-1,#e5e7eb)', borderRadius: 3, overflow: 'hidden', flexShrink: 0 }}>
                <div style={{ width: Math.min(pct, 100) + '%', height: '100%', background: sem.color, borderRadius: 3 }} />
              </div>
              <span style={{ fontSize: 11, fontWeight: 700, color: sem.color, width: 34, textAlign: 'right', flexShrink: 0 }}>{pct}%</span>
            </div>
          );
        })}
      </div>
    </div>
  );
};

// ── Wrapper dos blocos ────────────────────────────────────────────────────────
const PerfBlocos = ({ data, fy, seg, nivel, id, user, onNav }) => (
  <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12, alignItems: 'start' }}>
    {/* Coluna esquerda: Pipeline → Resultados → Predição → Ranking */}
    <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
      <BloPipeline pipeline={data.pipeline} />
      <BloResultados budget={data.budget} vendas={data.vendas} fy={fy} />
      <BloPredição pipeline={data.pipeline} budget={data.budget} vendas={data.vendas} nivel={nivel} id={id} fy={fy} seg={seg} onNav={onNav} />
      <BloRanking ranking={data.ranking} userVendedorId={user?.gestor_vendedor_id} budget={data.budget} />
    </div>
    {/* Coluna direita: Equipamentos → Por Segmento → Equipamentos Vendidos */}
    <BloEquipamentos budget={data.budget} vendas={data.vendas} />
  </div>
);

// ── Componente principal ──────────────────────────────────────────────────────
const ScreenComercialPerformance = ({ user, userTipo, userName, vendedorId, onNav, tipo = 'mimaki' }) => {
  const init = initNivel(userTipo || '');
  const activeSegs = tipo === 'media' ? PERF_SEGS_MEDIA : PERF_SEGS;
  const unidade    = tipo === 'media' ? 'OPs' : 'máq.';
  const [nav,      setNav]      = React.useState([{ nivel: init.nivel, id: init.id, label: NIVEL_LABELS[init.nivel] }]);
  const [seg,      setSeg]      = React.useState('ALL');
  const [fy,       setFy]       = React.useState(26);
  const [tipoAno,  setTipoAno]  = React.useState('civil'); // 'fiscal' | 'civil'
  const [data,     setData]     = React.useState(null);
  const [loading,  setLoading]  = React.useState(false);
  const [error,    setError]    = React.useState(null);

  const current = nav[nav.length - 1];

  // Reset seg when tipo changes (segs são diferentes entre Mimaki e Media)
  React.useEffect(() => { setSeg('ALL'); }, [tipo]);

  React.useEffect(() => {
    setLoading(true);
    setError(null);
    setData(null);
    const params = new URLSearchParams({ nivel: current.nivel, fy, seg, tipoAno, tipo });
    if (current.id) params.set('id', current.id);
    fetch(`/api/performance/summary?${params}`)
      .then(r => r.json())
      .then(d => { setData(d); setLoading(false); })
      .catch(e => { setError(e.message); setLoading(false); });
  }, [current.nivel, current.id, seg, fy, tipoAno, tipo]);

  const drillDown = (nivelDest, id, label) => setNav(prev => [...prev, { nivel: nivelDest, id, label }]);
  const breadcrumbNav = (idx) => setNav(prev => prev.slice(0, idx + 1));

  const cardSt = {
    background: 'var(--dgd-bg-card,white)', border: '1px solid var(--dgd-border-1,#e5e7eb)',
    borderRadius: 10, padding: '14px 18px', cursor: 'pointer', minWidth: 130,
  };

  return (
    <div style={{ padding: 20, display: 'flex', flexDirection: 'column', gap: 14 }}>

      {/* Header: breadcrumb + toggle tipo ano + selector ano */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap', gap: 8 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 4, fontSize: 13, flexWrap: 'wrap' }}>
          {nav.map((n, i) => (
            <React.Fragment key={i}>
              {i > 0 && <span style={{ color: 'var(--dgd-fg-3,#9ca3af)' }}>›</span>}
              <button
                onClick={() => breadcrumbNav(i)}
                style={{
                  background: 'none', border: 'none', padding: '2px 5px', borderRadius: 4,
                  cursor: i < nav.length - 1 ? 'pointer' : 'default',
                  color: i < nav.length - 1 ? 'var(--dgd-accent,#3b82f6)' : 'var(--dgd-fg-1,#111)',
                  fontWeight: i === nav.length - 1 ? 700 : 400, fontSize: 13,
                }}
              >
                {n.label}
              </button>
            </React.Fragment>
          ))}
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          {/* Toggle Ano Fiscal / Ano Civil */}
          <div style={{ display: 'flex', background: 'var(--dgd-border-1,#e5e7eb)', borderRadius: 8, padding: 2, gap: 2 }}>
            {[{ id: 'fiscal', label: 'Ano Fiscal' }, { id: 'civil', label: 'Ano Civil' }].map(t => (
              <button key={t.id} onClick={() => setTipoAno(t.id)} style={{
                fontSize: 11, padding: '3px 10px', borderRadius: 6, border: 'none', cursor: 'pointer',
                background: tipoAno === t.id ? 'var(--dgd-bg-card,white)' : 'transparent',
                color: tipoAno === t.id ? 'var(--dgd-fg-1,#111)' : 'var(--dgd-fg-3,#6b7280)',
                fontWeight: tipoAno === t.id ? 700 : 400,
                boxShadow: tipoAno === t.id ? '0 1px 3px rgba(0,0,0,0.10)' : 'none',
              }}>{t.label}</button>
            ))}
          </div>
          {/* Selector de ano */}
          <select
            value={fy}
            onChange={e => setFy(parseInt(e.target.value))}
            style={{ fontSize: 12, padding: '4px 8px', borderRadius: 6, border: '1px solid var(--dgd-border-1,#e5e7eb)', background: 'var(--dgd-bg-card,white)' }}
          >
            {tipoAno === 'fiscal'
              ? <><option value={25}>FY25</option><option value={26}>FY26</option></>
              : <><option value={25}>2025</option><option value={26}>2026</option></>
            }
          </select>
        </div>
      </div>

      {/* Filtro de segmento */}
      <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
        {activeSegs.map(s => (
          <button
            key={s.id}
            onClick={() => setSeg(s.id)}
            style={{
              padding: '5px 12px', borderRadius: 20, fontSize: 12, border: '1px solid var(--dgd-border-1,#e5e7eb)',
              background: seg === s.id ? 'var(--dgd-fg-1,#111)' : 'var(--dgd-bg-card,white)',
              color: seg === s.id ? 'white' : 'var(--dgd-fg-2,#374151)',
              cursor: 'pointer', fontWeight: seg === s.id ? 700 : 400,
            }}
          >
            {s.label}
          </button>
        ))}
      </div>

      {loading && <div style={{ color: 'var(--dgd-fg-3,#6b7280)', fontSize: 13, padding: '20px 0', textAlign: 'center' }}>A carregar...</div>}
      {error   && <div style={{ color: '#dc2626', fontSize: 13, padding: 12, background: '#fef2f2', borderRadius: 8 }}>Erro: {error}</div>}

      {/* Cards de drill-down */}
      {!loading && data && NIVEL_NEXT[current.nivel] && data.cards?.length > 0 && (() => {
        const LABEL_MAP = { PTDIG: 'Portugal', DIGES: 'Espanha' };
        const totalFechos  = data.cards.reduce((s, c) => s + c.fechados, 0);
        const totalBudget  = data.budget?.total?.qty || 0;
        const totalPct     = totalBudget > 0 ? Math.round(totalFechos / totalBudget * 100) : 0;
        const semTotal     = SEMAFORO(totalPct);

        if (current.nivel === 'iberia') {
          // Vista Ibéria: bloco totais + split PT/ES
          return (
            <div style={{ background: 'var(--dgd-bg-card,white)', border: '1px solid var(--dgd-border-1,#e5e7eb)', borderRadius: 10, padding: '16px 20px', display: 'flex', flexDirection: 'column', gap: 14 }}>

              {/* Linha total Ibéria */}
              <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
                <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--dgd-fg-3,#6b7280)', textTransform: 'uppercase', letterSpacing: '0.08em', minWidth: 80 }}>Ibéria Total</div>
                <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>
                  <span style={{ fontSize: 28, fontWeight: 800, color: 'var(--dgd-fg-1,#111)', lineHeight: 1 }}>{totalFechos}</span>
                  <span style={{ fontSize: 13, color: 'var(--dgd-fg-3,#6b7280)' }}>/ {fmtQty(totalBudget)} {unidade}</span>
                </div>
                <span style={{ fontSize: 13, fontWeight: 700, color: semTotal.color }}>{semTotal.icon} {totalPct}%</span>
                {/* Barra progresso */}
                <div style={{ flex: 1, minWidth: 120, height: 6, background: 'var(--dgd-border-1,#e5e7eb)', borderRadius: 3, overflow: 'hidden' }}>
                  <div style={{ width: Math.min(totalPct, 100) + '%', height: '100%', background: semTotal.color, borderRadius: 3, transition: 'width 0.4s' }} />
                </div>
              </div>

              {/* Divisor */}
              <div style={{ borderTop: '1px solid var(--dgd-border-1,#f3f4f6)' }} />

              {/* Linhas por tenant */}
              <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap' }}>
                {data.cards.map(card => {
                  const budgetCard = card.budgetQty != null ? card.budgetQty : totalBudget / (data.cards.length || 1);
                  const pct = budgetCard > 0 ? Math.round(card.fechados / budgetCard * 100) : 0;
                  const sem = SEMAFORO(pct);
                  const ptPct = totalFechos > 0 ? Math.round(card.fechados / totalFechos * 100) : 0;
                  return (
                    <div key={card.id}
                      style={{ flex: 1, minWidth: 200, display: 'flex', alignItems: 'center', gap: 12, padding: '10px 14px', borderRadius: 8, border: '1px solid var(--dgd-border-1,#e5e7eb)', cursor: 'pointer', background: 'var(--dgd-bg-sunken,#f9fafb)' }}
                      onClick={() => drillDown(NIVEL_NEXT[current.nivel], card.id, LABEL_MAP[card.id] || card.label)}
                      onMouseEnter={e => e.currentTarget.style.background = 'var(--dgd-bg-card,white)'}
                      onMouseLeave={e => e.currentTarget.style.background = 'var(--dgd-bg-sunken,#f9fafb)'}
                    >
                      <div style={{ minWidth: 80 }}>
                        <div style={{ fontSize: 12, fontWeight: 700, color: 'var(--dgd-fg-1,#111)' }}>{LABEL_MAP[card.id] || card.label}</div>
                        <div style={{ fontSize: 10, color: 'var(--dgd-fg-3,#6b7280)', marginTop: 1 }}>{card.id}</div>
                      </div>
                      <div style={{ flex: 1 }}>
                        {card.total === 0
                          ? <div style={{ fontSize: 11, color: 'var(--dgd-fg-3,#9ca3af)', fontStyle: 'italic', padding: '4px 0' }}>
                              Sem dados do tenant GestorConnect
                              <div style={{ fontSize: 10, marginTop: 2, color: 'var(--dgd-fg-3,#9ca3af)' }}>Budget: {fmtQty(budgetCard)} {unidade} (estimativa)</div>
                            </div>
                          : <>
                              <div style={{ display: 'flex', alignItems: 'baseline', gap: 5, marginBottom: 4 }}>
                                <span style={{ fontSize: 20, fontWeight: 700, color: 'var(--dgd-fg-1,#111)', lineHeight: 1 }}>{card.fechados}</span>
                                <span style={{ fontSize: 11, color: 'var(--dgd-fg-3,#6b7280)' }}>/ {fmtQty(budgetCard)} {unidade}</span>
                                <span style={{ fontSize: 11, fontWeight: 700, color: sem.color, marginLeft: 4 }}>{sem.icon} {pct}%</span>
                              </div>
                              <div style={{ height: 4, background: 'var(--dgd-border-1,#e5e7eb)', borderRadius: 2, overflow: 'hidden' }}>
                                <div style={{ width: Math.min(pct, 100) + '%', height: '100%', background: sem.color, borderRadius: 2 }} />
                              </div>
                            </>
                        }
                      </div>
                      {card.total > 0 && <div style={{ fontSize: 11, color: 'var(--dgd-fg-3,#6b7280)', minWidth: 36, textAlign: 'right' }}>{ptPct}% Ibéria</div>}
                      <span style={{ fontSize: 14, color: 'var(--dgd-fg-3,#9ca3af)' }}>›</span>
                    </div>
                  );
                })}
              </div>
            </div>
          );
        }

        // Outros níveis: cards compactos habituais
        return (
          <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap' }}>
            {data.cards.map(card => {
              const budgetPerCard = card.budgetQty != null
                ? card.budgetQty
                : totalBudget / (data.cards.length || 1);
              const pct = budgetPerCard > 0 ? Math.round(card.fechados / budgetPerCard * 100) : 0;
              const sem = SEMAFORO(pct);
              return (
                <div key={card.id} style={cardSt}
                  onClick={() => drillDown(NIVEL_NEXT[current.nivel], card.id, card.label)}
                  onMouseEnter={e => e.currentTarget.style.boxShadow = '0 2px 8px rgba(0,0,0,0.10)'}
                  onMouseLeave={e => e.currentTarget.style.boxShadow = 'none'}
                >
                  <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--dgd-fg-1,#111)', marginBottom: 4 }}>{card.label}</div>
                  <div style={{ fontSize: 12, color: 'var(--dgd-fg-2,#4b5563)' }}>{card.fechados} / {fmtQty(budgetPerCard)} {unidade}</div>
                  <div style={{ fontSize: 16, marginTop: 6 }}>{sem.icon} <span style={{ fontSize: 12, color: sem.color, fontWeight: 700 }}>{pct}%</span></div>
                </div>
              );
            })}
          </div>
        );
      })()}

      {/* Blocos Pipeline + Resultados + Predição + Ranking */}
      {!loading && data && (
        <PerfBlocos data={data} fy={fy} seg={seg} nivel={current.nivel} id={current.id} user={user} onNav={onNav} />
      )}

    </div>
  );
};

window.ScreenComercialPerformance = ScreenComercialPerformance;
