// ── Inova Cotação — primitivos compartilhados ───────────────────────────
const { useState, useEffect, useRef, useMemo } = React;

// Paletas (vermelho / branco / preto · claro & escuro)
const DARK = {
  bg: '#020203', bg2: '#070708', stage: '#020203', surface: '#141416', surface2: '#19191C',
  headerBg: 'rgba(0,0,0,0.5)',
  panel: 'rgba(255,255,255,0.045)', panelHi: 'rgba(255,255,255,0.07)',
  border: 'rgba(255,255,255,0.10)', borderHi: 'rgba(255,255,255,0.18)',
  text: '#F7F7F8', mute: '#8A8A92', mute2: '#5C5C63',
  red: '#FF1330', redBright: '#FF3B54', redDeep: '#C00016',
  green: '#00E68C', greenBg: 'rgba(0,230,140,0.14)', redBg: 'rgba(255,19,48,0.15)',
  yellow: '#FFC83D', yellowBg: 'rgba(255,200,61,0.14)', blue: '#3B82F6', blueBg: 'rgba(59,130,246,0.14)',
  glassGrad: 'linear-gradient(180deg, rgba(255,255,255,0.055), rgba(255,255,255,0.02))',
  glassTop: 'linear-gradient(90deg, transparent, rgba(255,255,255,0.18), transparent)',
  cardShadow: '0 1px 2px rgba(0,0,0,0.35)', cardShadowHover: '0 6px 22px rgba(0,0,0,0.45)',
};
const LIGHT = {
  bg: '#F2F2F6', bg2: '#FFFFFF', stage: '#E4E4EA', surface: '#FFFFFF', surface2: '#FFFFFF',
  headerBg: 'rgba(252,252,254,0.82)',
  panel: '#F7F7FA', panelHi: '#EFEFF4',
  border: 'rgba(18,18,30,0.09)', borderHi: 'rgba(18,18,30,0.16)',
  text: '#15151C', mute: '#62626E', mute2: '#9D9DA9',
  red: '#E60022', redBright: '#FF1330', redDeep: '#B80018',
  green: '#00935A', greenBg: 'rgba(0,147,90,0.10)', redBg: 'rgba(230,0,34,0.07)',
  yellow: '#A8730A', yellowBg: 'rgba(255,183,0,0.16)', blue: '#2563EB', blueBg: 'rgba(37,99,235,0.10)',
  glassGrad: 'linear-gradient(180deg, #FFFFFF, #FCFCFE)',
  glassTop: 'linear-gradient(90deg, transparent, rgba(230,0,34,0.18), transparent)',
  cardShadow: '0 1px 2px rgba(18,18,40,0.04), 0 6px 20px rgba(18,18,40,0.06)',
  cardShadowHover: '0 2px 6px rgba(18,18,40,0.06), 0 10px 26px rgba(18,18,40,0.10)',
  pillMuteBg: 'rgba(18,18,30,0.05)', pillWhiteBg: 'rgba(18,18,30,0.07)',
  glow: 0.05,
  barNeutral: 'linear-gradient(180deg, #BFBFCC, #DCDCE4)', trackNeutral: 'rgba(18,18,30,0.10)',
};
const DARK2 = { pillMuteBg: 'rgba(255,255,255,0.06)', pillWhiteBg: 'rgba(255,255,255,0.1)', glow: 0.10, barNeutral: 'linear-gradient(180deg, rgba(255,255,255,0.26), rgba(255,255,255,0.08))', trackNeutral: 'rgba(255,255,255,0.1)' };
Object.assign(DARK, DARK2);
const T = { ...DARK };
// Acento de cor (tweak) — sobrepõe a família "red" do tema
const ACCENTS = {
  inova:     null, // usa o vermelho próprio de cada tema
  esmeralda: { red: '#00C271', redBright: '#22E08C', redDeep: '#039356' },
  dual:      { red: '#FF1330', redBright: '#FF3B54', redDeep: '#0A8F58' },
};
function applyAccent(mode) {
  window.__accent = ACCENTS.hasOwnProperty(mode) ? mode : 'inova';
  if (window.__accent !== 'inova' && ACCENTS[window.__accent]) Object.assign(T, ACCENTS[window.__accent]);
  if (window.__accent === 'esmeralda') T.redBg = 'rgba(0,194,113,0.14)';
}
window.applyAccent = applyAccent;
function setTheme(mode) {
  Object.assign(T, mode === 'light' ? LIGHT : DARK);
  window.__theme = mode;
  try { localStorage.setItem('inova-theme', mode); } catch (e) {}
  applyAccent(window.__accent || 'inova');
  if (typeof document !== 'undefined') { document.body.style.background = T.bg; document.body.style.color = T.text; }
}
window.setTheme = setTheme;
window.__theme = (() => { try { return localStorage.getItem('inova-theme') || 'dark'; } catch (e) { return 'dark'; } })();
if (window.__theme === 'light') Object.assign(T, LIGHT);

