/* ===========================================================
   camo.jsx — abstract camouflage pattern components
   Three styles: "organic" (blobs), "topo" (contour lines), "dots" (halftone)
   All rendered as inline SVG, tonal variations of CSS vars.
   =========================================================== */

const { useId, useMemo } = React;

/* --- Seeded random for stable shapes between renders --- */
function rng(seed) {
  let s = seed | 0;
  return () => {
    s = (s * 1664525 + 1013904223) | 0;
    return ((s >>> 0) % 100000) / 100000;
  };
}

/* ====================== ORGANIC BLOB CAMO ====================== */
function blobPath(rand, cx, cy, baseR) {
  const steps = 10 + Math.floor(rand() * 4);
  const pts = [];
  for (let i = 0; i < steps; i++) {
    const a = (i / steps) * Math.PI * 2;
    const r = baseR * (0.65 + rand() * 0.6);
    pts.push([cx + Math.cos(a) * r, cy + Math.sin(a) * r]);
  }
  // smooth via cubic
  let d = `M ${pts[0][0].toFixed(1)} ${pts[0][1].toFixed(1)}`;
  for (let i = 0; i < pts.length; i++) {
    const p0 = pts[i];
    const p1 = pts[(i + 1) % pts.length];
    const p2 = pts[(i + 2) % pts.length];
    const cpx = p1[0] + (p2[0] - p0[0]) * 0.12;
    const cpy = p1[1] + (p2[1] - p0[1]) * 0.12;
    d += ` Q ${p1[0].toFixed(1)} ${p1[1].toFixed(1)} ${cpx.toFixed(1)} ${cpy.toFixed(1)}`;
  }
  return d + " Z";
}

function CamoOrganic({ seed = 7, width = 1600, height = 1000, tones, opacity = 1, dense = 1 }) {
  const id = useId();
  const blobs = useMemo(() => {
    const rand = rng(seed);
    const blobCount = Math.floor(28 * dense);
    const arr = [];
    for (let i = 0; i < blobCount; i++) {
      arr.push({
        cx: rand() * width,
        cy: rand() * height,
        r: 60 + rand() * 220,
        tone: Math.floor(rand() * tones.length),
        rot: rand() * 360,
      });
    }
    return arr;
  }, [seed, width, height, tones.length, dense]);

  return (
    <svg viewBox={`0 0 ${width} ${height}`} preserveAspectRatio="xMidYMid slice"
         style={{ width: "100%", height: "100%", opacity }} aria-hidden="true">
      <defs>
        <filter id={`blur-${id}`} x="-10%" y="-10%" width="120%" height="120%">
          <feGaussianBlur stdDeviation="0.6" />
        </filter>
      </defs>
      <g filter={`url(#blur-${id})`}>
        {blobs.map((b, i) => (
          <path key={i}
                d={blobPath(rng(seed + i * 17), b.cx, b.cy, b.r)}
                fill={tones[b.tone]}
                transform={`rotate(${b.rot} ${b.cx} ${b.cy})`} />
        ))}
      </g>
    </svg>
  );
}

/* ====================== TOPOGRAPHIC CAMO ====================== */
function CamoTopo({ seed = 3, width = 1600, height = 1000, tones, opacity = 1, dense = 1 }) {
  // concentric, slightly noisy elliptical contours mimicking terrain
  const centers = useMemo(() => {
    const rand = rng(seed);
    const arr = [];
    const n = Math.floor(6 * dense);
    for (let i = 0; i < n; i++) {
      arr.push({
        cx: rand() * width,
        cy: rand() * height,
        rx: 120 + rand() * 320,
        ry: 80 + rand() * 240,
        rot: rand() * 360,
        rings: 7 + Math.floor(rand() * 6),
        tone: Math.floor(rand() * tones.length),
      });
    }
    return arr;
  }, [seed, width, height, tones.length, dense]);

  return (
    <svg viewBox={`0 0 ${width} ${height}`} preserveAspectRatio="xMidYMid slice"
         style={{ width: "100%", height: "100%", opacity }} aria-hidden="true">
      {centers.map((c, ci) => (
        <g key={ci} transform={`rotate(${c.rot} ${c.cx} ${c.cy})`}>
          {Array.from({ length: c.rings }).map((_, ri) => {
            const t = (ri + 1) / c.rings;
            return (
              <ellipse key={ri}
                       cx={c.cx} cy={c.cy}
                       rx={c.rx * t} ry={c.ry * t}
                       fill="none"
                       stroke={tones[(c.tone + ri) % tones.length]}
                       strokeWidth={1}
                       vectorEffect="non-scaling-stroke" />
            );
          })}
        </g>
      ))}
    </svg>
  );
}

