// -----------------------------------------------------------------
// Charts — Core 2.0-aesthetic data-viz primitives.
//
// Rules the charts follow (anti-slop):
//   • Minimal chrome: no borders, no drop-shadows, hair y-axis only where useful.
//   • Colors come from tokens.css --chart-* variables; no gradients on data.
//   • Numbers use --font-mono for tabular alignment.
//   • No decorative animation.
// -----------------------------------------------------------------


// -----------------------------------------------------------------
// BarPair — planned vs actual paired bars per week.
//    data: [{ label: 'W1', planned: 8, actual: 5 }, ...]
// Values are 0-100. Bars sit on a shared 0 baseline; the two series
// per week share x-space, planned in muted tone behind actual in
// accent tone (planned is a "ghost" fill).
// -----------------------------------------------------------------
function BarPair({ data, height = 140, maxValue }) {
  // Defensive: allow this chart to render an empty state without crashing.
  const safeData = Array.isArray(data) ? data : [];
  const w = 640, h = height;
  const padX = 28, padTop = 12, padBottom = 22;
  const chartW = w - padX * 2;
  const chartH = h - padTop - padBottom;
  if (safeData.length === 0) {
    return <svg viewBox={`0 0 ${w} ${h}`} className="chart chart-barpair" aria-label="No data"/>;
  }
  const max = maxValue ?? Math.max(
    ...safeData.flatMap(d => [Number(d.planned) || 0, Number(d.actual) || 0]),
    1
  ) * 1.15;
  const bandW = chartW / safeData.length;
  const barW = Math.min(14, bandW / 3);

  const y = v => padTop + chartH - (v / max) * chartH;

  return (
    <svg viewBox={`0 0 ${w} ${h}`} className="chart chart-barpair" role="img" aria-label="Planned vs actual progress">
      {/* baseline */}
      <line x1={padX} x2={w - padX} y1={padTop + chartH} y2={padTop + chartH}
            stroke="var(--stroke-subtle)" strokeWidth="1" />

      {/* gridlines at 25/50/75 (very faint) */}
      {[0.25, 0.5, 0.75].map((t, i) => (
        <line key={i}
              x1={padX} x2={w - padX}
              y1={padTop + chartH * (1 - t)} y2={padTop + chartH * (1 - t)}
              stroke="var(--stroke-subtle)" strokeWidth="1" strokeDasharray="2 4" />
      ))}

      {/* bars */}
      {data.map((d, i) => {
        const bx = padX + i * bandW + bandW / 2;
        return (
          <g key={i}>
            {/* planned = ghost fill behind */}
            <rect x={bx - barW}    y={y(d.planned)} width={barW * 2} height={padTop + chartH - y(d.planned)}
                  rx="4"
                  fill="var(--chart-min)" opacity="0.9" />
            {/* actual = solid over */}
            <rect x={bx - barW / 2} y={y(d.actual)} width={barW}     height={padTop + chartH - y(d.actual)}
                  rx="4"
                  fill="var(--chart-blue)" />
            {/* x-label */}
            <text x={bx} y={h - 6} textAnchor="middle"
                  fontSize="10" fontFamily="var(--font-mono)"
                  fill="var(--text-tertiary)" letterSpacing="0.02em">
              {d.label}
            </text>
          </g>
        );
      })}
    </svg>
  );
}


// -----------------------------------------------------------------
// StackedProgressList — workstream readiness.
//    rows: [{ label: 'Product & Scope', percent: 85, tone: 'blue' }, ...]
// A calm list of thin fill bars with the label + mono % on either side.
// -----------------------------------------------------------------
function StackedProgressList({ rows, dense = false }) {
  const safeRows = Array.isArray(rows) ? rows : [];
  return (
    <div className={`spl${dense ? ' spl-dense' : ''}`}>
      {safeRows.map((r, i) => {
        const tone = (window.MYGENI_MISSION_TONES || {})[r.tone] || { fg: 'var(--chart-blue)', track: 'rgba(42,133,255,0.16)' };
        return (
          <div className="spl-row" key={i}>
            <div className="spl-label">
              {r.icon && <Icon name={r.icon} size={12} strokeWidth={1.75} style={{ color: tone.fg }} />}
              <span>{r.label}</span>
            </div>
            <div className="spl-track" style={{ background: tone.track }}>
              <div className="spl-fill" style={{ width: `${r.percent}%`, background: tone.fg }} />
            </div>
            <div className="spl-value mono">{r.percent}%</div>
          </div>
        );
      })}
    </div>
  );
}