// ── Ícones (stroke, 1.6) ────────────────────────────────────────────────
function Icon({ name, size = 20, color = 'currentColor', strokeWidth = 1.6, style }) {
  const p = { fill: 'none', stroke: color, strokeWidth, strokeLinecap: 'round', strokeLinejoin: 'round' };
  const paths = {
    grid:    <><rect x="3" y="3" width="7" height="7" rx="1.5" {...p}/><rect x="14" y="3" width="7" height="7" rx="1.5" {...p}/><rect x="3" y="14" width="7" height="7" rx="1.5" {...p}/><rect x="14" y="14" width="7" height="7" rx="1.5" {...p}/></>,
    chart:   <><path d="M3 3v18h18" {...p}/><path d="M7 15l3-4 3 2 5-7" {...p}/></>,
    list:    <><path d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01" {...p}/></>,
    table:   <><rect x="3" y="4" width="18" height="16" rx="2" {...p}/><path d="M3 9h18M9 9v11" {...p}/></>,
    box:     <><path d="M21 8l-9-5-9 5v8l9 5 9-5V8z" {...p}/><path d="M3 8l9 5 9-5M12 13v8" {...p}/></>,
    plus:    <><path d="M12 5v14M5 12h14" {...p}/></>,
    bell:    <><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9" {...p}/><path d="M13.7 21a2 2 0 0 1-3.4 0" {...p}/></>,
    refresh: <><path d="M21 12a9 9 0 1 1-3-6.7L21 8M21 3v5h-5" {...p}/></>,
    search:  <><circle cx="11" cy="11" r="7" {...p}/><path d="M21 21l-4-4" {...p}/></>,
    filter:  <><path d="M3 5h18l-7 8v6l-4-2v-4L3 5z" {...p}/></>,
    arrowDown:<><path d="M12 5v14M19 12l-7 7-7-7" {...p}/></>,
    arrowUp: <><path d="M12 19V5M5 12l7-7 7 7" {...p}/></>,
    check:   <><path d="M20 6L9 17l-5-5" {...p}/></>,
    clock:   <><circle cx="12" cy="12" r="9" {...p}/><path d="M12 7v5l3 2" {...p}/></>,
    send:    <><path d="M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z" {...p}/></>,
    user:    <><circle cx="12" cy="8" r="4" {...p}/><path d="M4 21c0-4 4-6 8-6s8 2 8 6" {...p}/></>,
    tag:     <><path d="M3 3h7l11 11-7 7L3 10V3z" {...p}/><circle cx="7.5" cy="7.5" r="1.3" fill={color} stroke="none"/></>,
    trophy:  <><path d="M8 21h8M12 17v4M6 4h12v5a6 6 0 0 1-12 0V4z" {...p}/><path d="M6 6H3v2a3 3 0 0 0 3 3M18 6h3v2a3 3 0 0 1-3 3" {...p}/></>,
    bolt:    <><path d="M13 2L4 14h7l-1 8 9-12h-7l1-8z" {...p}/></>,
    chevron: <><path d="M9 6l6 6-6 6" {...p}/></>,
    x:       <><path d="M18 6L6 18M6 6l12 12" {...p}/></>,
    shield:  <><path d="M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6l8-3z" {...p}/><path d="M9 12l2 2 4-4" {...p}/></>,
    receipt: <><path d="M5 3v18l2-1 2 1 2-1 2 1 2-1 2 1V3l-2 1-2-1-2 1-2-1-2 1-2-1z" {...p}/><path d="M9 8h6M9 12h6" {...p}/></>,
    calendar:<><rect x="3" y="5" width="18" height="16" rx="2" {...p}/><path d="M3 9h18M8 3v4M16 3v4" {...p}/></>,
    telegram:<><path d="M22 3L2 11l6 2 2 6 3-4 5 4 4-16z" {...p}/><path d="M8 13l9-6-6 8" {...p}/></>,
    whatsapp:<><path d="M3.5 20.5l1.2-4.2A8 8 0 1 1 8 19.3l-4.5 1.2z" {...p}/><path d="M9 9.5c0 3 2.5 5.5 5.5 5.5.6 0 .9-.6.6-1.1l-.8-1.2-1.6.6c-1-.5-1.8-1.3-2.3-2.3l.6-1.6-1.2-.8c-.5-.3-1.1 0-1.1.6z" {...p}/></>,
    logout:  <><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4M16 17l5-5-5-5M21 12H9" {...p}/></>,
    sparkle: <><path d="M12 3l1.6 5.4L19 10l-5.4 1.6L12 17l-1.6-5.4L5 10l5.4-1.6L12 3z" {...p}/></>,
    pill:    <><rect x="3" y="9" width="18" height="6" rx="3" transform="rotate(45 12 12)" {...p}/><path d="M8.5 8.5l7 7" {...p}/></>,
    dumbbell:<><path d="M6 7v10M3 9v6M18 7v10M21 9v6M6 12h12" {...p}/></>,
    drop:    <><path d="M12 3s6 6.5 6 11a6 6 0 0 1-12 0c0-4.5 6-11 6-11z" {...p}/></>,
    baby:    <><circle cx="12" cy="8" r="4" {...p}/><path d="M9 7h.01M15 7h.01M10 10c1 1 3 1 4 0M5 21c1-4 4-6 7-6s6 2 7 6" {...p}/></>,
    star:    <path d="M12 3l2.5 5.5L20 9.5l-4 4 1 6-5-3-5 3 1-6-4-4 5.5-1L12 3z" fill={color} stroke="none"/>,
    sun:     <><circle cx="12" cy="12" r="4.2" {...p}/><path d="M12 2v2M12 20v2M2 12h2M20 12h2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M19.1 4.9l-1.4 1.4M6.3 17.7l-1.4 1.4" {...p}/></>,
    moon:    <path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z" {...p}/>,
    paperclip:<path d="M21 11l-8.5 8.5a5 5 0 0 1-7-7L14 4a3.5 3.5 0 0 1 5 5l-8.5 8.5a2 2 0 0 1-3-3L15 6" {...p}/>,
    pin:     <><path d="M12 17v5" {...p}/><path d="M9 3h6l-1 6 3 3v2H7v-2l3-3-1-6z" {...p}/></>,
    play:    <path d="M7 4v16l13-8L7 4z" fill={color} stroke="none"/>,
    mic:     <><rect x="9" y="3" width="6" height="11" rx="3" {...p}/><path d="M5 11a7 7 0 0 0 14 0M12 18v3" {...p}/></>,
    image:   <><rect x="3" y="4" width="18" height="16" rx="2" {...p}/><circle cx="9" cy="9" r="1.6" {...p}/><path d="M21 16l-5-5L5 20" {...p}/></>,
    file:    <><path d="M14 3v5h5" {...p}/><path d="M7 3h7l5 5v11a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z" {...p}/></>,
    plusGrid:<><path d="M12 5v14M5 12h14" {...p}/></>,
  };
  return <svg width={size} height={size} viewBox="0 0 24 24" style={style}>{paths[name] || null}</svg>;
}

