/* global React */

// PixelMosaic — irregular cloud-like shape made of square cells.
// Inspired by the Synthetic Eden reference posters. Deterministic per `seed`.
function PixelMosaic({
  seed = 1,
  cols = 18,
  rows = 12,
  cell = 12,
  gap = 2,
  color = "#B8C5D6",
  color2 = null,
  density = 0.55,
  blobs = 3,
  rounded = false,
  scatter = true,
  className = "pixel-mosaic",
  style = {},
}) {
  const cells = React.useMemo(() => {
    // simple deterministic prng
    let s = seed * 9301 + 49297;
    const rand = () => {
      s = (s * 9301 + 49297) % 233280;
      return s / 233280;
    };
    const centers = [];
    for (let b = 0; b < blobs; b++) {
      centers.push({
        cx: rand() * cols,
        cy: rand() * rows,
        r: 2 + rand() * Math.min(cols, rows) * 0.35,
      });
    }
    const out = [];
    for (let y = 0; y < rows; y++) {
      for (let x = 0; x < cols; x++) {
        let strongest = 0;
        for (const c of centers) {
          const dx = x + 0.5 - c.cx;
          const dy = y + 0.5 - c.cy;
          const d = Math.sqrt(dx * dx + dy * dy);
          // soft falloff
          const v = Math.max(0, 1 - d / c.r) + (rand() - 0.5) * 0.18;
          if (v > strongest) strongest = v;
        }
        // scatter: leave occasional outlier pixels
        const outlier = scatter && rand() < 0.012;
        if (strongest > 1 - density || outlier) {
          out.push({
            x, y,
            color: color2 && rand() < 0.18 ? color2 : color,
            opacity: 0.65 + Math.min(0.35, strongest * 0.5),
          });
        }
      }
    }
    return out;
  }, [seed, cols, rows, density, blobs, color, color2, scatter]);

  const w = cols * cell + (cols - 1) * gap;
  const h = rows * cell + (rows - 1) * gap;
  const r = rounded ? cell * 0.18 : 0;

  return (
    <svg
      className={className}
      style={style}
      viewBox={`0 0 ${w} ${h}`}
      width={w}
      height={h}
      preserveAspectRatio="xMidYMid meet"
      xmlns="http://www.w3.org/2000/svg"
    >
      {cells.map((c, i) => (
        <rect
          key={i}
          x={c.x * (cell + gap)}
          y={c.y * (cell + gap)}
          width={cell}
          height={cell}
          rx={r}
          ry={r}
          fill={c.color}
          opacity={c.opacity}
        />
      ))}
    </svg>
  );
}

// DirTexture — small textural marks for direction cards. Each direction
// gets a different motif.
function DirTexture({ kind, color = "#15151A", size = 88, mono = false }) {
  const stroke = mono ? "rgba(255,255,255,0.8)" : color;
  if (kind === "audio") {
    // waveform bars
    const bars = [4, 9, 6, 14, 18, 10, 7, 16, 22, 12, 8, 5, 11, 17, 9, 6];
    return (
      <svg viewBox="0 0 88 88" width={size} height={size}>
        {bars.map((b, i) => (
          <rect key={i} x={2 + i * 5.4} y={44 - b} width={3} height={b * 2} fill={stroke} opacity={0.85} />
        ))}
      </svg>
    );
  }
  if (kind === "visual") {
    // overlapping squares
    return (
      <svg viewBox="0 0 88 88" width={size} height={size}>
        <rect x="6" y="14" width="46" height="46" fill="none" stroke={stroke} strokeWidth="1.4" />
        <rect x="26" y="28" width="46" height="46" fill="none" stroke={stroke} strokeWidth="1.4" />
        <rect x="40" y="44" width="28" height="28" fill={stroke} opacity="0.85" />
      </svg>
    );
  }
  if (kind === "dance") {
    // figure / path lines
    return (
      <svg viewBox="0 0 88 88" width={size} height={size}>
        <path d="M10 70 Q 22 30 38 44 T 78 22" fill="none" stroke={stroke} strokeWidth="1.4" />
        <path d="M14 80 Q 30 50 50 60 T 84 36" fill="none" stroke={stroke} strokeWidth="1.4" opacity="0.6" />
        <circle cx="78" cy="22" r="3.2" fill={stroke} />
        <circle cx="10" cy="70" r="3.2" fill={stroke} />
        <circle cx="84" cy="36" r="2.4" fill={stroke} opacity="0.7" />
        <circle cx="14" cy="80" r="2.4" fill={stroke} opacity="0.7" />
      </svg>
    );
  }
  if (kind === "media") {
    // play / film sprockets
    return (
      <svg viewBox="0 0 88 88" width={size} height={size}>
        <rect x="6" y="20" width="76" height="48" fill="none" stroke={stroke} strokeWidth="1.4" />
        {[12, 26, 40, 54, 68].map((x, i) => (
          <rect key={i} x={x} y={14} width="4" height="4" fill={stroke} />
        ))}
        {[12, 26, 40, 54, 68].map((x, i) => (
          <rect key={i} x={x} y={70} width="4" height="4" fill={stroke} />
        ))}
        <polygon points="38,32 38,56 58,44" fill={stroke} />
      </svg>
    );
  }
  if (kind === "synthesis") {
    // many lines converging to one point — for the feature card
    return (
      <svg viewBox="0 0 220 220" width={size} height={size}>
        <g stroke={stroke} strokeWidth="1.2" fill="none" opacity="0.65">
          <line x1="0" y1="20" x2="160" y2="120" />
          <line x1="0" y1="60" x2="160" y2="120" />
          <line x1="0" y1="100" x2="160" y2="120" />
          <line x1="0" y1="140" x2="160" y2="120" />
          <line x1="0" y1="180" x2="160" y2="120" />
          <line x1="0" y1="220" x2="160" y2="120" />
          <line x1="40" y1="0" x2="160" y2="120" />
          <line x1="80" y1="0" x2="160" y2="120" />
          <line x1="120" y1="0" x2="160" y2="120" />
          <line x1="200" y1="0" x2="160" y2="120" />
          <line x1="220" y1="40" x2="160" y2="120" />
          <line x1="220" y1="80" x2="160" y2="120" />
          <line x1="220" y1="160" x2="160" y2="120" />
          <line x1="220" y1="220" x2="160" y2="120" />
        </g>
        <circle cx="160" cy="120" r="6" fill={stroke} />
        <circle cx="160" cy="120" r="22" fill="none" stroke={stroke} strokeWidth="1" opacity="0.4" />
        <circle cx="160" cy="120" r="44" fill="none" stroke={stroke} strokeWidth="1" opacity="0.2" />
      </svg>
    );
  }
  return null;
}

Object.assign(window, { PixelMosaic, DirTexture });