// -----------------------------------------------------------------
// HorizontalStages — the shared journey visualization.
//    stages: [{ n, name, status: 'done'|'now'|'upcoming'|'blocked', short?: '' }]
// Configurable per-node state. Used by Home Momentum + Overview + Stage v2.
// -----------------------------------------------------------------
function HorizontalStages({ stages, dense = false, showLabels = true, onNodeClick, active }) {
  const safeStages = Array.isArray(stages) ? stages : [];
  return (
    <div className={`hstages${dense ? ' hstages-dense' : ''}`} role="list">
      {safeStages.map((s, i) => {
        const isFirst = i === 0;
        const isLast  = i === safeStages.length - 1;
        const isActive = active === s.n;
        return (
          <React.Fragment key={s.n}>
            <button
              className={`hs-node hs-${s.status}${isActive ? ' hs-active' : ''}`}
              onClick={onNodeClick ? () => onNodeClick(s) : undefined}
              role="listitem"
              aria-label={`Stage ${s.n}: ${s.name} (${s.status})`}
              tabIndex={onNodeClick ? 0 : -1}
              type="button"
            >
              <div className="hs-glyph">
                {s.status === 'done'     && <Icon name="check" size={12} strokeWidth={2.5} />}
                {s.status === 'now'      && <span className="hs-dot" />}
                {s.status === 'upcoming' && <span className="hs-hint" />}
                {s.status === 'blocked'  && <span className="hs-block" />}
              </div>
              {showLabels && (
                <div className="hs-text">
                  <div className="hs-num mono">Stage {String(s.n).padStart(2, '0')}</div>
                  <div className="hs-name">{s.name}</div>
                </div>
              )}
            </button>
            {!isLast && (
              <div className={`hs-conn ${s.status === 'done' ? 'hs-conn-done' : (safeStages[i + 1] && safeStages[i + 1].status === 'now') ? 'hs-conn-toNow' : 'hs-conn-up'}`} />
            )}
          </React.Fragment>
        );
      })}
    </div>
  );
}


// -----------------------------------------------------------------
// Sparkline — small area line for cards.
//    values: [n, n, n, ...] between 0 and any max.
// -----------------------------------------------------------------
// Renamed to avoid colliding with the existing components.jsx Sparkline({points, color}).
function ChartSparkline({ values, width = 120, height = 32, tone = 'blue' }) {
  const safeValues = Array.isArray(values) && values.length > 0 ? values : [0, 0];
  const max = Math.max(...safeValues, 1);
  const min = Math.min(...safeValues, 0);
  const range = Math.max(max - min, 1);
  const stepX = width / Math.max(1, safeValues.length - 1);
  const pts   = safeValues.map((v, i) => [i * stepX, height - ((v - min) / range) * (height - 4) - 2]);
  const line  = pts.map((p, i) => `${i === 0 ? 'M' : 'L'} ${p[0].toFixed(1)} ${p[1].toFixed(1)}`).join(' ');
  const area  = `${line} L ${width} ${height} L 0 ${height} Z`;
  const color = tone === 'green' ? 'var(--chart-green)'
              : tone === 'red'   ? 'var(--danger-solid)'
              : tone === 'purple' ? 'var(--chart-purple)'
              : 'var(--chart-blue)';

  return (
    <svg viewBox={`0 0 ${width} ${height}`} width={width} height={height} className="chart chart-sparkline">
      <path d={area}  fill={color} opacity="0.10" />
      <path d={line}  fill="none" stroke={color} strokeWidth="1.5"
            strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}


// -----------------------------------------------------------------
// DonutStack — small progress donut with a large center label.
//    percent: 0-100
// -----------------------------------------------------------------
function DonutStack({ percent, size = 56, thickness = 6, tone = 'blue', label }) {
  const safePercent = Math.max(0, Math.min(100, Number(percent) || 0));
  const r = (size - thickness) / 2;
  const c = 2 * Math.PI * r;
  const dash = (safePercent / 100) * c;
  const color = tone === 'green'  ? 'var(--chart-green)'
              : tone === 'red'    ? 'var(--danger-solid)'
              : tone === 'purple' ? 'var(--chart-purple)'
              : 'var(--chart-blue)';

  return (
    <div className="chart chart-donut" style={{ width: size, height: size, position: 'relative' }}>
      <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size} style={{ transform: 'rotate(-90deg)' }}>
        <circle cx={size / 2} cy={size / 2} r={r} fill="none" stroke="var(--chart-min)" strokeWidth={thickness} />
        <circle cx={size / 2} cy={size / 2} r={r} fill="none" stroke={color} strokeWidth={thickness}
                strokeLinecap="round"
                strokeDasharray={`${dash} ${c - dash}`} />
      </svg>
      <div className="chart-donut-center mono">
        <span className="v">{safePercent}</span><span className="u">%</span>
        {label && <span className="l">{label}</span>}
      </div>
    </div>
  );
}


// Expose
Object.assign(window, {
  BarPair, StackedProgressList, HorizontalStages, ChartSparkline, DonutStack,
});