// ── Glass card ──────────────────────────────────────────────────────────
function Glass({ children, style, hover, onClick, pad = 20, className }) {
  const [h, setH] = useState(false);
  return (
    <div onClick={onClick} className={className}
      onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
      style={{
        position: 'relative', borderRadius: 13, padding: pad,
        background: T.glassGrad,
        border: `1px solid ${h && hover ? T.borderHi : T.border}`,
        backdropFilter: 'blur(20px) saturate(140%)', WebkitBackdropFilter: 'blur(20px) saturate(140%)',
        boxShadow: h && hover ? T.cardShadowHover : T.cardShadow,
        cursor: onClick ? 'pointer' : 'default',
        transition: 'border-color .2s, box-shadow .2s, transform .2s',
        transform: h && hover ? 'translateY(-1px)' : 'none',
        overflow: 'hidden', ...style,
      }}>
      <div style={{ position: 'absolute', top: 0, left: 0, right: 0, height: 1, background: T.glassTop }} />
      {children}
    </div>
  );
}

// Selo de status
function Pill({ children, tone = 'mute', style }) {
  const map = {
    red:   { bg: T.redBg, fg: T.redBright, bd: 'rgba(255,19,48,0.35)' },
    green: { bg: T.greenBg, fg: T.green, bd: 'rgba(0,230,140,0.35)' },
    yellow:{ bg: T.yellowBg, fg: T.yellow, bd: 'rgba(255,200,61,0.4)' },
    mute:  { bg: T.pillMuteBg, fg: T.mute, bd: T.border },
    white: { bg: T.pillWhiteBg, fg: T.text, bd: T.borderHi },
  };
  const c = map[tone];
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 5,
      padding: '3px 9px', borderRadius: 999, fontSize: 11.5, fontWeight: 700,
      letterSpacing: 0.2, background: c.bg, color: c.fg, border: `1px solid ${c.bd}`,
      whiteSpace: 'nowrap', ...style,
    }}>{children}</span>
  );
}

