"use client";

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

interface StrikethroughProps {
  children: string; // Enforce string children for splitting
  delay?: number;
  className?: string;
  color?: string;
}

/**
 * Hand-drawn Strikethrough Component
 *
 * NOW SUPPORTS MULTI-LINE TEXT!
 *
 * Strategy: Splits the text into individual words. Each word is wrapped
 * in a span with its own SVG strikethrough. This allows the text to
 * wrap naturally across lines, and each word carries its strikethrough
 * with it.
 */

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;
  };
}

function generateStrikePath(rng: () => number) {
  // Simple approach: just a slightly wobbly line from left to right
  // through vertical center (y=50).
  const points: { x: number; y: number }[] = [];
  const numPoints = 4; // Fewer points for shorter word segments

  for (let i = 0; i <= numPoints; i++) {
    const x = (i / numPoints) * 100;
    const y = 55 + (rng() - 0.5) * 15; // ±7.5 units wobble
    points.push({ x, y });
  }

  // Build a smooth path through all points
  let d = `M ${points[0].x},${points[0].y}`;
  for (let i = 1; i < points.length - 1; i++) {
    const midX = (points[i].x + points[i + 1].x) / 2;
    const midY = (points[i].y + points[i + 1].y) / 2;
    d += ` Q ${points[i].x},${points[i].y} ${midX},${midY}`;
  }
  const last = points[points.length - 1];
  d += ` L ${last.x},${last.y}`;

  return d;
}

const WordStrike: React.FC<{
  word: string;
  index: number;
  baseDelay: number;
  color: string;
  seed: string;
}> = ({ word, index, baseDelay, color, seed }) => {
  // Unique seed per word so they look different
  const uniqueSeed = `${seed}-${index}-${word}`;

  const path = useMemo(() => {
    const rng = createRng(uniqueSeed);
    return generateStrikePath(rng);
  }, [uniqueSeed]);

  return (
    <span className="relative inline-block whitespace-nowrap">
      <svg
        className="absolute inset-0 w-full h-full pointer-events-none overflow-visible"
        preserveAspectRatio="none"
        viewBox="0 0 100 100"
        xmlns="http://www.w3.org/2000/svg"
        aria-hidden="true"
        style={{ zIndex: 10 }}
      >
        <motion.path
          d={path}
          initial={{ pathLength: 0, opacity: 0 }}
          whileInView={{ pathLength: 1, opacity: 1 }}
          viewport={{ once: true, margin: "-5%" }}
          transition={{
            pathLength: {
              duration: 0.4,
              // Stagger words slightly
              delay: baseDelay + index * 0.05,
              ease: "easeOut",
            },
            opacity: { duration: 0.1, delay: baseDelay + index * 0.05 },
          }}
          stroke={color}
          strokeWidth="2.5"
          strokeLinecap="round"
          fill="none"
          vectorEffect="non-scaling-stroke"
        />
      </svg>
      {word}
    </span>
  );
};

export const Strikethrough: React.FC<StrikethroughProps> = ({
  children,
  delay = 0,
  className = "",
  color = "rgba(220, 50, 50, 0.8)",
}) => {
  const id = useId();

  // Split by spaces but preserve them as separate elements for spacing
  // Actually, we can just split by space and rejoin with non-struck spaces
  const words = children.split(" ");

  return (
    <span className={cn("relative inline", className)}>
      {words.map((word, i) => (
        <React.Fragment key={i}>
          <WordStrike
            word={word}
            index={i}
            baseDelay={delay}
            color={color}
            seed={id}
          />
          {i < words.length - 1 && " "}
        </React.Fragment>
      ))}
    </span>
  );
};
