/* ============================================================
   VENTUM CHARTS — reusable SVG infographic components for
   content artifacts. All chartss are deterministic, brand-
   palette-locked, and theme-aware (light or 'navy' on dark).
   ============================================================ */

const VC_COLORS = {
  navy: '#0B1F33',
  navyDeep: '#061320',
  teal: '#22B8A7',
  signal: '#2563EB',
  ink100: '#0B1F33',
  ink80: '#2A3A4D',
  ink60: '#56657A',
  ink40: '#8A98AB',
  ink20: '#C6CFD9',
  ink10: '#E7ECEF',
  ink05: '#F3F6F8',
  white: '#FFFFFF'
};

function vcTheme(theme = 'light') {
  if (theme === 'navy') {
    return {
      bg: 'transparent',
      fg: '#FFFFFF',
      muted: 'rgba(255,255,255,0.62)',
      dim: 'rgba(255,255,255,0.18)',
      dimmer: 'rgba(255,255,255,0.08)',
      accent: VC_COLORS.teal,
      track: 'rgba(255,255,255,0.10)',
      bar: '#FFFFFF',
      barAlt: VC_COLORS.teal
    };
  }
  return {
    bg: 'transparent',
    fg: VC_COLORS.ink100,
    muted: VC_COLORS.ink60,
    dim: VC_COLORS.ink20,
    dimmer: VC_COLORS.ink10,
    accent: VC_COLORS.teal,
    track: VC_COLORS.ink10,
    bar: VC_COLORS.navy,
    barAlt: VC_COLORS.teal
  };
}

// Small inline-editable number used inside chart SVGs / chart UIs.
// Renders a contentEditable span. On blur, parses out the numeric part
// and reports the new value via onChange.
function EditableNumber({ value, onChange, style = {}, suffix = '', className = '' }) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (ref.current && ref.current.innerText !== String(value ?? '')) {
      ref.current.innerText = String(value ?? '');
    }
  }, [value]);
  if (!onChange) {
    // read-only path
    return <span className={className} style={style}>{value}{suffix}</span>;
  }
  return (
    <span style={{ display: 'inline-flex', alignItems: 'baseline' }}>
      <span
        ref={ref}
        contentEditable
        suppressContentEditableWarning
        className={"editable editable-num " + className}
        style={style}
        onBlur={(e) => {
          const txt = e.currentTarget.innerText.trim();
          // accept numbers like "32", "32.5", "32%", "32 min"
          const num = parseFloat(txt.replace(/,/g, ''));
          onChange(isNaN(num) ? value : num, txt);
        }}
      />
      {suffix && <span style={{ marginLeft: 2 }}>{suffix}</span>}
    </span>
  );
}
window.EditableNumber = EditableNumber;

