// scene-primitives.jsx — Gold Bank flow animation primitives
// Node glyphs, gold tokens, mSSP chips, silhouettes, arcs.

const GB = {
  bg: '#0a0a0f',
  surface: 'rgba(255,255,255,0.06)',
  border: 'rgba(255,255,255,0.10)',
  borderStrong: 'rgba(255,255,255,0.18)',
  gold: '#c49a3c',
  goldHi: '#e3c06a',
  goldLo: '#8a6a24',
  goldGlow: 'rgba(196,154,60,0.35)',
  fg: '#e8e6e3',
  muted: '#a0a3ad',
  dim: '#6b7280',
};

// ── Silhouette (producer, recipient) ────────────────────────────────────────
// A simple head-and-shoulders SVG portrait, mono-gold linework, inside a glass ring.
function Silhouette({ variant = 'person', size = 72, stroke = GB.gold, opacity = 1, kind }) {
  // Different head/shoulder shapes by variant — cheap, readable at small sizes.
  const paths = {
    person: (
      <g>
        <circle cx="0" cy="-10" r="10" fill="none" stroke={stroke} strokeWidth="1.6"/>
        <path d="M -18,18 C -16,4 -8,-2 0,-2 C 8,-2 16,4 18,18"
              fill="none" stroke={stroke} strokeWidth="1.6" strokeLinecap="round"/>
      </g>
    ),
    miner: (
      <g>
        <circle cx="0" cy="-10" r="10" fill="none" stroke={stroke} strokeWidth="1.6"/>
        {/* hard hat */}
        <path d="M -13,-14 C -12,-22 12,-22 13,-14 L 13,-12 L -13,-12 Z"
              fill="none" stroke={stroke} strokeWidth="1.6"/>
        <path d="M -18,18 C -16,4 -8,-2 0,-2 C 8,-2 16,4 18,18"
              fill="none" stroke={stroke} strokeWidth="1.6" strokeLinecap="round"/>
      </g>
    ),
    merchant: (
      <g>
        <circle cx="0" cy="-10" r="10" fill="none" stroke={stroke} strokeWidth="1.6"/>
        {/* apron v-collar */}
        <path d="M -18,18 C -16,4 -8,-2 0,-2 C 8,-2 16,4 18,18 M -6,-1 L 0,6 L 6,-1"
              fill="none" stroke={stroke} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
      </g>
    ),
    worker: (
      <g>
        <circle cx="0" cy="-10" r="10" fill="none" stroke={stroke} strokeWidth="1.6"/>
        <path d="M -18,18 C -16,4 -8,-2 0,-2 C 8,-2 16,4 18,18"
              fill="none" stroke={stroke} strokeWidth="1.6" strokeLinecap="round"/>
        {/* tool handle over shoulder */}
        <line x1="-14" y1="10" x2="-20" y2="-6" stroke={stroke} strokeWidth="1.4" strokeLinecap="round"/>
      </g>
    ),
    family: (
      <g>
        <circle cx="-6" cy="-10" r="8" fill="none" stroke={stroke} strokeWidth="1.4"/>
        <circle cx="8"  cy="-6" r="5" fill="none" stroke={stroke} strokeWidth="1.4"/>
        <path d="M -18,18 C -16,6 -12,0 -6,0 C 0,0 4,4 6,10 M 2,18 C 4,10 8,6 8,2 C 12,4 16,10 18,18"
              fill="none" stroke={stroke} strokeWidth="1.4" strokeLinecap="round"/>
      </g>
    ),
  };
  const variantKey = kind || variant;
  const body = paths[variantKey] || paths.person;
  return (
    <svg width={size} height={size} viewBox="-28 -28 56 56" style={{ display: 'block', opacity }}>
      {body}
    </svg>
  );
}

