// Crayon-style marks — chunky, textured, slightly irregular strokes.
// Three variants per mark so repeated use doesn't look identical.

if (typeof document !== "undefined" && !document.getElementById("__crayon_defs__")) {
  const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
  svg.setAttribute("id", "__crayon_defs__");
  svg.setAttribute("width", "0");
  svg.setAttribute("height", "0");
  svg.style.position = "absolute";
  svg.innerHTML = `
    <defs>
      <filter id="crayon-texture" x="-20%" y="-20%" width="140%" height="140%">
        <feTurbulence type="fractalNoise" baseFrequency="0.9" numOctaves="2" seed="7" result="noise"/>
        <feDisplacementMap in="SourceGraphic" in2="noise" scale="2.2" xChannelSelector="R" yChannelSelector="G"/>
      </filter>
      <filter id="crayon-rough" x="-30%" y="-30%" width="160%" height="160%">
        <feTurbulence type="fractalNoise" baseFrequency="1.4" numOctaves="2" seed="3" result="noise"/>
        <feDisplacementMap in="SourceGraphic" in2="noise" scale="1.3" xChannelSelector="R" yChannelSelector="G"/>
      </filter>
      <filter id="crayon-text" x="-5%" y="-5%" width="110%" height="110%">
        <feTurbulence type="fractalNoise" baseFrequency="2.6" numOctaves="2" seed="11" result="noise"/>
        <feColorMatrix in="noise" type="matrix"
          values="0 0 0 0 0
                  0 0 0 0 0
                  0 0 0 0 0
                  0 0 0 1.2 -0.2" result="grain"/>
        <feComposite in="SourceGraphic" in2="grain" operator="out" result="eroded"/>
        <feTurbulence type="fractalNoise" baseFrequency="0.05" numOctaves="1" seed="5" result="wobble"/>
        <feDisplacementMap in="eroded" in2="wobble" scale="0.8" xChannelSelector="R" yChannelSelector="G"/>
      </filter>
    </defs>
  `;
  if (document.body) document.body.appendChild(svg);
  else document.addEventListener("DOMContentLoaded", () => document.body.appendChild(svg));
}

// Scroll-triggered stroke-draw hook: when the ref enters the viewport,
// animate each path's stroke-dashoffset from full length → 0.
const useDrawInStrokes = (refs, delayBase = 0, stepMs = 80, durMs = 650) => {
  const rootRef = React.useRef(null);
  const [drawn, setDrawn] = React.useState(false);
  React.useEffect(() => {
    if (!rootRef.current) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) { setDrawn(true); io.unobserve(e.target); }
      });
    }, { threshold: 0.35, rootMargin: "0px 0px -8% 0px" });
    io.observe(rootRef.current);
    return () => io.disconnect();
  }, []);
  React.useEffect(() => {
    refs.forEach((r, i) => {
      if (!r.current) return;
      const len = r.current.getTotalLength();
      r.current.style.strokeDasharray = String(len);
      r.current.style.strokeDashoffset = drawn ? "0" : String(len);
      r.current.style.transition =
        `stroke-dashoffset ${durMs}ms cubic-bezier(.45,.1,.3,1) ${delayBase + i * stepMs}ms`;
    });
  }, [drawn]);
  return rootRef;
};

