/* ============================================================
   CHARTS — visualizaciones SVG (radar, barras, dona, heatmap…)
   Exporta a window: Glyph, Radar, DistBars, Donut, Heatmap,
   EvolBar, HistLines, ScoreBar, RingStat
   ============================================================ */

const IHX = window.IH;
const ARCH = IHX.archetypes;
const COL = Object.fromEntries(ARCH.map(a => [a.id, a.hex]));

/* —— Glifo geométrico abstracto por arquetipo —— */
function Glyph({ id, size = 28, stroke = 2, color }) {
  const c = color || COL[id] || '#888';
  const s = size, m = s / 2;
  const props = { fill: 'none', stroke: c, strokeWidth: stroke, strokeLinecap: 'round', strokeLinejoin: 'round' };
  let body = null;
  switch (id) {
    case 'huerfano': // anillo abierto
      body = <path {...props} d={`M ${m + m*0.62*Math.cos(-0.7)} ${m + m*0.62*Math.sin(-0.7)} A ${m*0.62} ${m*0.62} 0 1 1 ${m + m*0.62*Math.cos(0.7)} ${m + m*0.62*Math.sin(0.7)}`} />;
      break;
    case 'vagabundo': // zigzag
      body = <polyline {...props} points={`${s*0.16},${s*0.62} ${s*0.38},${s*0.36} ${s*0.5},${s*0.58} ${s*0.62},${s*0.34} ${s*0.84},${s*0.6}`} />;
      break;
    case 'martir': // diamante partido
      body = <g {...props}>
        <polygon points={`${m},${s*0.16} ${s*0.78},${m} ${m},${s*0.84} ${s*0.22},${m}`} />
        <line x1={m} y1={s*0.16} x2={m} y2={s*0.84} />
      </g>;
      break;
    case 'guerrero': // triángulo ascendente
      body = <polygon {...props} points={`${m},${s*0.18} ${s*0.82},${s*0.8} ${s*0.18},${s*0.8}`} />;
      break;
    case 'sabio': // concéntrico
      body = <g {...props}>
        <circle cx={m} cy={m} r={s*0.34} />
        <circle cx={m} cy={m} r={s*0.15} />
      </g>;
      break;
    case 'mago': // octograma (dos cuadrados)
      body = <g {...props}>
        <rect x={s*0.22} y={s*0.22} width={s*0.56} height={s*0.56} />
        <rect x={s*0.22} y={s*0.22} width={s*0.56} height={s*0.56} transform={`rotate(45 ${m} ${m})`} />
      </g>;
      break;
    default:
      body = <circle {...props} cx={m} cy={m} r={s*0.3} />;
  }
  return <svg width={s} height={s} viewBox={`0 0 ${s} ${s}`} style={{ display: 'block' }}>{body}</svg>;
}

/* —— RADAR —— series: [{scores, color, fillOpacity, label, dash}] —— */
function Radar({ series = [], size = 360, max = 100, showColoredAxes = true, labels = true, levels = 4 }) {
  const cx = size / 2, cy = size / 2;
  const pad = labels ? 58 : 14;
  const R = size / 2 - pad;
  const ids = IHX.order;
  const N = ids.length;
  const angle = i => (-Math.PI / 2) + (i * 2 * Math.PI / N);
  const pt = (i, r) => [cx + r * Math.cos(angle(i)), cy + r * Math.sin(angle(i))];

  const gridPolys = [];
  for (let l = 1; l <= levels; l++) {
    const r = R * l / levels;
    const pts = ids.map((_, i) => pt(i, r).join(',')).join(' ');
    gridPolys.push(<polygon key={l} points={pts} fill="none" stroke="var(--hair)" strokeWidth="1" />);
  }
  const spokes = ids.map((_, i) => {
    const [x, y] = pt(i, R);
    return <line key={i} x1={cx} y1={cy} x2={x} y2={y} stroke="var(--hair)" strokeWidth="1" />;
  });

  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{ display: 'block', overflow: 'visible' }}>
      {gridPolys}{spokes}
      {/* vértices de color */}
      {showColoredAxes && ids.map((id, i) => {
        const [x, y] = pt(i, R);
        return <circle key={id} cx={x} cy={y} r="3" fill={COL[id]} />;
      })}
      {/* series */}
      {series.map((s, si) => {
        const pts = ids.map((id, i) => pt(i, R * Math.max(0, Math.min(max, s.scores[id])) / max));
        const poly = pts.map(p => p.join(',')).join(' ');
        return (
          <g key={si}>
            <polygon points={poly} fill={s.color} fillOpacity={s.fillOpacity ?? 0.14}
              stroke={s.color} strokeWidth={s.width ?? 2}
              strokeDasharray={s.dash || 'none'}
              style={{ transition: 'all .5s cubic-bezier(.2,.7,.2,1)' }} />
            {(s.dots ?? true) && pts.map((p, i) => (
              <circle key={i} cx={p[0]} cy={p[1]} r="3.5" fill={s.color} stroke="var(--panel)" strokeWidth="1.5" />
            ))}
          </g>
        );
      })}
      {/* etiquetas */}
      {labels && ids.map((id, i) => {
        const [x, y] = pt(i, R + 30);
        const a = ARCH.find(z => z.id === id);
        const anchor = Math.abs(x - cx) < 6 ? 'middle' : (x > cx ? 'start' : 'end');
        return (
          <g key={id}>
            <text x={x} y={y - 3} textAnchor={anchor} fontFamily="var(--sans)" fontSize="12.5"
              fontWeight="600" fill="var(--ink)">{a.name}</text>
          </g>
        );
      })}
    </svg>
  );
}

