// Neurasea — UI foundation: theme, primitives, icons
// Exports to window: ThemeCtx, useTheme, makeTheme, Icon, StatusDot, Meter,
//   Battery, Toggle, Segmented, Pill, Card, Btn, Bolt, FlowLine, Sparkline, Avatar

const NS_SANS = '-apple-system, BlinkMacSystemFont, "SF Pro Display", system-ui, "Segoe UI", sans-serif';
const NS_MONO = 'ui-monospace, "SF Mono", "JetBrains Mono", Menlo, monospace';

const ACCENTS = {
  green:  { live: 'oklch(0.72 0.13 162)', liveSoft: 'oklch(0.72 0.13 162 / 0.14)' },
  blue:   { live: 'oklch(0.64 0.14 250)', liveSoft: 'oklch(0.64 0.14 250 / 0.14)' },
  violet: { live: 'oklch(0.62 0.17 295)', liveSoft: 'oklch(0.62 0.17 295 / 0.14)' },
};
// swatch hex (shown in Tweaks) → accent key
const ACCENT_SWATCH = { '#1f9d6b': 'green', '#3b74e0': 'blue', '#7c5ce0': 'violet' };

function makeTheme(dark, accent) {
  const key = ACCENT_SWATCH[accent] || accent;
  const a = ACCENTS[key] || ACCENTS.green;
  const base = dark ? {
    desk1: '#1a1c22', desk2: '#0a0b0e',
    win: '#101115', panel: '#17181c', panel2: '#1c1d22', panel3: '#222329',
    ink: '#f2f2f4', ink2: '#a2a2ac', ink3: '#67676f',
    line: 'rgba(255,255,255,0.10)', line2: 'rgba(255,255,255,0.055)',
    inset: 'rgba(255,255,255,0.04)',
    shadow: '0 30px 80px rgba(0,0,0,0.55), 0 0 0 1px rgba(255,255,255,0.06)',
  } : {
    desk1: '#e9e7e1', desk2: '#cfcdc7',
    win: '#f3f2ee', panel: '#ffffff', panel2: '#faf9f7', panel3: '#f1f0ec',
    ink: '#18181a', ink2: '#6c6c70', ink3: '#a0a0a6',
    line: 'rgba(0,0,0,0.085)', line2: 'rgba(0,0,0,0.05)',
    inset: 'rgba(0,0,0,0.02)',
    shadow: '0 30px 80px rgba(0,0,0,0.32), 0 0 0 1px rgba(0,0,0,0.10)',
  };
  return {
    dark, accent, sans: NS_SANS, mono: NS_MONO,
    ...base,
    live: a.live, liveSoft: a.liveSoft,
    idle: 'oklch(0.80 0.11 78)', idleSoft: dark ? 'oklch(0.80 0.11 78 / 0.16)' : 'oklch(0.80 0.11 78 / 0.16)',
    draw: 'oklch(0.66 0.13 250)', drawSoft: 'oklch(0.66 0.13 250 / 0.14)',
    off: dark ? '#55555d' : '#b6b6bc',
  };
}

const ThemeCtx = React.createContext(makeTheme(false, 'green'));
const useTheme = () => React.useContext(ThemeCtx);

