"use client";

import React, { useId, useMemo } from "react";
import { motion } from "framer-motion";
import { cn } from "../utils/cn";

interface MarkerProps {
  children: React.ReactNode;
  delay?: number;
  className?: string;
  color?: string;
}

/**
 * Copic Marker Component
 *
 * Uses hand-drawn filled polygon paths (NOT rects or strokes) for an
 * organic, human feel. Each highlight band is a wobbly shape with
 * bezier curves, not a perfect rectangle. Second strokes are offset
 * to simulate imperfect re-highlighting.
 */

// Seeded PRNG for SSR-safe randomness
function createRng(seed: string) {
  let s = 0;
  for (let i = 0; i < seed.length; i++) {
    s = ((s << 5) - s + seed.charCodeAt(i)) | 0;
  }
  return () => {
    s = (s * 16807 + 0) % 2147483647;
    return (s & 0x7fffffff) / 0x7fffffff;
  };
}

/**
 * Generate a hand-drawn highlight band path.
 * Instead of a rectangle, we trace an organic polygon with wobbly edges.
 *
 * The shape goes: left edge → top edge (left to right) → right edge → bottom edge (right to left)
 * Each edge has 1-2 control points for subtle curves.
 *
 * ViewBox: 0 0 100 100 with preserveAspectRatio="none"
 * So x=0..100 maps to text width, y=0..100 maps to text height.
 */
function generateBandPath(rng: () => number, bandIndex: number) {
  // Vertical position: center band in the text height
  // First band centered around y=50, second shifted up or down
  const yOffset = bandIndex === 0 ? 0 : (rng() - 0.5) * 20; // -10 to +10 shift
  const yCenter = 50 + yOffset;

  // Band thickness: covers ~40-50% of text height
  const halfHeight = 20 + rng() * 8; // 20-28 units (40-56% of viewBox)
  const yTop = yCenter - halfHeight;
  const yBottom = yCenter + halfHeight;

  // Horizontal extent: slight random overshoot/undershoot
  const xStart = -2 + rng() * 3; // -2 to 1
  const xEnd = 99 + rng() * 3; // 99 to 102

  // Generate wobbly top edge points (left to right)
  const topWobble1 = yTop + (rng() - 0.5) * 6;
  const topWobble2 = yTop + (rng() - 0.5) * 6;
  const topWobble3 = yTop + (rng() - 0.5) * 6;

  // Generate wobbly bottom edge points (right to left)
  const botWobble1 = yBottom + (rng() - 0.5) * 6;
  const botWobble2 = yBottom + (rng() - 0.5) * 6;
  const botWobble3 = yBottom + (rng() - 0.5) * 6;

  // Slight angle on left/right edges
  const leftTopY = yTop + (rng() - 0.5) * 4;
  const leftBotY = yBottom + (rng() - 0.5) * 4;
  const rightTopY = yTop + (rng() - 0.5) * 4;
  const rightBotY = yBottom + (rng() - 0.5) * 4;

  // Build the path:
  // Start at top-left, trace top edge with curves, down right edge,
  // trace bottom edge with curves back left, close.
  const path = [
    // Start top-left
    `M ${xStart},${leftTopY}`,
    // Top edge: 3 curve segments left→right
    `C ${xStart + 15},${topWobble1} ${xStart + 30},${topWobble1} ${33},${topWobble2}`,
    `C ${45},${topWobble2} ${55},${topWobble3} ${67},${topWobble3}`,
    `C ${78},${topWobble3} ${xEnd - 10},${rightTopY} ${xEnd},${rightTopY}`,
    // Right edge down
    `L ${xEnd + (rng() - 0.5) * 2},${rightBotY}`,
    // Bottom edge: 3 curve segments right→left
    `C ${xEnd - 10},${botWobble1} ${78},${botWobble1} ${67},${botWobble2}`,
    `C ${55},${botWobble2} ${45},${botWobble3} ${33},${botWobble3}`,
    `C ${xStart + 30},${botWobble3} ${xStart + 15},${leftBotY} ${xStart},${leftBotY}`,
    // Close
    `Z`,
  ].join(" ");

  return path;
}

export const Marker: React.FC<MarkerProps> = ({
  children,
  delay = 0,
  className = "",
  color = "rgba(250, 204, 21, 0.5)",
}) => {
  const id = useId();
  const filterId = `marker-rough-${id.replace(/:/g, "")}`;

  const bands = useMemo(() => {
    const rng = createRng(id);
    const numBands = rng() > 0.5 ? 2 : 1;
    const result = [];

    for (let i = 0; i < numBands; i++) {
      result.push({
        d: generateBandPath(rng, i),
        delay: delay + i * 0.15,
        duration: 0.4 + rng() * 0.15,
      });
    }
    return result;
  }, [id, delay]);

  return (
    <span className={cn("relative inline px-1", className)}>
      <svg
        className="absolute inset-0 h-full w-full pointer-events-none z-[-1] overflow-visible mix-blend-multiply"
        preserveAspectRatio="none"
        viewBox="0 0 100 100"
        xmlns="http://www.w3.org/2000/svg"
        aria-hidden="true"
      >
        <defs>
          <filter id={filterId} x="-5%" y="-5%" width="110%" height="110%">
            {/* Very subtle edge wobble — alcohol ink bleed, not brush fraying */}
            <feTurbulence
              type="fractalNoise"
              baseFrequency="0.04 0.3"
              numOctaves="2"
              seed={Math.abs(id.charCodeAt(1) || 42)}
              result="noise"
            />
            <feDisplacementMap
              in="SourceGraphic"
              in2="noise"
              scale="1.5"
              xChannelSelector="R"
              yChannelSelector="G"
            />
          </filter>
        </defs>

        {bands.map((band, i) => (
          <motion.path
            key={i}
            d={band.d}
            fill={color}
            filter={`url(#${filterId})`}
            initial={{ scaleX: 0, opacity: 0 }}
            whileInView={{ scaleX: 1, opacity: 1 }}
            viewport={{ once: true, margin: "-10%" }}
            transition={{
              scaleX: {
                duration: band.duration,
                delay: band.delay,
                ease: [0.4, 0, 0.2, 1],
              },
              opacity: {
                duration: 0.1,
                delay: band.delay,
              },
            }}
            style={{ transformOrigin: "left center" }}
          />
        ))}
      </svg>
      <span className="relative z-10 font-semibold" style={{ color: "#000" }}>
        {children}
      </span>
    </span>
  );
};