/* —— Etiqueta de valor en el eje (leyenda compacta) —— */
function AxisLegend({ scores }) {
  return (
    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: '10px 22px' }}>
      {IHX.order.map(id => {
        const a = IHX.byId[id];
        return (
          <div key={id} style={{ display: 'flex', alignItems: 'center', gap: 9 }}>
            <span style={{ width: 9, height: 9, borderRadius: 2, background: a.hex, flex: 'none' }}></span>
            <span style={{ fontSize: 13, color: 'var(--ink-2)', flex: 1 }}>{a.name}</span>
            <span className="mono" style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink)' }}>{scores[id]}%</span>
          </div>
        );
      })}
    </div>
  );
}

/* —— Barra de puntaje horizontal —— */
function ScoreBar({ id, value, max = 100, height = 9, showGlyph = false, animated = true }) {
  const a = IHX.byId[id];
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 12, width: '100%' }}>
      {showGlyph && <Glyph id={id} size={22} stroke={1.6} />}
      <div style={{ flex: 1 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 5 }}>
          <span style={{ fontSize: 13.5, fontWeight: 500 }}>{a.name}</span>
          <span className="mono" style={{ fontSize: 13, fontWeight: 600, color: a.hex }}>{value}%</span>
        </div>
        <div style={{ height, background: 'var(--paper-2)', borderRadius: height, overflow: 'hidden' }}>
          <div style={{ width: `${value}%`, height: '100%', background: a.hex, borderRadius: height,
            transition: animated ? 'width .7s cubic-bezier(.2,.7,.2,1)' : 'none' }}></div>
        </div>
      </div>
    </div>
  );
}

/* —— Distribución: cuántos colaboradores por arquetipo dominante —— */
function DistBars({ dist, total }) {
  const maxV = Math.max(1, ...Object.values(dist));
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
      {IHX.order.map(id => {
        const a = IHX.byId[id];
        const v = dist[id] || 0;
        const pct = Math.round((v / (total || 1)) * 100);
        return (
          <div key={id} style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
            <div style={{ width: 96, display: 'flex', alignItems: 'center', gap: 9 }}>
              <Glyph id={id} size={20} stroke={1.6} />
              <span style={{ fontSize: 13.5, fontWeight: 500 }}>{a.name}</span>
            </div>
            <div style={{ flex: 1, height: 26, background: 'var(--paper-2)', borderRadius: 4, position: 'relative', overflow: 'hidden' }}>
              <div style={{ width: `${(v / maxV) * 100}%`, height: '100%', background: a.hex, opacity: 0.9,
                borderRadius: 4, transition: 'width .7s cubic-bezier(.2,.7,.2,1)' }}></div>
            </div>
            <div className="mono" style={{ width: 78, textAlign: 'right', fontSize: 13 }}>
              <span style={{ fontWeight: 600, color: 'var(--ink)' }}>{v}</span>
              <span style={{ color: 'var(--ink-3)' }}> · {pct}%</span>
            </div>
          </div>
        );
      })}
    </div>
  );
}

