// Shared UI primitives: VendorTile (geometric glyphs, not branded marks),
// Sparkline, StatusDot, MiniGraph

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

// Geometric glyphs for connector categories — NOT branded marks. Abstract shapes.
function VendorGlyph({ glyph, size = 18 }) {
  const s = size;
  const stroke = 1.6;
  const common = { width: s, height: s, viewBox: '0 0 24 24', fill: 'none', stroke: '#fff', strokeWidth: stroke, strokeLinecap: 'square', strokeLinejoin: 'miter' };
  switch (glyph) {
    case 'chat':   return <svg {...common}><path d="M4 5h16v11H9l-5 4z"/></svg>;
    case 'envelope': return <svg {...common}><path d="M3 6h18v12H3z"/><path d="M3 6l9 7 9-7"/></svg>;
    case 'call':   return <svg {...common}><circle cx="12" cy="12" r="8"/><circle cx="12" cy="12" r="3" fill="#fff"/></svg>;
    case 'doc':    return <svg {...common}><path d="M6 3h9l4 4v14H6z"/><path d="M9 9h7M9 13h7M9 17h5"/></svg>;
    case 'file':   return <svg {...common}><path d="M5 5h7l3 3h4v11H5z"/></svg>;
    case 'bucket': return <svg {...common}><path d="M4 7l2 13h12l2-13z"/><path d="M4 7h16"/></svg>;
    case 'branch': return <svg {...common}><circle cx="7" cy="6" r="2"/><circle cx="7" cy="18" r="2"/><circle cx="17" cy="12" r="2"/><path d="M7 8v8M7 12c0-3 3-4 6-4"/></svg>;
    case 'db':     return <svg {...common}><ellipse cx="12" cy="6" rx="7" ry="2.5"/><path d="M5 6v12c0 1.4 3.1 2.5 7 2.5s7-1.1 7-2.5V6"/><path d="M5 12c0 1.4 3.1 2.5 7 2.5s7-1.1 7-2.5"/></svg>;
    case 'crm':    return <svg {...common}><circle cx="12" cy="9" r="3"/><path d="M5 20c1.5-3.5 4-5 7-5s5.5 1.5 7 5"/></svg>;
    case 'support':return <svg {...common}><path d="M4 13v-1a8 8 0 0116 0v1"/><path d="M4 13h3v5H5a1 1 0 01-1-1zM20 13h-3v5h2a1 1 0 001-1z"/></svg>;
    case 'issue':  return <svg {...common}><circle cx="12" cy="12" r="8"/><path d="M12 7v6M12 16v.5"/></svg>;
    case 'chart':  return <svg {...common}><path d="M4 20V8M10 20V4M16 20v-8M22 20H2"/></svg>;
    case 'hook':   return <svg {...common}><path d="M12 3v10a4 4 0 104 4"/></svg>;
    case 'api':    return <svg {...common}><path d="M8 6L3 12l5 6M16 6l5 6-5 6"/></svg>;
    case 'upload': return <svg {...common}><path d="M12 4v12M7 9l5-5 5 5M4 20h16"/></svg>;
    default: return <svg {...common}><rect x="5" y="5" width="14" height="14"/></svg>;
  }
}

// Vendor logo tile — geometric glyph on brand-ish colored surface
function VendorLogo({ vendor, size = 32, radius = 8 }) {
  const v = VENDORS[vendor];
  if (!v) return null;
  return (
    <div style={{
      width: size, height: size, borderRadius: radius,
      background: v.color, display: 'inline-flex',
      alignItems: 'center', justifyContent: 'center',
      flexShrink: 0
    }}>
      <VendorGlyph glyph={v.glyph} size={size * 0.56} />
    </div>
  );
}

function StatusDot({ kind = 'live', size = 8 }) {
  const colors = {
    live:    'var(--success)',
    syncing: 'var(--accent)',
    paused:  'var(--text-tertiary)',
    partial: 'var(--warning)',
    error:   'var(--error)',
  };
  const pulse = kind === 'live' || kind === 'syncing';
  return (
    <span style={{
      width: size, height: size, borderRadius: '50%',
      background: colors[kind] || colors.live,
      display: 'inline-block',
      flexShrink: 0,
    }} className={pulse ? 'pulse' : ''} />
  );
}

function Sparkline({ data, color, height = 36, filled = false, width = '100%' }) {
  const w = 200, h = height;
  const min = Math.min(...data), max = Math.max(...data);
  const range = max - min || 1;
  const step = w / (data.length - 1);
  const points = data.map((v, i) => [i * step, h - ((v - min) / range) * (h - 4) - 2]);
  const path = points.map((p, i) => (i === 0 ? 'M' : 'L') + p[0].toFixed(1) + ' ' + p[1].toFixed(1)).join(' ');
  const area = path + ` L ${w} ${h} L 0 ${h} Z`;
  const c = color || 'var(--accent)';
  return (
    <svg viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none" style={{ width, height: h, display: 'block' }}>
      {filled && <path d={area} fill={c} opacity="0.12" />}
      <path d={path} fill="none" stroke={c} strokeWidth="1.5" strokeLinejoin="round" strokeLinecap="round" vectorEffect="non-scaling-stroke" />
    </svg>
  );
}