// Crayon underline: three overlapping wobbly strokes, drawn in on scroll
const HandUnderline = ({ children, color = "var(--ocean-500)", thickness = 6, variant = 0 }) => {
  const paths = [
    ["M2,10 C 60,4 140,14 220,8 C 280,5 340,12 398,9",
     "M3,12 C 80,16 160,6 240,12 C 310,16 360,8 397,11",
     "M4,8 C 100,6 180,12 260,7 C 320,4 370,11 396,7"],
    ["M3,11 C 70,15 150,5 230,12 C 300,18 360,7 398,10",
     "M2,9 C 90,5 170,13 250,7 C 320,4 370,10 396,9",
     "M4,13 C 110,10 200,16 280,11 C 340,8 380,13 397,12"],
    ["M2,9 C 50,4 110,13 170,7 C 240,3 310,14 398,8",
     "M3,12 C 80,16 170,8 250,13 C 320,17 370,10 397,14",
     "M4,7 C 120,10 220,5 300,10 C 350,13 380,8 396,9"],
  ];
  const stroke = paths[variant % paths.length];
  const pathRefs = [React.useRef(null), React.useRef(null), React.useRef(null)];
  const rootRef = useDrawInStrokes(pathRefs, 120, 80, 600);
  return (
    <span ref={rootRef}
          style={{ position: "relative", display: "inline-block",
                   whiteSpace: "nowrap", padding: "0 0.05em" }}>
      <span style={{ position: "relative", zIndex: 1 }}>{children}</span>
      <svg viewBox="0 0 400 22" preserveAspectRatio="none" aria-hidden
           style={{ position: "absolute", left: "-2%", right: "-2%", width: "104%",
                    bottom: "-0.22em", height: "0.5em", overflow: "visible",
                    filter: "url(#crayon-rough)", pointerEvents: "none" }}>
        <path ref={pathRefs[0]} d={stroke[0]} fill="none" stroke={color}
              strokeWidth={thickness * 1.35} strokeLinecap="round" opacity="0.35"/>
        <path ref={pathRefs[1]} d={stroke[1]} fill="none" stroke={color}
              strokeWidth={thickness} strokeLinecap="round" opacity="0.7"/>
        <path ref={pathRefs[2]} d={stroke[2]} fill="none" stroke={color}
              strokeWidth={thickness * 0.65} strokeLinecap="round" opacity="0.95"/>
      </svg>
    </span>
  );
};

// Crayon-highlight (kept from previous version)
const HandHighlight = ({ children, color = "var(--gold-500)", variant = 0 }) => {
  const sweeps = [
    ["M4,22 C 120,18 240,26 396,20","M3,28 C 140,32 260,24 397,30",
     "M5,34 C 100,30 220,38 395,32","M4,16 C 180,20 300,14 396,18"],
    ["M3,20 C 100,25 220,17 395,22","M4,26 C 160,22 280,30 396,25",
     "M5,32 C 130,36 250,28 394,33","M2,14 C 120,10 260,18 396,14"],
    ["M5,24 C 140,18 260,28 396,22","M3,30 C 100,34 220,26 395,31",
     "M4,36 C 180,32 300,40 396,34","M4,18 C 110,22 230,14 395,19"],
  ];
  const lines = sweeps[variant % sweeps.length];
  const pathRefs = [React.useRef(null), React.useRef(null), React.useRef(null), React.useRef(null)];
  const rootRef = useDrawInStrokes(pathRefs, 80, 90, 700);
  return (
    <span ref={rootRef}
          style={{ position: "relative", display: "inline-block",
                   whiteSpace: "nowrap", padding: "0 0.12em" }}>
      <svg viewBox="0 0 400 50" preserveAspectRatio="none" aria-hidden
           style={{ position: "absolute", inset: "-0.15em -0.18em -0.18em",
                    width: "calc(100% + 0.36em)", height: "calc(100% + 0.33em)",
                    zIndex: 0, pointerEvents: "none", filter: "url(#crayon-texture)" }}>
        {lines.map((d, i) => (
          <path key={i} ref={pathRefs[i]} d={d} fill="none" stroke={color}
                strokeWidth={i === 0 || i === 1 ? 12 : 10}
                strokeLinecap="round"
                opacity={i === 0 ? 0.55 : i === 1 ? 0.6 : 0.45}/>
        ))}
      </svg>
      <span style={{ position: "relative", zIndex: 1 }}>{children}</span>
    </span>
  );
};

// CrayonText — renders text that looks like it was written in crayon:
// grainy edges, slight wobble, waxy layered fill.
const CrayonText = ({ children, color = "var(--navy-500)" }) => (
  <span style={{
    position: "relative", display: "inline-block",
    color,
    filter: "url(#crayon-text)",
    // layered text-shadow creates the chunky, waxy buildup of crayon
    textShadow: `
      0.5px 0.5px 0 ${color},
      -0.5px 0.5px 0 ${color},
      0.5px -0.5px 0 ${color},
      -0.5px -0.5px 0 ${color},
      1px 0 0 ${color}80,
      -1px 0 0 ${color}80,
      0 1px 0 ${color}80
    `,
  }}>
    {children}
  </span>
);