/* —— Dona de distribución —— */
function Donut({ dist, total, size = 200, thickness = 26 }) {
  const cx = size / 2, cy = size / 2, r = (size - thickness) / 2;
  const circ = 2 * Math.PI * r;
  let acc = 0;
  const segs = IHX.order.map(id => {
    const v = dist[id] || 0;
    const frac = total ? v / total : 0;
    const seg = { id, frac, off: acc };
    acc += frac;
    return seg;
  });
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{ display: 'block' }}>
      <circle cx={cx} cy={cy} r={r} fill="none" stroke="var(--paper-2)" strokeWidth={thickness} />
      {segs.map(s => (
        <circle key={s.id} cx={cx} cy={cy} r={r} fill="none" stroke={COL[s.id]} strokeWidth={thickness}
          strokeDasharray={`${s.frac * circ} ${circ}`} strokeDashoffset={-s.off * circ}
          transform={`rotate(-90 ${cx} ${cy})`} style={{ transition: 'stroke-dasharray .6s ease' }} />
      ))}
      <text x={cx} y={cy - 4} textAnchor="middle" fontFamily="var(--serif)" fontSize="30" fontWeight="600" fill="var(--ink)">{total}</text>
      <text x={cx} y={cy + 16} textAnchor="middle" fontFamily="var(--mono)" fontSize="10" letterSpacing="0.1em" fill="var(--ink-3)">EVALUADOS</text>
    </svg>
  );
}