// ── Icons ────────────────────────────────────────────────────────────────
function Icon({ name, size = 18, 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}/></>,
    bolt: <path d="M13 2L4.5 13.5H11l-1 8.5L19.5 10H13l0-8z" {...p}/>,
    plug: <><path d="M9 2v5M15 2v5" {...p}/><path d="M6 7h12v3a6 6 0 0 1-12 0V7z" {...p}/><path d="M12 16v6" {...p}/></>,
    terminal: <><rect x="3" y="4" width="18" height="16" rx="2.5" {...p}/><path d="M7 9l3 3-3 3M13 15h4" {...p}/></>,
    layers: <><path d="M12 3l9 5-9 5-9-5 9-5z" {...p}/><path d="M3 13l9 5 9-5" {...p}/></>,
    battery: <><rect x="2.5" y="7" width="16" height="10" rx="2.5" {...p}/><path d="M21.5 11v2" {...p}/></>,
    gear: <><circle cx="12" cy="12" r="3.2" {...p}/><path d="M12 2v3M12 19v3M2 12h3M19 12h3M5 5l2 2M17 17l2 2M19 5l-2 2M7 17l-2 2" {...p}/></>,
    check: <path d="M4 12l5 5L20 6" {...p}/>,
    arrowRight: <path d="M5 12h14M13 6l6 6-6 6" {...p}/>,
    arrowUpRight: <path d="M7 17L17 7M8 7h9v9" {...p}/>,
    plus: <path d="M12 5v14M5 12h14" {...p}/>,
    spark: <path d="M12 3l2 6 6 2-6 2-2 6-2-6-6-2 6-2 2-6z" {...p}/>,
    pause: <><path d="M9 5v14M15 5v14" {...p}/></>,
    copy: <><rect x="9" y="9" width="11" height="11" rx="2" {...p}/><path d="M5 15V5a2 2 0 0 1 2-2h8" {...p}/></>,
    chevron: <path d="M9 6l6 6-6 6" {...p}/>,
    dot: <circle cx="12" cy="12" r="3" fill={color} stroke="none"/>,
    moon: <path d="M20 14.5A8 8 0 1 1 9.5 4a6.5 6.5 0 0 0 10.5 10.5z" {...p}/>,
    flow: <><path d="M3 12h18" {...p}/><path d="M14 7l5 5-5 5" {...p}/></>,
    shield: <><path d="M12 3l7 3v5c0 4.5-3 8-7 10-4-2-7-5.5-7-10V6l7-3z" {...p}/></>,
    info: <><circle cx="12" cy="12" r="9" {...p}/><path d="M12 11v5M12 8h.01" {...p}/></>,
    globe: <><circle cx="12" cy="12" r="9" {...p}/><path d="M3 12h18M12 3c2.5 2.5 2.5 15 0 18M12 3c-2.5 2.5-2.5 15 0 18" {...p}/></>,
  };
  return <svg width={size} height={size} viewBox="0 0 24 24" style={{ display: 'block', flexShrink: 0, transition: 'transform .2s', ...style }}>{paths[name]}</svg>;
}

// ── Status dot ───────────────────────────────────────────────────────────
function StatusDot({ color, size = 8, pulse = false }) {
  return (
    <span style={{ position: 'relative', width: size, height: size, display: 'inline-flex', flexShrink: 0 }}>
      {pulse && <span style={{ position: 'absolute', inset: -2, borderRadius: '50%', background: color, opacity: 0.3, animation: 'nsPulse 2s ease-out infinite' }} />}
      <span style={{ width: size, height: size, borderRadius: '50%', background: color }} />
    </span>
  );
}

// ── Horizontal meter ─────────────────────────────────────────────────────
function Meter({ value, color, track, height = 6 }) {
  const t = useTheme();
  return (
    <div style={{ width: '100%', height, borderRadius: height, background: track || t.panel3, overflow: 'hidden' }}>
      <div style={{ width: `${Math.max(2, Math.min(100, value))}%`, height: '100%', borderRadius: height, background: color || t.live, transition: 'width .6s cubic-bezier(.4,0,.2,1)' }} />
    </div>
  );
}

// ── Battery / charge ─────────────────────────────────────────────────────
function Battery({ pct, color, w = 220, h = 14 }) {
  const t = useTheme();
  const c = color || t.live;
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
      <div style={{ position: 'relative', width: w, height: h, borderRadius: h / 2, background: t.panel3, border: `1px solid ${t.line}`, overflow: 'hidden' }}>
        <div style={{ position: 'absolute', inset: 1.5, width: `calc(${Math.min(100, pct)}% - 3px)`, borderRadius: h / 2, background: `linear-gradient(90deg, ${c}, ${c})`, transition: 'width .7s cubic-bezier(.4,0,.2,1)' }} />
      </div>
      <div style={{ width: 4, height: h * 0.5, borderRadius: 2, background: t.line }} />
    </div>
  );
}