function Bars({ data, height = 36, color, width = '100%' }) {
  const n = data.length;
  const max = Math.max(...data);
  const c = color || 'var(--accent)';
  return (
    <svg viewBox={`0 0 ${n * 6} ${height}`} preserveAspectRatio="none" style={{ width, height, display: 'block' }}>
      {data.map((v, i) => (
        <rect key={i} x={i * 6 + 1} y={height - (v / max) * (height - 2)} width="4" height={(v / max) * (height - 2)} fill={c} opacity={0.7 + (i / n) * 0.3} />
      ))}
    </svg>
  );
}

// Progress bar
function Progress({ value, height = 4, color }) {
  return (
    <div style={{ width: '100%', height, background: 'var(--border-subtle)', borderRadius: 99, overflow: 'hidden' }}>
      <div style={{
        width: `${value}%`, height: '100%',
        background: color || 'var(--accent)',
        borderRadius: 99,
        transition: 'width 240ms cubic-bezier(.2,.8,.2,1)'
      }} />
    </div>
  );
}

// Code block with copy
function CodeBlock({ children, language = 'json', lines }) {
  const [copied, setCopied] = useState(false);
  const onCopy = () => { setCopied(true); setTimeout(() => setCopied(false), 1500); };
  const text = typeof children === 'string' ? children : Array.isArray(children) ? children.join('\n') : '';
  return (
    <div style={{
      background: 'var(--bg)', border: '1px solid var(--border-subtle)',
      borderRadius: 8, position: 'relative', overflow: 'hidden'
    }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '8px 12px', borderBottom: '1px solid var(--border-subtle)' }}>
        <span className="mono-sm mono text-tertiary">{language}</span>
        <button className="btn sm ghost" onClick={onCopy}>
          <Icons.Copy size={12} /> {copied ? 'Copied' : 'Copy'}
        </button>
      </div>
      <pre className="mono" style={{
        margin: 0, padding: '12px 16px',
        fontSize: 12, lineHeight: '20px',
        overflowX: 'auto', color: 'var(--text-primary)',
        whiteSpace: 'pre',
      }}>{text}</pre>
    </div>
  );
}

// Mini-graph: static SVG, 5-8 nodes
function MiniGraph({ height = 200 }) {
  return (
    <svg viewBox="0 0 480 200" style={{ width: '100%', height, display: 'block' }}>
      <defs>
        <marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">
          <path d="M0 0L10 5L0 10z" fill="var(--text-tertiary)"/>
        </marker>
      </defs>
      {/* edges */}
      <g stroke="var(--border-strong)" strokeWidth="1" fill="none">
        <path d="M120 100 L 240 100" markerEnd="url(#arrow)"/>
        <path d="M240 100 L 360 60" markerEnd="url(#arrow)"/>
        <path d="M240 100 L 360 140" markerEnd="url(#arrow)"/>
        <path d="M240 100 L 240 175" markerEnd="url(#arrow)"/>
      </g>
      {/* edge labels */}
      <g fontSize="10" fill="var(--text-tertiary)" fontFamily="'Geist Mono', monospace">
        <text x="180" y="94" textAnchor="middle">founder</text>
        <text x="308" y="74" textAnchor="middle">builds</text>
        <text x="308" y="128" textAnchor="middle">competes</text>
        <text x="256" y="140" textAnchor="start">has_team</text>
      </g>
      {/* nodes */}
      <MGNode x={120} y={100} label="D. Amodei"   kind="Person" color="var(--accent)" />
      <MGNode x={240} y={100} label="Anthropic"   kind="Org"    color="var(--text-primary)" active />
      <MGNode x={360} y={60}  label="Claude 4"    kind="Prod"   color="var(--accent)" />
      <MGNode x={360} y={140} label="Competitor"  kind="Org"    color="var(--text-secondary)" />
      <MGNode x={240} y={180} label="Safety Team" kind="Team"   color="var(--accent)" />
    </svg>
  );
}
function MGNode({ x, y, label, kind, color, active }) {
  return (
    <g transform={`translate(${x} ${y})`}>
      <circle r={active ? 26 : 20} fill="var(--surface)" stroke={color} strokeWidth={active ? 2 : 1.2}/>
      <text y={4} textAnchor="middle" fontSize="10" fill="var(--text-primary)" fontWeight="500">{label}</text>
      <text y={active ? 42 : 35} textAnchor="middle" fontSize="9" fill="var(--text-tertiary)" fontFamily="'Geist Mono', monospace">{kind}</text>
    </g>
  );
}

Object.assign(window, { VendorLogo, VendorGlyph, StatusDot, Sparkline, Bars, Progress, CodeBlock, MiniGraph });
