/* global React */
// Shared primitives and SVG bits for Sherlock screens.

const { useState, useEffect, useMemo, useRef } = React;

// ── Wax seal mark - Watson's signature glyph ──────────────────────────
function WaxSeal({ size = 28, letter = 'W' }) {
  return (
    <svg width={size} height={size} viewBox="0 0 32 32" style={{ display: 'block' }}>
      <defs>
        <radialGradient id="wax-g" cx="35%" cy="32%" r="70%">
          <stop offset="0" stopColor="#C9756A" />
          <stop offset="0.55" stopColor="#9C3A2A" />
          <stop offset="1" stopColor="#6F2417" />
        </radialGradient>
      </defs>
      <circle cx="16" cy="16" r="14" fill="url(#wax-g)" />
      <circle cx="16" cy="16" r="11.5" fill="none" stroke="rgba(255,240,230,0.18)" strokeWidth="0.6" strokeDasharray="1 2" />
      <text x="16" y="20.5" textAnchor="middle"
        fontFamily="Spectral, serif" fontSize="13" fontWeight="600" fill="#F4EFE6"
        fontStyle="italic">{letter}</text>
    </svg>
  );
}

// ── Sherlock case-file monogram ──
function CaseMark({ size = 22 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" style={{ display: 'block' }}>
      <circle cx="12" cy="12" r="11" fill="none" stroke="#1B2238" strokeWidth="0.7" />
      <text x="12" y="15.5" textAnchor="middle" fontFamily="Spectral, serif" fontSize="11" fontWeight="500" fill="#1B2238" fontStyle="italic">S</text>
    </svg>
  );
}

// ── Pin (sealing-wax disc) ──
function Pin({ size = 14, idx }) {
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      width: size, height: size, borderRadius: '50%',
      background: '#9C3A2A', color: '#F4EFE6',
      fontFamily: 'Spectral, serif', fontStyle: 'italic',
      fontSize: size * 0.6, fontWeight: 500, lineHeight: 1,
      boxShadow: 'inset 0 0 0 0.6px rgba(255,240,230,0.25)',
      flex: '0 0 auto',
    }}>{idx ?? ''}</span>
  );
}

// ── Severity dot - color from token, sized for ledger ──
function Sev({ level = 'info', size = 6 }) {
  const c = { critical: 'var(--brick)', high: 'var(--brick)', warn: 'var(--mustard)', warning: 'var(--mustard)', info: 'var(--teal)', low: 'var(--teal)' }[level] || 'var(--ink-mute)';
  return <span style={{ width: size, height: size, borderRadius: '50%', background: c, display: 'inline-block', flex: '0 0 auto' }} />;
}

// ── Parchment card. No drop shadow. Hairline rule via border. ──
function Card({ title, action, kicker, padding = 16, children, style, accent }) {
  return (
    <section style={{
      background: 'var(--paper)',
      border: '1px solid var(--rule)',
      ...style,
    }}>
      {(title || action || kicker) && (
        <header style={{
          display: 'flex', alignItems: 'baseline', justifyContent: 'space-between',
          padding: `${padding}px ${padding}px ${kicker ? 4 : padding}px`,
          gap: 12,
        }}>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, minWidth: 0 }}>
            {accent}
            {kicker && <span className="smallcaps">{kicker}</span>}
            {title && <h3 style={{ font: '500 14px/1.2 var(--sans)', margin: 0, color: 'var(--ink)' }}>{title}</h3>}
          </div>
          {action}
        </header>
      )}
      <div style={{ padding: title ? `0 ${padding}px ${padding}px` : padding }}>{children}</div>
    </section>
  );
}

// ── Confidence bar - irregular, ink-on-parchment ──
function ConfBar({ value, color = 'var(--plum)', height = 4 }) {
  return (
    <div style={{ height, background: 'var(--parchment-2)', borderRadius: 0, overflow: 'hidden', position: 'relative' }}>
      <div style={{
        height: '100%', width: `${value * 100}%`,
        background: color, transition: 'width .6s cubic-bezier(.2,.7,.3,1)',
      }} />
    </div>
  );
}

// ── Tag chip - no fill by default, optional wash ──
function Tag({ children, tone = 'ink', size = 'sm', solid }) {
  const tones = {
    ink:    { fg: 'var(--ink)',    wash: 'var(--parchment-2)' },
    brick:  { fg: 'var(--wax)',    wash: 'var(--brick-wash)' },
    mustard:{ fg: '#8a6a14',       wash: 'var(--mustard-wash)' },
    teal:   { fg: '#3e6e6d',       wash: 'var(--teal-wash)' },
    plum:   { fg: 'var(--plum)',   wash: 'var(--plum-wash)' },
  };
  const t = tones[tone] || tones.ink;
  const py = size === 'xs' ? 1 : 2;
  const px = size === 'xs' ? 5 : 7;
  const fz = size === 'xs' ? 9.5 : 10.5;
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 4,
      padding: `${py}px ${px}px`,
      fontFamily: 'var(--mono)', fontSize: fz, fontWeight: 500,
      letterSpacing: '0.02em',
      color: t.fg,
      background: solid ? t.wash : 'transparent',
      border: solid ? 'none' : `1px solid ${t.fg}33`,
      borderRadius: 1,
      whiteSpace: 'nowrap',
    }}>{children}</span>
  );
}

// ── Spark line / area for tiny charts ──
function Spark({ data, w = 80, h = 22, color = 'var(--ink-soft)', fill, strokeWidth = 1, anomalyIndex, anomalyTitle, onAnomalyClick }) {
  if (!data?.length) return null;
  const min = Math.min(...data), max = Math.max(...data);
  const r = max - min || 1;
  const pts = data.map((v, i) => [(i / (data.length - 1)) * w, h - ((v - min) / r) * (h - 2) - 1]);
  const d = pts.map((p, i) => (i ? 'L' : 'M') + p[0].toFixed(1) + ' ' + p[1].toFixed(1)).join(' ');
  const area = d + ` L${w} ${h} L0 ${h} Z`;
  const dot = anomalyIndex != null ? pts[anomalyIndex] : null;
  return (
    <svg width={w} height={h} style={{ display: 'block', overflow: 'visible' }}>
      {fill && <path d={area} fill={fill} />}
      <path d={d} fill="none" stroke={color} strokeWidth={strokeWidth} strokeLinejoin="round" strokeLinecap="round" />
      {dot && (
        <g style={{ cursor: onAnomalyClick ? 'pointer' : 'default' }} onClick={onAnomalyClick}>
          <circle cx={dot[0]} cy={dot[1]} r={10} fill="transparent" />
          <circle cx={dot[0]} cy={dot[1]} r={4.5} fill="var(--paper)" stroke="var(--ink)" strokeWidth={1.4} />
          {anomalyTitle && <title>{anomalyTitle}</title>}
        </g>
      )}
    </svg>
  );
}

// ── Hairline + label divider ──
function Divider({ children, mt = 14, mb = 10 }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: mt, marginBottom: mb }}>
      {children && <span className="smallcaps">{children}</span>}
      <div style={{ flex: 1, borderTop: '1px solid var(--rule)' }} />
    </div>
  );
}

Object.assign(window, { WaxSeal, CaseMark, Pin, Sev, Card, ConfBar, Tag, Spark, Divider });