// ── Toggle switch ────────────────────────────────────────────────────────
function Toggle({ on, onClick, color }) {
  const t = useTheme();
  return (
    <button onClick={onClick} style={{
      width: 42, height: 25, borderRadius: 13, border: 'none', cursor: 'pointer', padding: 0,
      background: on ? (color || t.live) : (t.dark ? '#3a3b42' : '#d8d7d2'),
      position: 'relative', transition: 'background .25s', flexShrink: 0,
    }}>
      <span style={{ position: 'absolute', top: 2.5, left: on ? 19.5 : 2.5, width: 20, height: 20, borderRadius: '50%', background: '#fff', boxShadow: '0 1px 3px rgba(0,0,0,0.3)', transition: 'left .25s cubic-bezier(.4,0,.2,1)' }} />
    </button>
  );
}

// ── Segmented control ────────────────────────────────────────────────────
function Segmented({ options, value, onChange, size = 'md' }) {
  const t = useTheme();
  const pad = size === 'sm' ? '5px 12px' : '7px 16px';
  const fs = size === 'sm' ? 12.5 : 13.5;
  return (
    <div style={{ display: 'inline-flex', background: t.panel3, borderRadius: 10, padding: 3, gap: 2, border: `1px solid ${t.line2}` }}>
      {options.map(o => {
        const v = typeof o === 'string' ? o : o.value;
        const label = typeof o === 'string' ? o : o.label;
        const sel = v === value;
        return (
          <button key={v} onClick={() => onChange(v)} style={{
            padding: pad, fontSize: fs, fontWeight: 550, fontFamily: t.sans, cursor: 'pointer',
            border: 'none', borderRadius: 8, whiteSpace: 'nowrap',
            background: sel ? t.panel : 'transparent',
            color: sel ? t.ink : t.ink2,
            boxShadow: sel ? (t.dark ? '0 1px 2px rgba(0,0,0,0.4)' : '0 1px 2px rgba(0,0,0,0.08)') : 'none',
            transition: 'all .18s',
          }}>{label}</button>
        );
      })}
    </div>
  );
}

// ── Pill / tag ───────────────────────────────────────────────────────────
function Pill({ children, color, soft, mono = true }) {
  const t = useTheme();
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 6, padding: '4px 10px',
      borderRadius: 999, fontSize: 11.5, fontWeight: 600, letterSpacing: '0.01em',
      fontFamily: mono ? t.mono : t.sans,
      background: soft || t.panel3, color: color || t.ink2,
      border: `1px solid ${t.line2}`,
    }}>{children}</span>
  );
}

// ── Card ─────────────────────────────────────────────────────────────────
function Card({ children, style = {}, pad = 22, onClick, hover }) {
  const t = useTheme();
  const [h, setH] = React.useState(false);
  return (
    <div onClick={onClick}
      onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
      style={{
        background: t.panel, border: `1px solid ${t.line}`, borderRadius: 18, padding: pad,
        cursor: onClick ? 'pointer' : 'default',
        boxShadow: hover && h ? (t.dark ? '0 12px 36px rgba(0,0,0,0.4)' : '0 12px 36px rgba(0,0,0,0.10)') : 'none',
        transform: hover && h ? 'translateY(-2px)' : 'none',
        transition: 'transform .2s, box-shadow .2s, border-color .2s',
        borderColor: hover && h ? (t.dark ? 'rgba(255,255,255,0.16)' : 'rgba(0,0,0,0.14)') : t.line,
        ...style,
      }}>{children}</div>
  );
}