// ============================================================
// 1. LOG LADDER — visual representation of log-reduction.
//    Renders 6 stacked rungs labeled 10¹…10⁶, with the active
//    range filled in brand teal. Headline-style infographic.
// ============================================================
function LogLadder({ filled = 6, theme = 'light', label = 'Pathogen reduction', highlight = 'Up to 99.9995%' }) {
  const t = vcTheme(theme);
  const rungs = [1, 2, 3, 4, 5, 6];
  return (
    <div style={{ width: '100%' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 10 }}>
        <span className="mono" style={{ fontSize: 10, color: t.muted, letterSpacing: '0.14em', textTransform: 'uppercase' }}>{label}</span>
        <span className="mono" style={{ fontSize: 10, color: t.accent, letterSpacing: '0.14em', textTransform: 'uppercase', fontWeight: 500 }}>{highlight}</span>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(6, 1fr)', gap: 4 }}>
        {rungs.map((r) => {
          const active = r <= filled;
          // bar height grows with log (suggests exponential reduction)
          const h = 8 + r * 6;
          return (
            <div key={r} style={{ display: 'flex', flexDirection: 'column', alignItems: 'stretch', gap: 6 }}>
              <div style={{
                height: h,
                background: active ? (r === filled ? t.accent : t.bar) : t.dimmer,
                borderRadius: 1,
                opacity: active ? (0.45 + (r / filled) * 0.55) : 1
              }} />
              <div className="mono" style={{ fontSize: 9, color: active ? t.fg : t.muted, letterSpacing: '0.08em', textAlign: 'center' }}>
                10<sup style={{ fontSize: 7 }}>{r}</sup>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

// ============================================================
// 2. BEFORE/AFTER BARS — horizontal bar comparison.
//    items: [{ label, value, suffix }, ...]
//    First item is dim (status quo), second is teal (Ventum).
// ============================================================
function BeforeAfterBars({ items = [], theme = 'light', title = 'Turnaround time', subtitle = '', onEditValue, onEditLabel }) {
  const t = vcTheme(theme);
  const max = Math.max(...items.map((it) => Number(it.value) || 0), 1);
  return (
    <div style={{ width: '100%' }}>
      {(title || subtitle) && (
        <div style={{ marginBottom: 12, display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
          <div>
            <div className="mono" style={{ fontSize: 10, color: t.muted, letterSpacing: '0.14em', textTransform: 'uppercase' }}>{title}</div>
            {subtitle && <div style={{ fontSize: 12, color: t.muted, marginTop: 2 }}>{subtitle}</div>}
          </div>
        </div>
      )}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        {items.map((it, i) => {
          const pct = Math.max(4, (Number(it.value) / max) * 100);
          const isVentum = i === items.length - 1; // last bar is "with Ventum"
          return (
            <div key={i} style={{ display: 'grid', gridTemplateColumns: '120px 1fr 84px', gap: 12, alignItems: 'center' }}>
              {onEditLabel ? (
                <EditableNumber
                  value={it.label}
                  onChange={(_, raw) => onEditLabel(i, raw)}
                  className="mono"
                  style={{ fontSize: 10, color: isVentum ? t.fg : t.muted, letterSpacing: '0.1em', textTransform: 'uppercase', fontWeight: isVentum ? 500 : 400 }}
                />
              ) : (
                <div className="mono" style={{ fontSize: 10, color: isVentum ? t.fg : t.muted, letterSpacing: '0.1em', textTransform: 'uppercase', fontWeight: isVentum ? 500 : 400 }}>{it.label}</div>
              )}
              <div style={{ height: 16, background: t.track, borderRadius: 1, position: 'relative', overflow: 'hidden' }}>
                <div style={{
                  position: 'absolute', inset: 0, width: pct + '%',
                  background: isVentum ? t.accent : (theme === 'navy' ? 'rgba(255,255,255,0.35)' : VC_COLORS.ink40),
                  borderRadius: 1,
                  transition: 'width 0.25s ease'
                }} />
              </div>
              <div style={{ fontSize: 13, fontWeight: 500, color: t.fg, fontVariantNumeric: 'tabular-nums', textAlign: 'right' }}>
                {onEditValue ? (
                  <EditableNumber
                    value={it.value}
                    onChange={(num) => onEditValue(i, num)}
                    style={{ minWidth: 24, display: 'inline-block' }}
                  />
                ) : it.value}
                <span className="mono" style={{ fontSize: 9, color: t.muted, marginLeft: 4, letterSpacing: '0.1em' }}>{it.suffix || ''}</span>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

// ============================================================
// 3. PROCESS RIBBON — 3 (or N) step horizontal flow with
//    connectors. Used to visualize the One-Touch protocol or
//    pilot scope.
// ============================================================
function ProcessRibbon({ steps = [], theme = 'light' }) {
  const t = vcTheme(theme);
  if (!steps.length) return null;
  return (
    <div style={{ display: 'grid', gridTemplateColumns: `repeat(${steps.length}, 1fr)`, gap: 0, position: 'relative' }}>
      {steps.map((s, i) => (
        <div key={i} style={{ position: 'relative', paddingRight: i < steps.length - 1 ? 18 : 0 }}>
          <div style={{
            border: `1px solid ${t.dim}`,
            padding: '12px 14px',
            background: theme === 'navy' ? 'rgba(255,255,255,0.04)' : VC_COLORS.white,
            borderRadius: 2,
            height: '100%'
          }}>
            {/* Inline number + duration with a gap (not space-between) so they
                never collide into "01MINUTES" in narrow boxes; the duration
                wraps below only if there's truly no room. No extra height in
                the common case. */}
            <div style={{ display: 'flex', gap: 6, alignItems: 'baseline', flexWrap: 'wrap' }}>
              <span className="mono" style={{ fontSize: 9, color: t.accent, letterSpacing: '0.14em', fontWeight: 500 }}>0{i+1}</span>
              {s.duration && <span className="mono" style={{ fontSize: 8.5, color: t.muted, letterSpacing: '0.06em', textTransform: 'uppercase' }}>{s.duration}</span>}
            </div>
            <div style={{ fontSize: 14, fontWeight: 500, color: t.fg, marginTop: 4, letterSpacing: '-0.01em' }}>{s.label}</div>
            {s.detail && <div style={{ fontSize: 11.5, color: t.muted, marginTop: 4, lineHeight: 1.4 }}>{s.detail}</div>}
          </div>
          {i < steps.length - 1 && (
            <div style={{
              position: 'absolute',
              right: 0, top: '50%',
              width: 18, height: 1,
              background: t.accent,
              transform: 'translateY(-50%)'
            }}>
              <div style={{
                position: 'absolute', right: 0, top: -3,
                width: 0, height: 0,
                borderTop: '4px solid transparent',
                borderBottom: '4px solid transparent',
                borderLeft: `6px solid ${t.accent}`
              }} />
            </div>
          )}
        </div>
      ))}
    </div>
  );
}

// ============================================================
// 4. COVERAGE MATRIX — small grid of zones treated.
//    items: ['Air', 'High-touch surfaces', ...] — each rendered
//    as a filled cell. Visual answer to "What does it touch?"
// ============================================================
function CoverageMatrix({ items = [], theme = 'light', title = 'Single-cycle coverage' }) {
  const t = vcTheme(theme);
  return (
    <div style={{ width: '100%' }}>
      <div className="mono" style={{ fontSize: 10, color: t.muted, letterSpacing: '0.14em', textTransform: 'uppercase', marginBottom: 10 }}>{title}</div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 6 }}>
        {items.slice(0, 6).map((label, i) => (
          <div key={i} style={{
            display: 'grid', gridTemplateColumns: '16px 1fr', gap: 8,
            alignItems: 'center',
            padding: '8px 10px',
            background: theme === 'navy' ? 'rgba(255,255,255,0.04)' : VC_COLORS.ink05,
            border: `1px solid ${t.dimmer}`,
            borderRadius: 2
          }}>
            <span style={{ width: 8, height: 8, background: t.accent, borderRadius: 1, display: 'inline-block' }} />
            <span style={{ fontSize: 11.5, color: t.fg, letterSpacing: '-0.005em', lineHeight: 1.3 }}>{label}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

// ============================================================
// 5. DECAY CURVE — exponential pathogen-decay sparkline.
//    Pure SVG. Goes from a peak label down to a floor over a
//    given duration label. Visual shorthand for "log reduction
//    over one cycle".
// ============================================================
function DecayCurve({
  fromLabel = '10⁶',
  toLabel = '< 1',
  durationLabel = 'one cycle',
  theme = 'light',
  height = 110,
  width = 320,
  onEditFromLabel,
  onEditToLabel,
  onEditDurationLabel
}) {
  const t = vcTheme(theme);
  // Exponential decay y = e^(-kx)
  const k = 5;
  const pts = [];
  const padL = 36, padR = 18, padT = 14, padB = 22;
  const W = width - padL - padR;
  const H = height - padT - padB;
  for (let i = 0; i <= 40; i++) {
    const x = i / 40;
    const y = Math.exp(-k * x);
    pts.push([padL + x * W, padT + (1 - y) * H]);
  }
  const path = 'M ' + pts.map(([x, y]) => `${x.toFixed(1)},${y.toFixed(1)}`).join(' L ');
  const areaPath = path + ` L ${padL + W},${padT + H} L ${padL},${padT + H} Z`;
  // gridlines (log decades)
  const gridY = [0.25, 0.5, 0.75];

  // Edit controls render only when callbacks are provided. They live
  // OUTSIDE the <svg> as sibling HTML (data-editor-only) so the export
  // rasterizer never sees them — the label VALUES live in SVG <text>,
  // which rasterizes cleanly. Embedded-HTML labels would blank out
  // through the XMLSerializer -> Image -> canvas PPTX path, so we avoid
  // them entirely here.
  const editable = !!(onEditFromLabel || onEditToLabel || onEditDurationLabel);
  return (
    <div style={{ width: '100%', maxWidth: width }}>
      <svg viewBox={`0 0 ${width} ${height}`} width="100%" style={{ display: 'block', maxWidth: width }}>
        {/* gridlines */}
        {gridY.map((g, i) => (
          <line key={i} x1={padL} x2={padL + W} y1={padT + g * H} y2={padT + g * H} stroke={t.dimmer} strokeWidth="1" strokeDasharray="2 3" />
        ))}
        {/* axes */}
        <line x1={padL} x2={padL} y1={padT} y2={padT + H} stroke={t.dim} strokeWidth="1" />
        <line x1={padL} x2={padL + W} y1={padT + H} y2={padT + H} stroke={t.dim} strokeWidth="1" />
        {/* area + curve */}
        <path d={areaPath} fill={t.accent} fillOpacity="0.12" />
        <path d={path} fill="none" stroke={t.accent} strokeWidth="2" />
        {/* start dot */}
        <circle cx={pts[0][0]} cy={pts[0][1]} r="3.5" fill={t.accent} />
        <circle cx={pts[pts.length - 1][0]} cy={pts[pts.length - 1][1]} r="3.5" fill={t.bar} />
        {/* labels — export-safe SVG <text>; reflect current prop/chart_data values */}
        <text x={padL - 8} y={padT + 4} textAnchor="end" fill={t.fg} fontSize="10" fontFamily="var(--mono)" letterSpacing="0.06em">{fromLabel}</text>
        <text x={padL - 8} y={padT + H + 4} textAnchor="end" fill={t.muted} fontSize="10" fontFamily="var(--mono)" letterSpacing="0.06em">{toLabel}</text>
        <text x={padL} y={height - 4} fill={t.muted} fontSize="9" fontFamily="var(--mono)" letterSpacing="0.14em">T0</text>
        <text x={padL + W} y={height - 4} textAnchor="end" fill={t.muted} fontSize="9" fontFamily="var(--mono)" letterSpacing="0.14em">{durationLabel.toUpperCase()}</text>
      </svg>
      {editable && (
        <div data-editor-only="true" style={{ display: 'flex', flexWrap: 'wrap', gap: 12, marginTop: 6 }}>
          {onEditFromLabel && (
            <label style={{ display: 'inline-flex', alignItems: 'baseline', gap: 4 }}>
              <span className="mono" style={{ fontSize: 8, color: t.muted, letterSpacing: '0.12em', textTransform: 'uppercase' }}>From</span>
              <EditableNumber value={fromLabel} onChange={(_, raw) => onEditFromLabel(raw)} className="mono" style={{ fontSize: 10, color: t.fg, minWidth: 20 }} />
            </label>
          )}
          {onEditToLabel && (
            <label style={{ display: 'inline-flex', alignItems: 'baseline', gap: 4 }}>
              <span className="mono" style={{ fontSize: 8, color: t.muted, letterSpacing: '0.12em', textTransform: 'uppercase' }}>To</span>
              <EditableNumber value={toLabel} onChange={(_, raw) => onEditToLabel(raw)} className="mono" style={{ fontSize: 10, color: t.fg, minWidth: 20 }} />
            </label>
          )}
          {onEditDurationLabel && (
            <label style={{ display: 'inline-flex', alignItems: 'baseline', gap: 4 }}>
              <span className="mono" style={{ fontSize: 8, color: t.muted, letterSpacing: '0.12em', textTransform: 'uppercase' }}>Duration</span>
              <EditableNumber value={durationLabel} onChange={(_, raw) => onEditDurationLabel(raw)} className="mono" style={{ fontSize: 10, color: t.fg, minWidth: 20 }} />
            </label>
          )}
        </div>
      )}
    </div>
  );
}

// ============================================================
// 6. DONUT STAT — donut chart with central value & label.
//    Use for compliance lift, audit pass rate, etc.
// ============================================================
function DonutStat({ value = 96, suffix = '%', label = 'audit pass rate', theme = 'light', size = 140, onEditValue, onEditLabel }) {
  const t = vcTheme(theme);
  const r = size / 2 - 10;
  const cx = size / 2, cy = size / 2;
  const v = Math.max(0, Math.min(100, Number(value) || 0));
  return (
    <div style={{ display: 'inline-flex', flexDirection: 'column', alignItems: 'center', gap: 6 }}>
      <div style={{ position: 'relative', width: size, height: size }}>
        <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size} style={{ display: 'block' }}>
          <circle cx={cx} cy={cy} r={r} fill="none" stroke={t.track} strokeWidth="10" />
          <circle
            cx={cx} cy={cy} r={r}
            fill="none"
            stroke={t.accent}
            strokeWidth="10"
            pathLength="100"
            strokeDasharray={`${v} ${100 - v}`}
            strokeLinecap="butt"
            transform={`rotate(-90 ${cx} ${cy})`}
            style={{ transition: 'stroke-dasharray 0.25s ease' }}
          />
          {!onEditValue && (
            <text x={cx} y={cy} textAnchor="middle" dominantBaseline="central" fill={t.fg} fontSize={size * 0.30} fontWeight="300" letterSpacing="-0.04em">
              {v}<tspan fontSize={size * 0.14} dx="1" fill={t.muted} fontFamily="var(--mono)">{suffix}</tspan>
            </text>
          )}
        </svg>
        {onEditValue && (
          <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', pointerEvents: 'none' }}>
            <div style={{ display: 'flex', alignItems: 'baseline', pointerEvents: 'auto' }}>
              <EditableNumber
                value={v}
                onChange={(num) => onEditValue(Math.max(0, Math.min(100, num)))}
                style={{ fontSize: size * 0.30, fontWeight: 300, letterSpacing: '-0.04em', color: t.fg, minWidth: size * 0.5, textAlign: 'center' }}
              />
              <span className="mono" style={{ fontSize: size * 0.14, color: t.muted, marginLeft: 2 }}>{suffix}</span>
            </div>
          </div>
        )}
      </div>
      {onEditLabel ? (
        <EditableNumber
          value={label}
          onChange={(_, raw) => onEditLabel(raw)}
          className="mono"
          style={{ fontSize: 9.5, color: t.muted, letterSpacing: '0.16em', textTransform: 'uppercase', textAlign: 'center', maxWidth: size + 20 }}
        />
      ) : (
        <div className="mono" style={{ fontSize: 9.5, color: t.muted, letterSpacing: '0.16em', textTransform: 'uppercase', textAlign: 'center', maxWidth: size + 20 }}>{label}</div>
      )}
    </div>
  );
}

// ============================================================
// 7. STAT TILE — minimalist single-stat tile with delta arrow.
//    Used inside grids next to charts.
// ============================================================
function StatTile({ value, unit, label, delta, theme = 'light' }) {
  const t = vcTheme(theme);
  return (
    <div style={{
      padding: '14px 16px',
      border: `1px solid ${t.dim}`,
      borderRadius: 2,
      background: theme === 'navy' ? 'rgba(255,255,255,0.04)' : VC_COLORS.white
    }}>
      <div className="mono" style={{ fontSize: 9, color: t.muted, letterSpacing: '0.14em', textTransform: 'uppercase' }}>{label}</div>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 6, marginTop: 6 }}>
        <span style={{ fontSize: 28, fontWeight: 300, letterSpacing: '-0.03em', color: t.fg, lineHeight: 1 }}>{value}</span>
        {unit && <span className="mono" style={{ fontSize: 10, color: t.muted, letterSpacing: '0.1em' }}>{unit}</span>}
      </div>
      {delta && (
        <div className="mono" style={{ fontSize: 10, color: t.accent, marginTop: 6, letterSpacing: '0.08em' }}>
          ▲ {delta}
        </div>
      )}
    </div>
  );
}

// ============================================================
// 8. DOWNTIME WAVE — small bar-pattern chart showing downtime
//    minutes per turnover, "before" vs "after" series. Used in
//    the carousel data frame.
// ============================================================
function DowntimeBars({ before = [42, 38, 51, 47, 39, 44, 46], after = [14, 12, 16, 13, 11, 12, 15], theme = 'navy' }) {
  const t = vcTheme(theme);
  const all = [...before, ...after];
  const max = Math.max(...all);
  const W = 260, H = 80;
  const n = before.length;
  const bw = (W / n) - 4;
  return (
    <svg viewBox={`0 0 ${W} ${H + 18}`} width="100%" style={{ display: 'block', maxWidth: W + 20 }}>
      {before.map((b, i) => {
        const x = i * (bw + 4);
        const bh = (b / max) * H;
        const ah = (after[i] / max) * H;
        return (
          <g key={i}>
            <rect x={x} y={H - bh} width={bw / 2 - 1} height={bh} fill={theme === 'navy' ? 'rgba(255,255,255,0.35)' : VC_COLORS.ink40} />
            <rect x={x + bw / 2 + 1} y={H - ah} width={bw / 2 - 1} height={ah} fill={t.accent} />
          </g>
        );
      })}
      <text x="0" y={H + 14} fill={t.muted} fontSize="9" fontFamily="var(--mono)" letterSpacing="0.14em">MON</text>
      <text x={W} y={H + 14} textAnchor="end" fill={t.muted} fontSize="9" fontFamily="var(--mono)" letterSpacing="0.14em">SUN</text>
    </svg>
  );
}

// ============================================================
// EXPOSE
// ============================================================
Object.assign(window, {
  LogLadder,
  BeforeAfterBars,
  ProcessRibbon,
  CoverageMatrix,
  DecayCurve,
  DonutStat,
  StatTile,
  DowntimeBars,
  VC_COLORS
});