// ── Node: silhouette + optional account card frame around it ────────────────
// onboarded=true adds the gold hairline ring + mono account number under the silhouette.
function Node({ x, y, variant = 'person', size = 72, onboarded = false, label, sublabel, accent = false, scale = 1, opacity = 1 }) {
  const ringColor = onboarded ? GB.gold : GB.border;
  const ringWidth = onboarded ? 1.2 : 1;
  const glow = onboarded ? `0 0 24px ${GB.goldGlow}` : 'none';
  return (
    <div style={{
      position: 'absolute',
      left: x, top: y,
      transform: `translate(-50%,-50%) scale(${scale})`,
      transformOrigin: 'center',
      opacity,
      display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6,
      willChange: 'transform, opacity',
    }}>
      <div style={{
        width: size + 16, height: size + 16,
        borderRadius: '50%',
        background: 'rgba(255,255,255,0.04)',
        border: `${ringWidth}px solid ${ringColor}`,
        boxShadow: glow,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        backdropFilter: 'blur(6px)',
      }}>
        <Silhouette variant={variant} kind={variant} size={size} stroke={accent ? GB.goldHi : GB.gold} />
      </div>
      {label ? (
        <div style={{
          fontFamily: "'JetBrains Mono', ui-monospace, monospace",
          fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase',
          color: accent ? GB.gold : GB.muted,
          whiteSpace: 'nowrap',
        }}>{label}</div>
      ) : null}
      {sublabel ? (
        <div style={{
          fontFamily: "'JetBrains Mono', ui-monospace, monospace",
          fontSize: 9, letterSpacing: '0.16em', color: GB.dim, whiteSpace: 'nowrap',
        }}>{sublabel}</div>
      ) : null}
    </div>
  );
}

// ── Gold nugget glyph — a small faceted gold token ──────────────────────────
function GoldNugget({ x, y, size = 36, rot = 0, opacity = 1 }) {
  return (
    <div style={{
      position: 'absolute',
      left: x, top: y,
      width: size, height: size,
      transform: `translate(-50%,-50%) rotate(${rot}deg)`,
      opacity,
      willChange: 'transform, opacity',
    }}>
      <svg viewBox="-20 -20 40 40" width={size} height={size}>
        <defs>
          <linearGradient id="nug-g" x1="0" y1="-1" x2="0" y2="1">
            <stop offset="0%"  stopColor="#f0d48a"/>
            <stop offset="55%" stopColor="#c49a3c"/>
            <stop offset="100%" stopColor="#8a6a24"/>
          </linearGradient>
        </defs>
        {/* faceted lump */}
        <path d="M -14,2 L -8,-12 L 6,-14 L 14,-4 L 12,10 L 0,14 L -12,10 Z"
              fill="url(#nug-g)" stroke="#8a6a24" strokeWidth="0.6"/>
        {/* highlights */}
        <path d="M -8,-12 L 6,-14 L 0,-4 Z" fill="#ffe6a8" opacity="0.5"/>
        <path d="M -14,2 L -8,-12 L -4,-2 Z" fill="#ffe6a8" opacity="0.25"/>
      </svg>
    </div>
  );
}

// ── mSSP chip — a small digital token with gold ring + "m" mark ─────────────
function MsspChip({ x, y, size = 34, opacity = 1, pulse = 0 }) {
  const r = size / 2;
  const glow = 0.3 + 0.2 * Math.sin(pulse * Math.PI * 2);
  return (
    <div style={{
      position: 'absolute',
      left: x, top: y,
      width: size, height: size,
      transform: 'translate(-50%,-50%)',
      opacity,
      willChange: 'transform, opacity',
      filter: `drop-shadow(0 0 6px rgba(196,154,60,${glow}))`,
    }}>
      <svg viewBox={`-${r} -${r} ${size} ${size}`} width={size} height={size}>
        <circle cx="0" cy="0" r={r - 2} fill="#12121a" stroke={GB.gold} strokeWidth="1.4"/>
        <circle cx="0" cy="0" r={r - 5} fill="none" stroke={GB.gold} strokeWidth="0.5" opacity="0.5"/>
        <text x="0" y="1" textAnchor="middle" dominantBaseline="middle"
              fontFamily="'JetBrains Mono', monospace" fontSize={r * 0.9} fontWeight="600"
              fill={GB.gold}>m</text>
      </svg>
    </div>
  );
}

// ── Bank node — glass card containing the seal, at center ───────────────────
function BankNode({ x, y, size = 180, scale = 1, opacity = 1, glow = false, sealSrc = '/animations/gold-bank-seal.svg' }) {
  return (
    <div style={{
      position: 'absolute',
      left: x, top: y,
      width: size + 40, height: size + 40,
      transform: `translate(-50%,-50%) scale(${scale})`,
      transformOrigin: 'center',
      opacity,
      display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
      willChange: 'transform, opacity',
    }}>
      <div style={{
        width: size, height: size,
        borderRadius: '50%',
        background: 'radial-gradient(closest-side, rgba(196,154,60,0.10), rgba(10,10,15,0.0) 70%)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        filter: glow ? `drop-shadow(0 0 40px ${GB.goldGlow})` : 'none',
      }}>
        <img src={sealSrc} width={size} height={size} style={{ display: 'block' }} />
      </div>
    </div>
  );
}