// Delta com seta (verde p/ baixo = bom, vermelho p/ cima = ruim, amarelo ~0 = neutro)
function Delta({ pct, size = 12.5 }) {
  if (pct == null) return <span style={{ color: T.mute2 }}>—</span>;
  // igual ao custo (diferença zero) → amarelo com "="
  if (pct === 0 || Math.abs(pct) < 0.005) return <span style={{ display: 'inline-flex', alignItems: 'center', gap: 3, color: T.yellow, fontWeight: 800, fontSize: size, fontVariantNumeric: 'tabular-nums' }}>= 0,0%</span>;
  const down = pct < 0; // mais barato = bom
  const c = down ? T.green : T.redBright;
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 2, color: c, fontWeight: 800, fontSize: size, fontVariantNumeric: 'tabular-nums' }}>
      <Icon name={down ? 'arrowDown' : 'arrowUp'} size={size + 2} color={c} strokeWidth={2.4} />
      {Math.abs(pct).toFixed(1)}%
    </span>
  );
}

// ── Gráfico de barras ───────────────────────────────────────────────────
function BarChart({ data, height = 200 }) {
  const max = Math.max(...data.map(d => d.value));
  return (
    <div style={{ display: 'flex', alignItems: 'flex-end', gap: 18, height, paddingTop: 10 }}>
      {data.map((d, i) => {
        const h = (d.value / max) * (height - 36);
        return (
          <div key={i} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8, height: '100%', justifyContent: 'flex-end' }}>
            <div style={{ fontSize: 12, fontWeight: 700, color: T.text, fontVariantNumeric: 'tabular-nums' }}>{window.IC.fmtK(d.value)}</div>
            <div style={{
              width: '100%', maxWidth: 54, height: h, borderRadius: '7px 7px 3px 3px',
              background: i === 1 ? `linear-gradient(180deg, ${T.redBright}, ${T.redDeep})` : T.panelHi,
              boxShadow: 'none',
              transition: 'height .6s cubic-bezier(.2,.8,.2,1)',
            }} />
            <div style={{ fontSize: 11, color: T.mute, textAlign: 'center', lineHeight: 1.2, height: 26 }}>{d.cat}</div>
          </div>
        );
      })}
    </div>
  );
}

// ── Gráfico de linha (variação de custo) ────────────────────────────────
function LineChart({ data, height = 200 }) {
  const w = 560, pad = 28;
  const ys = data.map(d => d.idx);
  const min = Math.min(...ys) - 1, max = Math.max(...ys) + 1;
  const X = i => pad + (i / (data.length - 1)) * (w - pad * 2);
  const Y = v => (height - 30) - ((v - min) / (max - min)) * (height - 56);
  const pts = data.map((d, i) => [X(i), Y(d.idx)]);
  const line = pts.map((p, i) => (i ? 'L' : 'M') + p[0] + ' ' + p[1]).join(' ');
  const area = line + ` L ${X(data.length-1)} ${height-30} L ${X(0)} ${height-30} Z`;
  return (
    <svg viewBox={`0 0 ${w} ${height}`} style={{ width: '100%', height }}>
      <defs>
        <linearGradient id="lg" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor={T.redBright} stopOpacity="0.35" />
          <stop offset="100%" stopColor={T.redBright} stopOpacity="0" />
        </linearGradient>
      </defs>
      {[0,1,2,3].map(g => <line key={g} x1={pad} x2={w-pad} y1={20 + g*((height-50)/3)} y2={20 + g*((height-50)/3)} stroke={T.border} strokeWidth="1" />)}
      <path d={area} fill="url(#lg)" />
      <path d={line} fill="none" stroke={T.redBright} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" />
      {pts.map((p, i) => (
        <g key={i}>
          <circle cx={p[0]} cy={p[1]} r="3.5" fill={T.bg} stroke={T.redBright} strokeWidth="2" />
          <text x={p[0]} y={height-10} fill={T.mute} fontSize="11" textAnchor="middle" fontFamily="inherit">{data[i].wk}</text>
        </g>
      ))}
    </svg>
  );
}