/* —— Mapa de calor organizacional (área × arquetipo) —— */
function Heatmap({ areaMap }) {
  const areas = Object.keys(areaMap);
  const ids = IHX.order;
  const cell = (v) => {
    // 0..100 → opacidad
    return Math.max(0.06, Math.min(1, v / 100));
  };
  return (
    <div style={{ overflowX: 'auto' }}>
      <table style={{ borderCollapse: 'separate', borderSpacing: 4, width: '100%' }}>
        <thead>
          <tr>
            <th style={{ textAlign: 'left', padding: '0 10px 8px 0', fontSize: 11, fontFamily: 'var(--mono)', color: 'var(--ink-3)', letterSpacing: '0.08em', textTransform: 'uppercase', fontWeight: 500 }}>Área</th>
            {ids.map(id => (
              <th key={id} style={{ padding: '0 0 8px', textAlign: 'center' }}>
                <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4 }}>
                  <Glyph id={id} size={18} stroke={1.6} />
                  <span style={{ fontSize: 10.5, color: 'var(--ink-2)', fontWeight: 500 }}>{IHX.byId[id].name}</span>
                </div>
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {areas.map(ar => (
            <tr key={ar}>
              <td style={{ fontSize: 13, fontWeight: 500, paddingRight: 12, whiteSpace: 'nowrap' }}>{ar}
                <span className="mono" style={{ color: 'var(--ink-3)', fontWeight: 400, marginLeft: 6, fontSize: 11 }}>n={areaMap[ar].n}</span>
              </td>
              {ids.map(id => {
                const v = areaMap[ar].scores[id];
                const op = cell(v);
                const light = op > 0.62;
                return (
                  <td key={id} style={{ textAlign: 'center' }}>
                    <div title={`${ar} · ${IHX.byId[id].name}: ${v}%`}
                      style={{ background: COL[id], opacity: op === 1 ? 1 : undefined,
                        backgroundColor: COL[id], position: 'relative',
                        borderRadius: 5, height: 40, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                      <span style={{ position: 'absolute', inset: 0, background: COL[id], opacity: op, borderRadius: 5 }}></span>
                      <span className="mono" style={{ position: 'relative', fontSize: 12.5, fontWeight: 600,
                        color: light ? '#fff' : 'var(--ink-2)' }}>{v}</span>
                    </div>
                  </td>
                );
              })}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

/* —— Ranking de evolución por área —— */
function EvolRanking({ rows }) {
  const maxV = 100;
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 13 }}>
      {rows.map((r, i) => (
        <div key={r.area} style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
          <span className="mono" style={{ width: 22, fontSize: 13, color: 'var(--ink-3)', fontWeight: 600 }}>{String(i + 1).padStart(2, '0')}</span>
          <span style={{ width: 132, fontSize: 14, fontWeight: 500 }}>{r.area}</span>
          <div style={{ flex: 1, height: 10, background: 'var(--paper-2)', borderRadius: 10, overflow: 'hidden' }}>
            <div style={{ width: `${r.evol}%`, height: '100%', borderRadius: 10,
              background: `linear-gradient(90deg, var(--a-guerrero), var(--a-sabio))`,
              transition: 'width .7s cubic-bezier(.2,.7,.2,1)' }}></div>
          </div>
          <span className="mono" style={{ width: 46, textAlign: 'right', fontSize: 14, fontWeight: 600, color: 'var(--ink)' }}>{r.evol}</span>
        </div>
      ))}
    </div>
  );
}

/* —— Comparación histórica (líneas/área del índice + arquetipos) —— */
function HistLines({ hist, width = 520, height = 200 }) {
  const pad = { t: 16, r: 16, b: 30, l: 30 };
  const W = width - pad.l - pad.r, H = height - pad.t - pad.b;
  const xs = hist.map((_, i) => pad.l + (hist.length === 1 ? W / 2 : i * W / (hist.length - 1)));
  const y = v => pad.t + H - (v / 100) * H;
  const ids = IHX.order;
  return (
    <svg width="100%" viewBox={`0 0 ${width} ${height}`} style={{ display: 'block', overflow: 'visible' }}>
      {[0, 25, 50, 75, 100].map(g => (
        <g key={g}>
          <line x1={pad.l} y1={y(g)} x2={width - pad.r} y2={y(g)} stroke="var(--hair)" strokeWidth="1" />
          <text x={pad.l - 8} y={y(g) + 3} textAnchor="end" fontFamily="var(--mono)" fontSize="9" fill="var(--ink-3)">{g}</text>
        </g>
      ))}
      {ids.map(id => {
        const d = hist.map((h, i) => `${xs[i]},${y(h.scores[id])}`).join(' ');
        return <polyline key={id} points={d} fill="none" stroke={COL[id]} strokeWidth="1.5" opacity="0.5" />;
      })}
      {/* índice de evolución resaltado */}
      <polyline points={hist.map((h, i) => `${xs[i]},${y(h.evol)}`).join(' ')} fill="none"
        stroke="var(--gold)" strokeWidth="3" />
      {hist.map((h, i) => <circle key={i} cx={xs[i]} cy={y(h.evol)} r="4.5" fill="var(--gold)" stroke="var(--panel)" strokeWidth="1.5" />)}
      {hist.map((h, i) => (
        <text key={i} x={xs[i]} y={height - 10} textAnchor="middle" fontFamily="var(--sans)" fontSize="11" fill="var(--ink-2)" fontWeight="500">{h.periodo.replace(' anterior', ' ant.')}</text>
      ))}
    </svg>
  );
}

/* —— Anillo estadístico (índice de evolución) —— */
function RingStat({ value, label, size = 132, color = 'var(--gold)' }) {
  const r = (size - 14) / 2, circ = 2 * Math.PI * r, cx = size / 2;
  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8 }}>
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
        <circle cx={cx} cy={cx} r={r} fill="none" stroke="var(--paper-2)" strokeWidth="11" />
        <circle cx={cx} cy={cx} r={r} fill="none" stroke={color} strokeWidth="11" strokeLinecap="round"
          strokeDasharray={`${(value / 100) * circ} ${circ}`} transform={`rotate(-90 ${cx} ${cx})`}
          style={{ transition: 'stroke-dasharray .8s cubic-bezier(.2,.7,.2,1)' }} />
        <text x={cx} y={cx - 2} textAnchor="middle" fontFamily="var(--serif)" fontSize="34" fontWeight="600" fill="var(--ink)">{value}</text>
        <text x={cx} y={cx + 18} textAnchor="middle" fontFamily="var(--mono)" fontSize="9" fill="var(--ink-3)" letterSpacing="0.1em">/ 100</text>
      </svg>
      {label && <span className="eyebrow" style={{ textAlign: 'center' }}>{label}</span>}
    </div>
  );
}

Object.assign(window, { Glyph, Radar, AxisLegend, ScoreBar, DistBars, Donut, Heatmap, EvolRanking, HistLines, RingStat, COL });