// ── Arc path between two points (for traveling tokens) ──────────────────────
// Returns a function t∈[0,1] → {x, y}
function arcPath(x1, y1, x2, y2, curvature = 0.25) {
  const mx = (x1 + x2) / 2;
  const my = (y1 + y2) / 2;
  const dx = x2 - x1, dy = y2 - y1;
  const len = Math.sqrt(dx * dx + dy * dy);
  // Perpendicular offset
  const nx = -dy / len, ny = dx / len;
  const cx = mx + nx * len * curvature;
  const cy = my + ny * len * curvature;
  return (t) => {
    const u = 1 - t;
    return {
      x: u * u * x1 + 2 * u * t * cx + t * t * x2,
      y: u * u * y1 + 2 * u * t * cy + t * t * y2,
    };
  };
}

// ── Static arc line drawn as an SVG path ────────────────────────────────────
function ArcLine({ x1, y1, x2, y2, curvature = 0.25, dash = '4 6', opacity = 0.45, strokeWidth = 1, color = GB.gold, progress = 1 }) {
  const mx = (x1 + x2) / 2, my = (y1 + y2) / 2;
  const dx = x2 - x1, dy = y2 - y1;
  const len = Math.sqrt(dx * dx + dy * dy) || 1;
  const nx = -dy / len, ny = dx / len;
  const cx = mx + nx * len * curvature;
  const cy = my + ny * len * curvature;
  const d = `M ${x1},${y1} Q ${cx},${cy} ${x2},${y2}`;
  return (
    <svg style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }} width="100%" height="100%">
      <path d={d} fill="none" stroke={color} strokeWidth={strokeWidth}
            strokeDasharray={dash} opacity={opacity}
            pathLength="1"
            strokeDashoffset={0}
            style={{
              strokeDasharray: dash,
              // simulate progress with a mask via stroke-dash if needed; we keep dashed for aesthetic
              opacity: opacity * progress,
            }}/>
    </svg>
  );
}

// ── Caption — minimal two-line label slab, fades in + out ───────────────────
function Caption({ kicker, line }) {
  const { progress, duration, localTime } = useSprite();
  const entry = 0.5, exit = 0.5;
  const fadeInT = clamp(localTime / entry, 0, 1);
  const fadeOutT = clamp((duration - localTime) / exit, 0, 1);
  const o = Math.min(fadeInT, fadeOutT);
  const ty = (1 - fadeInT) * 10;
  return (
    <div style={{
      position: 'absolute',
      left: '50%', bottom: 72,
      transform: `translate(-50%, ${ty}px)`,
      opacity: o,
      textAlign: 'center',
      willChange: 'transform, opacity',
    }}>
      {kicker ? (
        <div style={{
          fontFamily: "'JetBrains Mono', ui-monospace, monospace",
          fontSize: 11, letterSpacing: '0.24em', textTransform: 'uppercase',
          color: GB.gold, marginBottom: 8,
        }}>{kicker}</div>
      ) : null}
      <div style={{
        fontFamily: 'Fraunces, Georgia, serif',
        fontWeight: 500, fontSize: 36, letterSpacing: '-0.01em',
        color: GB.fg,
      }}>{line}</div>
    </div>
  );
}

// ── Grid of tiny dots (subtle background texture) ───────────────────────────
function DotGrid({ opacity = 0.05 }) {
  return (
    <svg style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }} width="100%" height="100%">
      <defs>
        <pattern id="dg" x="0" y="0" width="32" height="32" patternUnits="userSpaceOnUse">
          <circle cx="1" cy="1" r="1" fill={GB.gold} opacity={opacity}/>
        </pattern>
      </defs>
      <rect width="100%" height="100%" fill="url(#dg)"/>
    </svg>
  );
}

// ── Radial glow (subtle corner wash) ────────────────────────────────────────
function CornerGlow() {
  return (
    <div style={{
      position: 'absolute', inset: 0, pointerEvents: 'none',
      background: `
        radial-gradient(600px circle at 15% 20%, rgba(196,154,60,0.08), transparent 60%),
        radial-gradient(700px circle at 85% 80%, rgba(122,154,196,0.05), transparent 60%)
      `,
    }}/>
  );
}

Object.assign(window, {
  GB, Silhouette, Node, GoldNugget, MsspChip, BankNode, ArcLine, Caption,
  arcPath, DotGrid, CornerGlow,
});