/* ====================== HALFTONE DOT CAMO ====================== */
function CamoDots({ seed = 11, width = 1600, height = 1000, tones, opacity = 1, dense = 1 }) {
  // dot grid where size & color vary by a Perlin-ish noise function
  const dots = useMemo(() => {
    const rand = rng(seed);
    const spacing = 22;
    const arr = [];
    // generate a sparse field of "centers" that pull big dots
    const fields = [];
    for (let i = 0; i < 7 * dense; i++) {
      fields.push({ x: rand() * width, y: rand() * height, r: 220 + rand() * 280 });
    }
    for (let y = 0; y < height; y += spacing) {
      for (let x = 0; x < width; x += spacing) {
        let influence = 0;
        for (const f of fields) {
          const dx = x - f.x, dy = y - f.y;
          const d = Math.sqrt(dx*dx + dy*dy);
          influence += Math.max(0, 1 - d / f.r);
        }
        const v = Math.min(1, influence);
        const jitterX = (rand() - 0.5) * 6;
        const jitterY = (rand() - 0.5) * 6;
        const size = 0.5 + v * 3.6;
        const toneIdx = Math.min(tones.length - 1, Math.floor(v * tones.length));
        arr.push({ x: x + jitterX, y: y + jitterY, r: size, tone: toneIdx });
      }
    }
    return arr;
  }, [seed, width, height, tones.length, dense]);

  return (
    <svg viewBox={`0 0 ${width} ${height}`} preserveAspectRatio="xMidYMid slice"
         style={{ width: "100%", height: "100%", opacity }} aria-hidden="true">
      {dots.map((d, i) => (
        <circle key={i} cx={d.x} cy={d.y} r={d.r} fill={tones[d.tone]} />
      ))}
    </svg>
  );
}

/* ====================== ROUTER ====================== */
function Camo({ variant = "organic", tones, ...rest }) {
  if (variant === "topo") return <CamoTopo tones={tones} {...rest} />;
  if (variant === "dots") return <CamoDots tones={tones} {...rest} />;
  return <CamoOrganic tones={tones} {...rest} />;
}

/* ====================== LOGO MARK ====================== */
/* Stylized "C" formed by camo blobs collapsing into a precise letterform */
function CamoufLogo({ size = 28, color = "currentColor" }) {
  return (
    <svg width={size} height={size} viewBox="0 0 32 32" fill="none" aria-hidden="true">
      {/* outer ring with notch (resembles a tactical reticle + camo splash) */}
      <circle cx="16" cy="16" r="14" stroke={color} strokeWidth="1.4" />
      {/* inner camo-style shape: blob mass forming negative C */}
      <path d="M22 9.5 C 17.5 7.5, 12.5 8.5, 10 12 C 7.8 15, 8 19, 10.5 21.5 C 13 24, 18 24.5, 22 22.5"
            stroke={color} strokeWidth="2.2" fill="none" strokeLinecap="square" />
      <circle cx="16" cy="16" r="1.2" fill={color} />
      <line x1="16" y1="0" x2="16" y2="3" stroke={color} strokeWidth="1" />
      <line x1="16" y1="29" x2="16" y2="32" stroke={color} strokeWidth="1" />
      <line x1="0" y1="16" x2="3" y2="16" stroke={color} strokeWidth="1" />
      <line x1="29" y1="16" x2="32" y2="16" stroke={color} strokeWidth="1" />
    </svg>
  );
}

Object.assign(window, { Camo, CamoOrganic, CamoTopo, CamoDots, CamoufLogo });