// ── Número animado (count up) ───────────────────────────────────────────
function CountUp({ value, prefix = '', suffix = '', decimals = 0, dur = 1100, style }) {
  const [v, setV] = useState(0);
  const ref = useRef();
  useEffect(() => {
    let raf, start;
    const from = ref.current ?? 0;
    const step = (t) => {
      if (!start) start = t;
      const p = Math.min(1, (t - start) / dur);
      const e = 1 - Math.pow(1 - p, 3);
      setV(from + (value - from) * e);
      if (p < 1) raf = requestAnimationFrame(step); else ref.current = value;
    };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, [value]);
  return <span style={style}>{prefix}{v.toLocaleString('pt-BR', { minimumFractionDigits: decimals, maximumFractionDigits: decimals })}{suffix}</span>;
}

// ── Donut / Pizza ───────────────────────────────────────────────────────
function Donut({ data, size = 168, thickness = 30 }) {
  const total = data.reduce((s, d) => s + d.value, 0);
  const r = (size - thickness) / 2, cx = size / 2, cy = size / 2, C = 2 * Math.PI * r;
  let acc = 0;
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 22 }}>
      <svg width={size} height={size} style={{ transform: 'rotate(-90deg)', flexShrink: 0 }}>
        <circle cx={cx} cy={cy} r={r} fill="none" stroke={T.panelHi} strokeWidth={thickness} />
        {data.map((d, i) => {
          const frac = d.value / total, len = frac * C;
          const el = <circle key={i} cx={cx} cy={cy} r={r} fill="none" stroke={d.color} strokeWidth={thickness}
            strokeDasharray={`${len} ${C - len}`} strokeDashoffset={-acc} strokeLinecap="butt"
            style={{ transition: 'stroke-dasharray .9s cubic-bezier(.2,.8,.2,1)' }} />;
          acc += len; return el;
        })}
        <circle cx={cx} cy={cy} r={r - thickness/2 - 2} fill={T.surface} />
      </svg>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 9, flex: 1 }}>
        {data.map((d, i) => (
          <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 9, fontSize: 12.5 }}>
            <span style={{ width: 11, height: 11, borderRadius: 3, background: d.color, flexShrink: 0 }} />
            <span style={{ flex: 1, color: T.mute }}>{d.label}</span>
            <span style={{ fontWeight: 700, color: T.text, fontVariantNumeric: 'tabular-nums' }}>{Math.round(d.value / total * 100)}%</span>
          </div>
        ))}
      </div>
    </div>
  );
}

// ── Barras horizontais (ranking) ────────────────────────────────────────
function HBars({ data }) {
  const max = Math.max(...data.map(d => d.value));
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 13 }}>
      {data.map((d, i) => (
        <div key={i}>
          <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 12.5, marginBottom: 5 }}>
            <span style={{ color: T.text, fontWeight: 600 }}>{d.label}</span>
            <span style={{ color: T.mute, fontVariantNumeric: 'tabular-nums' }}>{d.display ?? d.value}</span>
          </div>
          <div style={{ height: 9, borderRadius: 99, background: T.panelHi, overflow: 'hidden' }}>
            <div style={{ width: (d.value / max * 100) + '%', height: '100%', borderRadius: 99, background: d.color || `linear-gradient(90deg, ${T.redBright}, ${T.redDeep})`, transition: 'width .9s cubic-bezier(.2,.8,.2,1)' }} />
          </div>
        </div>
      ))}
    </div>
  );
}

// ── Sparkline (mini histórico) ──────────────────────────────────────────
function SparkLine({ data, w = 86, h = 26, color }) {
  if (!data || data.length < 2) return null;
  const min = Math.min(...data), max = Math.max(...data), rng = max - min || 1;
  const X = i => (i / (data.length - 1)) * w;
  const Y = v => h - 3 - ((v - min) / rng) * (h - 6);
  const d = data.map((v, i) => (i ? 'L' : 'M') + X(i).toFixed(1) + ' ' + Y(v).toFixed(1)).join(' ');
  const down = data[data.length - 1] <= data[0];
  const c = color || (down ? T.green : T.redBright);
  return (
    <svg width={w} height={h} style={{ display: 'block' }}>
      <path d={d} fill="none" stroke={c} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
      <circle cx={X(data.length - 1)} cy={Y(data[data.length - 1])} r="2.2" fill={c} />
    </svg>
  );
}

Object.assign(window, { T, Icon, Glass, Pill, Delta, BarChart, LineChart, CountUp, Donut, HBars, SparkLine });