// HandWritten — Caveat-font word with crayon texture. On scroll-in:
// the word reveals left→right via an animated clip-path whose right edge
// has a wobbly "pen tip" shape (not a flat line) so it reads as being
// hand-written rather than swept. A matching crayon underline draws in after.
const HandWritten = ({ children, color = "var(--ocean-500)", underline = true,
                       variant = 0 }) => {
  const paths = [
    ["M2,10 C 60,4 140,14 220,8 C 280,5 340,12 398,9",
     "M3,12 C 80,16 160,6 240,12 C 310,16 360,8 397,11",
     "M4,8 C 100,6 180,12 260,7 C 320,4 370,11 396,7"],
    ["M3,11 C 70,15 150,5 230,12 C 300,18 360,7 398,10",
     "M2,9 C 90,5 170,13 250,7 C 320,4 370,10 396,9",
     "M4,13 C 110,10 200,16 280,11 C 340,8 380,13 397,12"],
    ["M2,9 C 50,4 110,13 170,7 C 240,3 310,14 398,8",
     "M3,12 C 80,16 170,8 250,13 C 320,17 370,10 397,14",
     "M4,7 C 120,10 220,5 300,10 C 350,13 380,8 396,9"],
  ];
  const stroke = paths[variant % paths.length];
  const thickness = 6;
  // Extract a plain text representation regardless of whether children is a
  // raw string or an instrumentation-wrapped React element. This is used for
  // length-based pacing of the underline draw-in only.
  const extractText = (n) => {
    if (n == null || typeof n === "boolean") return "";
    if (typeof n === "string" || typeof n === "number") return String(n);
    if (Array.isArray(n)) return n.map(extractText).join("");
    if (n.props && n.props.children) return extractText(n.props.children);
    return "";
  };
  const text = extractText(children);

  const rootRef = React.useRef(null);
  // Always reveal immediately — the previous progressive clip-path/opacity
  // reveal had frame-commit issues where above-the-fold text would render
  // invisible on first paint. Underline still draws in.
  const drawn = true;

  React.useEffect(() => {}, []);

  const visibleChars = text.replace(/\s+/g, "").length;
  const writeMs = Math.max(800, visibleChars * 130);
  const underlineDelay = writeMs - 60;
  const underlineMs = 750;

  const uPathRefs = [React.useRef(null), React.useRef(null), React.useRef(null)];
  React.useEffect(() => {
    uPathRefs.forEach((r, i) => {
      if (!r.current) return;
      const len = r.current.getTotalLength();
      r.current.style.strokeDasharray = String(len);
      r.current.style.strokeDashoffset = drawn ? "0" : String(len);
      r.current.style.transition =
        `stroke-dashoffset ${underlineMs}ms cubic-bezier(.45,.1,.3,1) ${underlineDelay + i * 80}ms`;
    });
  }, [drawn]);

  // Animated wobbly clip-path — the right edge zig-zags as it moves,
  // making individual letters reveal at different vertical rates.
  // Uses a unique keyframe name per variant so multiple HandWritten
  // components can coexist without animation collisions.
  const animName = `hw-write-${variant}`;

  return (
    <span ref={rootRef}
          style={{ position: "relative", display: "inline-block",
                   whiteSpace: "nowrap", lineHeight: 1,
                   verticalAlign: "baseline" }}>
      <span style={{
        position: "relative",
        display: "inline-block",
        fontFamily: "'Caveat', cursive",
        fontWeight: 700,
        color,
        letterSpacing: "-0.01em",
        fontSize: "1.18em",
        lineHeight: 1,
        paddingRight: "0.2em",
        filter: "url(#crayon-rough)",
        textShadow: `
          0.6px 0 0 ${color}, -0.6px 0 0 ${color},
          0 0.6px 0 ${color}, 0 -0.6px 0 ${color}
        `,
        opacity: 1,
        transform: "translateX(0)",
      }}>
        {children}
      </span>

      {underline && (
        <svg viewBox="0 0 400 22" preserveAspectRatio="none" aria-hidden
             style={{ position: "absolute", left: "-2%", right: "-2%", width: "104%",
                      bottom: "-0.12em", height: "0.4em", overflow: "visible",
                      filter: "url(#crayon-rough)", pointerEvents: "none" }}>
          {[
            { d: stroke[0], w: thickness * 1.35, op: 0.35 },
            { d: stroke[1], w: thickness,        op: 0.7  },
            { d: stroke[2], w: thickness * 0.65, op: 0.95 },
          ].map((p, i) => (
            <path key={i} ref={uPathRefs[i]} d={p.d} fill="none" stroke={color}
                  strokeWidth={p.w} strokeLinecap="round" opacity={p.op}/>
          ))}
        </svg>
      )}
    </span>
  );
};

Object.assign(window, { HandUnderline, HandHighlight, CrayonText, HandWritten });
