// Peças de KPI reutilizáveis (spec 2026-07-13) — copiam padrões já aprovados (donut do Produtos,
// cards de KPI do Nichos). Só apresentação; dados prontos por props. Globais via window.

// Donut limpo: rosca conic + Total no centro + legenda 2-col com %. segments:[{label,value,color}].
// Hover: fatia sob o mouse fica cheia, as outras esmaecem; centro mostra o valor da fatia.
const CleanDonut = ({ eyebrow, title, segments, fmt = USDk }) => {
  const [hi, setHi] = React.useState(null);
  const segs = (segments || []).filter(s => s.value > 0);
  const total = segs.reduce((s, d) => s + d.value, 0) || 1;
  let acc = 0;
  const stops = segs.map((d, i) => {
    const from = acc / total * 360, to = (acc + d.value) / total * 360; acc += d.value;
    const dim = hi != null && hi !== i;
    return `${dim ? 'rgba(199,205,217,.35)' : d.color} ${from}deg ${to}deg`;
  }).join(',');
  const hsel = hi != null ? segs[hi] : null;
  return (
    <div style={kpp.card}>
      <div style={kpp.head}>
        <div style={kpp.eyebrow}>{eyebrow}</div>
        <div style={kpp.title}>{title}</div>
      </div>
      {segs.length === 0 ? (
        <div style={kpp.empty}>Sem dado no período.</div>
      ) : (
        <div style={{ display: 'flex', gap: 28, alignItems: 'center', padding: '8px 4px 4px', flexWrap: 'wrap' }}>
          <div style={{ flex: 'none', width: 150, height: 150, borderRadius: '50%', background: `conic-gradient(${stops})`, position: 'relative', transition: 'background .12s' }}
            onMouseLeave={() => setHi(null)}>
            <div style={{ position: 'absolute', inset: 20, borderRadius: '50%', background: '#fff', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
              <div style={{ font: '500 10px/1 var(--font-sans)', textTransform: 'uppercase', letterSpacing: '.05em', color: 'var(--fg-3)' }}>{hsel ? hsel.label : 'Total'}</div>
              <div style={{ font: '800 17px/1.1 var(--font-num)', color: 'var(--fg-1)', marginTop: 5, fontVariantNumeric: 'tabular-nums' }} className="fenix-num">{fmt(hsel ? hsel.value : total)}</div>
            </div>
          </div>
          <div style={{ flex: 1, minWidth: 200, display: 'grid', gridTemplateColumns: 'repeat(auto-fit,minmax(150px,1fr))', gap: '11px 28px' }}>
            {segs.map((d, i) => (
              <div key={d.label} onMouseEnter={() => setHi(i)} onMouseLeave={() => setHi(null)}
                style={{ display: 'flex', alignItems: 'center', gap: 10, cursor: 'default', opacity: hi == null || hi === i ? 1 : 0.5, transition: 'opacity .12s' }}>
                <span style={{ width: 11, height: 11, borderRadius: 3, background: d.color, flex: 'none' }} />
                <span style={{ font: '600 13px/1.2 var(--font-sans)', color: 'var(--fg-1)', flex: 1, minWidth: 0, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{d.label}</span>
                <span style={{ font: '700 12px/1 var(--font-mono)', color: 'var(--fg-2)', fontVariantNumeric: 'tabular-nums' }}>{PCT(d.value / total * 100)}</span>
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
};

// Card branco de KPI no estilo Nichos: eyebrow + chip de ícone; valor 800; sub OU chip de saúde.
// size='md' (padrão) | 'sm' (menor, p/ expansíveis).
const IconKpi = ({ eye, icon, tint, fg, value, sub, health, size = 'md', onClick }) => {
  const s = size === 'sm' ? kpp.smVars : kpp.mdVars;
  return (
    <div style={{ ...kpp.kpi, padding: s.pad, ...(onClick ? { cursor: 'pointer', transition: 'box-shadow .15s, transform .15s' } : {}) }}
      onClick={onClick}
      onMouseEnter={onClick ? e => { e.currentTarget.style.boxShadow = 'var(--shadow-md)'; e.currentTarget.style.transform = 'translateY(-1px)'; } : undefined}
      onMouseLeave={onClick ? e => { e.currentTarget.style.boxShadow = 'var(--shadow-sm)'; e.currentTarget.style.transform = 'none'; } : undefined}>
      <div style={{ ...kpp.kpiTop, marginBottom: s.gap }}>
        <span style={{ ...kpp.kpiEye, fontSize: s.eye }}>{eye}</span>
        {icon && <span style={{ ...kpp.kpiIc, width: s.ic, height: s.ic, background: tint }}><Icon name={icon} size={s.icSz} color={fg} /></span>}
      </div>
      <div style={{ ...kpp.kpiV, fontSize: s.val, ...(health ? { color: health.color } : {}) }} className="fenix-num">{value}</div>
      {health
        ? <div style={{ marginTop: 8 }}><div style={{ ...kpp.healthChip, color: health.color, background: health.bg }}><span style={{ ...kpp.healthDot, background: health.color }} />{health.label}</div></div>
        : (sub && <div style={{ ...kpp.kpiSub, marginTop: s.subGap }}>{sub}</div>)}
    </div>
  );
};

// Card branco de KPI no estilo Produtos: quadradinho colorido + rótulo; valor grande; sub OU saúde.
// `hoverable` (rodada 2, 31/jul): mesmo feedback de hover do card clicável (sombra +
// elevação), sem cursor pointer — para páginas que querem o realce sem ação de clique.
const DotKpi = ({ eye, color, value, sub, subColor, valColor, health, onClick, hoverable }) => (
  <div style={{ ...kpp.dotCard, ...(onClick ? { cursor: 'pointer' } : {}),
    ...((onClick || hoverable) ? { transition: 'box-shadow .15s, transform .15s' } : {}) }}
    onClick={onClick}
    onMouseEnter={(onClick || hoverable) ? e => { e.currentTarget.style.boxShadow = 'var(--shadow-md)'; e.currentTarget.style.transform = 'translateY(-1px)'; } : undefined}
    onMouseLeave={(onClick || hoverable) ? e => { e.currentTarget.style.boxShadow = 'var(--shadow-sm)'; e.currentTarget.style.transform = 'none'; } : undefined}>
    <div style={kpp.dotTop}>
      <span style={{ ...kpp.dot, background: (health ? health.color : color) }} />
      <span style={kpp.dotEye}>{eye}</span>
    </div>
    <div style={{ ...kpp.dotVal, ...(health ? { color: health.color } : valColor ? { color: valColor } : {}) }} className="fenix-num">{value}</div>
    {health
      ? <div style={{ ...kpp.dotSub, color: health.color }}>{health.label}</div>
      : (sub && <div style={{ ...kpp.dotSub, ...(subColor ? { color: subColor } : {}) }}>{sub}</div>)}
  </div>
);

// Célula plana de KPI (eyebrow + valor), sem ícone. Para linhas tipo tabela.
const MiniCell = ({ eye, value, color }) => (
  <div style={kpp.mini}>
    <div style={kpp.miniEye}>{eye}</div>
    <div style={{ ...kpp.miniVal, ...(color ? { color } : {}) }} className="fenix-num">{value}</div>
  </div>
);

// Paleta de fatias (mesma do PDDonut + 2 extras p/ donuts com mais séries).
const DONUT_PALETTE = ['#FD7119', '#303880', '#8A5BD6', '#1F9D6B', '#2C9CC4', '#E0922B', '#5B9BD6', '#E8746C', '#C7CDD9'];

// Donut SVG com hover por fatia (generaliza o PDDonut). NÃO renderiza card — use dentro do card
// do callsite. segments:[{label, value, color?, meta?}]. Agrupa Top N + "Outros". Props:
//  centerValue (string já formatada) + centerLabel: texto fixo no centro (não muda no hover).
//  legendValue(seg)->string: valor à direita na legenda (default: % da fatia).
//  caption(seg)->string: linha embaixo no hover (default: "label · legendValue"). hint: caption ocioso.
//  aside(hoveredSeg|null)->JSX: se presente, renderiza painel à direita no lugar da legenda.
//  onSlice(seg): se presente, fatia/legenda viram clicáveis.
const HoverDonut = ({ segments, centerValue, centerLabel = 'vendas', topN = 8, aside, legendValue, caption, onSlice, hint = 'Passe o mouse nas fatias' }) => {
  const [hi, setHi] = React.useState(null);
  const clean = (segments || []).filter(s => (s.value || 0) > 0).sort((a, b) => (b.value || 0) - (a.value || 0));
  let segs = clean;
  if (clean.length > topN + 1) {
    const rest = clean.slice(topN).reduce((s, x) => s + (x.value || 0), 0);
    segs = [...clean.slice(0, topN), { label: 'Outros', value: rest, color: '#C7CDD9', outros: true }];
  }
  if (segs.length === 0) return <div style={hd.empty}>Sem dado no período.</div>;
  const total = segs.reduce((s, x) => s + (x.value || 0), 0) || 1;
  const R = 54, C = 2 * Math.PI * R;
  let acc = 0;
  const arcs = segs.map((s, i) => {
    const frac = (s.value || 0) / total, len = frac * C, off = -acc * C; acc += frac;
    return { ...s, i, pctIn: frac * 100, color: s.color || DONUT_PALETTE[i % DONUT_PALETTE.length],
      dash: `${len.toFixed(2)} ${(C - len).toFixed(2)}`, offset: off.toFixed(2) };
  });
  const hs = hi != null ? arcs[hi] : null;
  const legVal = legendValue || (a => PCT(a.pctIn));
  const cap = caption || (a => `${a.label} · ${legVal(a)}`);

  const donut = (
    <svg width="140" height="140" viewBox="0 0 150 150" style={{ flex: 'none' }} onMouseLeave={() => setHi(null)}>
      <circle cx="75" cy="75" r={R} fill="none" stroke="var(--gray-100)" strokeWidth="20" />
      {arcs.map(a => (
        <circle key={a.i} cx="75" cy="75" r={R} fill="none" stroke={a.color}
          strokeWidth={hi === a.i ? 24 : 20} strokeDasharray={a.dash} strokeDashoffset={a.offset}
          transform="rotate(-90 75 75)"
          style={{ cursor: onSlice ? 'pointer' : 'default', opacity: hi == null || hi === a.i ? 1 : 0.35, transition: 'opacity .12s, stroke-width .12s' }}
          onMouseEnter={() => setHi(a.i)} onClick={onSlice ? () => onSlice(a) : undefined} />
      ))}
      <text x="75" y="70" textAnchor="middle" style={{ font: '800 15px var(--font-num)', fontVariantNumeric: 'tabular-nums', fill: 'var(--fg-1)' }}>{centerValue}</text>
      <text x="75" y="86" textAnchor="middle" style={{ font: '600 8px var(--font-sans)', letterSpacing: '.04em', textTransform: 'uppercase', fill: 'var(--fg-3)' }}>{centerLabel}</text>
    </svg>
  );

  if (aside) {
    return <div style={hd.asideGrid}>{donut}<div style={{ minWidth: 0 }}>{aside(hs)}</div></div>;
  }

  return (
    <>
      <div style={hd.row}>
        {donut}
        <div style={hd.legend}>
          {arcs.map(a => (
            <div key={a.i} onMouseEnter={() => setHi(a.i)} onMouseLeave={() => setHi(null)}
              onClick={onSlice ? () => onSlice(a) : undefined}
              style={{ display: 'flex', alignItems: 'center', gap: 8, cursor: onSlice ? 'pointer' : 'default', opacity: hi == null || hi === a.i ? 1 : 0.5 }}>
              <span style={{ width: 8, height: 8, borderRadius: 2, background: a.color, flex: 'none' }} />
              <span style={hd.legName}>{a.label}</span>
              <span style={hd.legVal}>{legVal(a)}</span>
            </div>
          ))}
        </div>
      </div>
      <div style={hd.capWrap}>
        <div style={{ font: '600 11.5px/1.3 var(--font-sans)', color: hs ? 'var(--fg-1)' : 'var(--fg-4)' }}>
          {hs ? cap(hs) : hint}
        </div>
      </div>
    </>
  );
};

const kpp = {
  card: { background: '#fff', border: '1px solid var(--border-1)', borderRadius: 'var(--r-lg)', boxShadow: 'var(--shadow-sm)', padding: '18px 22px' },
  head: { marginBottom: 6 },
  eyebrow: { font: '700 10px/1 var(--font-sans)', letterSpacing: '.1em', textTransform: 'uppercase', color: 'var(--fg-3)' },
  title: { font: '800 17px/1.2 var(--font-display)', color: 'var(--fg-1)', marginTop: 5 },
  empty: { font: '500 12.5px/1.4 var(--font-sans)', color: 'var(--fg-4)', padding: '8px 2px 4px' },

  kpi: { background: '#fff', border: '1px solid var(--border-1)', borderRadius: 'var(--r-lg)', boxShadow: 'var(--shadow-sm)', minWidth: 0, display: 'flex', flexDirection: 'column' },
  mdVars: { pad: '14px 14px', gap: 11, eye: 10, ic: 26, icSz: 16, val: 19, subGap: 8 },
  smVars: { pad: '10px 11px', gap: 8, eye: 9, ic: 21, icSz: 13, val: 16, subGap: 6 },
  kpiTop: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 6 },
  kpiEye: { fontWeight: 700, lineHeight: 1.2, fontFamily: 'var(--font-sans)', letterSpacing: '.04em', textTransform: 'uppercase', color: 'var(--fg-3)' },
  kpiIc: { borderRadius: 'var(--r-sm)', display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 'none' },
  kpiV: { fontWeight: 800, lineHeight: 1, fontFamily: 'var(--font-num)', color: 'var(--fg-1)', letterSpacing: '-.01em', fontVariantNumeric: 'tabular-nums' },
  kpiSub: { font: '600 10px/1.2 var(--font-sans)', color: 'var(--fg-4)' },
  healthChip: { display: 'inline-flex', alignItems: 'center', gap: 5, font: '700 10px/1 var(--font-sans)', padding: '4px 7px', borderRadius: 'var(--r-pill)' },
  healthDot: { width: 6, height: 6, borderRadius: '50%', flex: 'none' },

  mini: { background: '#fff', border: '1px solid var(--border-1)', borderRadius: 'var(--r-sm)', padding: '9px 11px', minWidth: 0 },
  miniEye: { font: '700 9px/1.1 var(--font-sans)', letterSpacing: '.04em', textTransform: 'uppercase', color: 'var(--fg-4)' },
  miniVal: { font: '700 15px/1 var(--font-mono)', color: 'var(--fg-1)', marginTop: 7, fontVariantNumeric: 'tabular-nums' },

  dotCard: { background: '#fff', border: '1px solid var(--border-1)', borderRadius: 'var(--r-lg)', padding: '16px 18px', boxShadow: 'var(--shadow-sm)', minWidth: 0 },
  dotTop: { display: 'flex', alignItems: 'center', gap: 8, marginBottom: 12 },
  dot: { width: 9, height: 9, borderRadius: 2, flex: 'none' },
  dotEye: { font: '700 10px/1 var(--font-sans)', letterSpacing: '.05em', textTransform: 'uppercase', color: 'var(--fg-3)' },
  dotVal: { font: '800 24px/1 var(--font-num)', letterSpacing: '-.015em', color: 'var(--fg-1)', fontVariantNumeric: 'tabular-nums', whiteSpace: 'nowrap' },
  dotSub: { font: 'var(--text-caption)', color: 'var(--fg-3)', marginTop: 7 },
};

const hd = {
  empty: { font: '500 12.5px/1.4 var(--font-sans)', color: 'var(--fg-4)', padding: '18px 2px' },
  row: { flex: 1, display: 'flex', alignItems: 'center', gap: 16, minWidth: 0 },
  legend: { flex: 1, display: 'flex', flexDirection: 'column', gap: 6, minWidth: 0 },
  legName: { font: '600 11.5px/1 var(--font-sans)', color: 'var(--fg-1)', flex: 1, minWidth: 0, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' },
  legVal: { font: '600 11px/1 var(--font-mono)', color: 'var(--fg-3)', fontVariantNumeric: 'tabular-nums' },
  capWrap: { paddingTop: 12, minHeight: 20 },
  asideGrid: { display: 'grid', gridTemplateColumns: '140px 1fr', gap: 24, alignItems: 'center' },
};

Object.assign(window, { CleanDonut, IconKpi, MiniCell, DotKpi, HoverDonut });