// ── Button ───────────────────────────────────────────────────────────────
function Btn({ children, kind = 'secondary', onClick, size = 'md', icon, color, style = {}, full }) {
  const t = useTheme();
  const [h, setH] = React.useState(false);
  const pad = size === 'sm' ? '7px 13px' : size === 'lg' ? '13px 22px' : '9px 16px';
  const fs = size === 'sm' ? 12.5 : size === 'lg' ? 15.5 : 13.5;
  const styles = {
    primary: { background: color || t.ink, color: t.dark ? '#101115' : '#fff', border: '1px solid transparent' },
    accent: { background: color || t.live, color: '#fff', border: '1px solid transparent' },
    secondary: { background: t.panel, color: t.ink, border: `1px solid ${t.line}` },
    ghost: { background: 'transparent', color: t.ink2, border: '1px solid transparent' },
  };
  return (
    <button onClick={onClick} onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
      style={{
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 7,
        padding: pad, fontSize: fs, fontWeight: 600, fontFamily: t.sans, cursor: 'pointer',
        borderRadius: 11, whiteSpace: 'nowrap', width: full ? '100%' : 'auto',
        filter: h ? 'brightness(1.06)' : 'none', transform: h ? 'translateY(-1px)' : 'none',
        transition: 'filter .15s, transform .15s', ...styles[kind], ...style,
      }}>
      {icon && <Icon name={icon} size={fs + 2} />}{children}
    </button>
  );
}

// ── Bolt energy glyph (filled) ───────────────────────────────────────────
function Bolt({ size = 16, color = 'currentColor' }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" style={{ display: 'block', flexShrink: 0 }}>
      <path d="M13 2L4.5 13.2c-.3.4 0 .9.5.9H10l-1.2 7.2c-.1.6.7.9 1 .4L19.5 10.5c.3-.4 0-.9-.5-.9H14l1-7.1c.1-.6-.7-.9-1-.5z" fill={color} />
    </svg>
  );
}

// ── Sparkline ────────────────────────────────────────────────────────────
function Sparkline({ data, color, w = 120, h = 34, fill = true }) {
  const t = useTheme();
  const c = color || t.live;
  const max = Math.max(...data), min = Math.min(...data);
  const rng = max - min || 1;
  const pts = data.map((d, i) => [ (i / (data.length - 1)) * w, h - 3 - ((d - min) / rng) * (h - 6) ]);
  const line = pts.map((p, i) => `${i ? 'L' : 'M'}${p[0].toFixed(1)} ${p[1].toFixed(1)}`).join(' ');
  const area = `${line} L${w} ${h} L0 ${h} Z`;
  const id = React.useMemo(() => 'sg' + Math.random().toString(36).slice(2, 7), []);
  return (
    <svg width={w} height={h} style={{ display: 'block', overflow: 'visible' }}>
      <defs><linearGradient id={id} x1="0" y1="0" x2="0" y2="1">
        <stop offset="0%" stopColor={c} stopOpacity="0.22"/><stop offset="100%" stopColor={c} stopOpacity="0"/>
      </linearGradient></defs>
      {fill && <path d={area} fill={`url(#${id})`} />}
      <path d={line} fill="none" stroke={c} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}

// ── Brand avatar (text monogram tile) ───────────────────────────────────
function Avatar({ label, bg, fg, size = 38, radius = 11 }) {
  const t = useTheme();
  return (
    <div style={{
      width: size, height: size, borderRadius: radius, flexShrink: 0,
      background: bg || t.panel3, color: fg || t.ink,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontFamily: t.sans, fontWeight: 700, fontSize: size * 0.34, letterSpacing: '-0.01em',
      border: `1px solid ${t.line2}`,
    }}>{label}</div>
  );
}

Object.assign(window, {
  ThemeCtx, useTheme, makeTheme, NS_SANS, NS_MONO,
  Icon, StatusDot, Meter, Battery, Toggle, Segmented, Pill, Card, Btn, Bolt, Sparkline, Avatar,
});
