/* ============================================================
   Egg — the crackable centerpiece.
   Reusable. Pass: brandName, offerHeadline, offerBody, ctaLabel,
                  tapCount, percentOff, on…
   ============================================================ */

const { useState, useEffect, useRef, useCallback, useMemo } = React;

// ─── Crack paths — 9 progressively-added overlays.
//     Drawn in viewBox 0 0 200 260 (egg lives roughly y=20..240, x=40..160).
//     Each path renders on top, stroke-dasharray reveal.
// Each entry: { d: path, w: stroke width override }. Larger w on early hairlines
// so the first few taps read clearly across the egg's surface.
const CRACK_PATHS = [
  // 1: clear hairline at the crown, longer + bolder than before
  { d: "M 96 30 L 102 44 L 96 58 L 104 72 L 98 86" },
  // 2: a branch peeling off to the right
  { d: "M 104 72 L 116 78 L 122 88 L 134 92" },
  // 3: a counter-branch left + downward zigzag
  { d: "M 96 58 L 84 64 L 78 76 L 68 84 M 78 76 L 82 92" },
  // 4: spider — pronounced branching across the upper half
  { d: "M 98 86 L 110 96 L 116 110 M 110 96 L 124 102 M 98 86 L 88 98 L 78 108" },
  // 5: a wide fracture sweeping across mid-shell
  { d: "M 68 84 L 56 102 L 64 118 L 80 116 L 96 126 L 112 120 L 126 130 L 138 122 L 148 108" },
  // 6: side fracture opens — clear darker line
  { d: "M 138 122 L 142 142 L 134 158 M 142 142 L 152 138" },
  // 7: jagged scar down the left flank
  { d: "M 56 102 L 46 128 L 56 150 L 48 170" },
  // 8: meridian — shell almost cracked through, top to bottom
  { d: "M 96 30 L 92 50 L 100 70 L 92 92 L 102 116 L 92 142 L 100 168 L 92 190" },
  // 9: base fracture — the egg is groaning
  { d: "M 48 170 L 60 188 L 78 196 L 96 188 L 116 198 L 134 192 L 148 178 L 152 138" },
];

// ─── Micro-feedback strings shown over the egg at certain taps
function feedbackForTap(n, total) {
  // Final three taps escalate
  if (n === total - 2) return "crack…";
  if (n === total - 1) return "almost…";
  if (n === total)     return "one more…";
  return null;
}

// ─── Pre-generate shard end positions deterministically.
//     12 shards radiating outward with varied angles/distance.
function makeShards(n = 12) {
  const out = [];
  for (let i = 0; i < n; i++) {
    const angle = (-110 + (i / n) * 340) * (Math.PI / 180);
    const dist  = 110 + Math.random() * 140;
    const tx = Math.cos(angle) * dist;
    const ty = Math.sin(angle) * dist - 30; // bias upward slightly
    const r  = (Math.random() * 720 - 360) | 0;
    const d  = (Math.random() * 80) | 0;
    out.push({ tx, ty, r, d, i });
  }
  return out;
}
function makeSparkles(n = 14) {
  const out = [];
  for (let i = 0; i < n; i++) {
    const angle = Math.random() * Math.PI * 2;
    const dist  = 80 + Math.random() * 120;
    out.push({
      tx: Math.cos(angle) * dist,
      ty: Math.sin(angle) * dist,
      d:  (Math.random() * 200) | 0,
      size: 3 + Math.random() * 4,
    });
  }
  return out;
}

// ─── The egg SVG: stylized-premium, golden-hour rim light.
function EggSVG({ tapStage, hatched }) {
  // Reveal cracks 1..tapStage; on tapStage>=10, shell shatters visually (we fade it).
  const reveal = Math.min(tapStage, CRACK_PATHS.length);

  return (
    <svg
      className="egg-svg-shell"
      viewBox="0 0 200 260"
      xmlns="http://www.w3.org/2000/svg"
      aria-hidden="true"
      style={{ opacity: hatched ? 0 : 1, transition: "opacity 240ms ease" }}
    >
      <defs>
        {/* Soft cream egg base */}
        <radialGradient id="eggBase" cx="38%" cy="32%" r="78%">
          <stop offset="0%"   stopColor="#FBF1DC" />
          <stop offset="55%"  stopColor="#F0DFB6" />
          <stop offset="100%" stopColor="#D6B884" />
        </radialGradient>

        {/* Shadow side wash — painterly */}
        <linearGradient id="eggShadow" x1="0" y1="0" x2="1" y2="0.6">
          <stop offset="0%"   stopColor="rgba(0,0,0,0)" />
          <stop offset="60%"  stopColor="rgba(80, 50, 12, 0.0)" />
          <stop offset="100%" stopColor="rgba(80, 50, 12, 0.32)" />
        </linearGradient>

        {/* Bottom warm glow from the nest */}
        <radialGradient id="eggUnderglow" cx="50%" cy="98%" r="50%">
          <stop offset="0%"   stopColor="rgba(232, 130, 40, 0.55)" />
          <stop offset="60%"  stopColor="rgba(232, 130, 40, 0)" />
        </radialGradient>

        {/* Rim light on left */}
        <linearGradient id="eggRim" x1="0" y1="0" x2="1" y2="0">
          <stop offset="0%"   stopColor="rgba(255, 240, 200, 0.85)" />
          <stop offset="22%"  stopColor="rgba(255, 240, 200, 0)" />
        </linearGradient>

        {/* Specular highlight */}
        <radialGradient id="eggSpec" cx="50%" cy="50%" r="50%">
          <stop offset="0%"   stopColor="rgba(255, 250, 230, 0.85)" />
          <stop offset="70%"  stopColor="rgba(255, 250, 230, 0)" />
        </radialGradient>

        {/* Mask: clip everything to the egg silhouette */}
        <clipPath id="eggClip">
          <path d="M 100 14
                   C 138 14, 168 80,  168 150
                   C 168 210, 138 246, 100 246
                   C  62 246,  32 210,  32 150
                   C  32  80,  62  14, 100 14 Z" />
        </clipPath>
      </defs>

      {/* Egg silhouette + layers, all clipped to the egg path */}
      <g clipPath="url(#eggClip)">
        {/* Base */}
        <rect x="0" y="0" width="200" height="260" fill="url(#eggBase)" />
        {/* Shadow side */}
        <rect x="0" y="0" width="200" height="260" fill="url(#eggShadow)" />
        {/* Warm underglow from the nest */}
        <rect x="0" y="0" width="200" height="260" fill="url(#eggUnderglow)" />
        {/* Rim light */}
        <rect x="0" y="0" width="200" height="260" fill="url(#eggRim)" />

        {/* Subtle freckles — drawn as tiny low-opacity ellipses */}
        <g fill="rgba(120, 80, 30, 0.18)">
          <ellipse cx="78"  cy="80"  rx="1.4" ry="1.1" />
          <ellipse cx="92"  cy="120" rx="1.1" ry="0.9" />
          <ellipse cx="118" cy="140" rx="1.2" ry="1.0" />
          <ellipse cx="74"  cy="170" rx="1.4" ry="1.1" />
          <ellipse cx="112" cy="190" rx="1.1" ry="0.9" />
          <ellipse cx="62"  cy="130" rx="0.9" ry="0.7" />
          <ellipse cx="138" cy="100" rx="1.0" ry="0.8" />
          <ellipse cx="100" cy="60"  rx="0.9" ry="0.7" />
          <ellipse cx="130" cy="180" rx="1.1" ry="0.9" />
        </g>

        {/* Specular highlight */}
        <ellipse cx="74" cy="80" rx="18" ry="28" fill="url(#eggSpec)" />

        {/* CRACKS — drawn last so they sit on top, inside the silhouette.
            Stroke wider darker line + thinner inner line for depth. */}
        <g style={{ mixBlendMode: "multiply" }}>
          {CRACK_PATHS.slice(0, reveal).map((p, i) => (
            <g key={i} className={`crack crack--${i + 1}`}>
              {/* soft shadow halo for legibility */}
              <path
                d={p.d}
                fill="none"
                stroke="rgba(70, 38, 10, 0.5)"
                strokeWidth="3"
                strokeLinecap="round"
                strokeLinejoin="round"
                style={{ animation: `crack-draw 380ms ${i * 30}ms ease-out forwards` }}
              />
              {/* main dark crack line */}
              <path
                d={p.d}
                fill="none"
                stroke="rgba(38, 20, 6, 0.95)"
                strokeWidth="1.4"
                strokeLinecap="round"
                strokeLinejoin="round"
                style={{ animation: `crack-draw 380ms ${i * 30}ms ease-out forwards` }}
              />
            </g>
          ))}
        </g>

        {/* As we near hatching, slight gold leaking through cracks */}
        {tapStage >= 6 && (
          <g style={{ mixBlendMode: "screen", opacity: Math.min(1, (tapStage - 5) / 4) }}>
            {CRACK_PATHS.slice(0, reveal).map((p, i) => (
              <path
                key={`g${i}`}
                d={p.d}
                fill="none"
                stroke="rgba(255, 220, 130, 0.7)"
                strokeWidth="0.6"
                strokeLinecap="round"
              />
            ))}
          </g>
        )}
      </g>

      {/* Outline contour for definition */}
      <path
        d="M 100 14
           C 138 14, 168 80,  168 150
           C 168 210, 138 246, 100 246
           C  62 246,  32 210,  32 150
           C  32  80,  62  14, 100 14 Z"
        fill="none"
        stroke="rgba(80, 50, 12, 0.18)"
        strokeWidth="1"
      />

      {/* Inline keyframes for the draw effect */}
      <style>{`
        .crack path { stroke-dasharray: 240; stroke-dashoffset: 240; }
        @keyframes crack-draw {
          to { stroke-dashoffset: 0; }
        }
      `}</style>
    </svg>
  );
}

// ─── The nest — a woven golden basket beneath the egg.
function NestSVG() {
  return (
    <svg
      className="egg-nest"
      viewBox="0 0 320 120"
      xmlns="http://www.w3.org/2000/svg"
      aria-hidden="true"
    >
      <defs>
        <radialGradient id="nestBowl" cx="50%" cy="0%" r="80%">
          <stop offset="0%"  stopColor="#7A4A14" />
          <stop offset="60%" stopColor="#4A2C0A" />
          <stop offset="100%" stopColor="#2F1B05" />
        </radialGradient>
        <linearGradient id="strand" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%"  stopColor="#E5C57A" />
          <stop offset="50%" stopColor="#C8A24A" />
          <stop offset="100%" stopColor="#7A5A20" />
        </linearGradient>
      </defs>

      {/* The bowl interior (egg sits in here) */}
      <ellipse cx="160" cy="14" rx="84" ry="20" fill="url(#nestBowl)" />

      {/* Outer nest body — woven strands */}
      <g stroke="url(#strand)" strokeWidth="2" strokeLinecap="round" fill="none">
        {Array.from({ length: 26 }).map((_, i) => {
          const startX = 30 + i * 10;
          const endX   = startX + 24 + (i % 4) * 6;
          const startY = 18 + (i % 3) * 4;
          const endY   = 80 + (i % 4) * 10;
          const ctrlX  = (startX + endX) / 2 + (i % 2 ? 6 : -6);
          const ctrlY  = (startY + endY) / 2 + 6;
          return (
            <path
              key={i}
              d={`M ${startX} ${startY} Q ${ctrlX} ${ctrlY} ${endX} ${endY}`}
              opacity={0.45 + (i % 3) * 0.15}
            />
          );
        })}
        {/* Cross-weaving */}
        {Array.from({ length: 20 }).map((_, i) => {
          const y = 30 + i * 4;
          const x1 = 36 + (i % 3) * 4;
          const x2 = 284 - (i % 3) * 4;
          return (
            <path
              key={`x${i}`}
              d={`M ${x1} ${y} Q 160 ${y + 6} ${x2} ${y}`}
              opacity={0.35 + (i % 2) * 0.2}
              strokeWidth={1 + (i % 2) * 0.5}
            />
          );
        })}
      </g>

      {/* Bottom shadow */}
      <ellipse cx="160" cy="100" rx="120" ry="12"
        fill="rgba(60, 30, 6, 0.4)" filter="blur(4px)" />
    </svg>
  );
}

// ─── The coupon card — multi-step unfold reveal
function CouponCard({ brandName, headline, body, percent, ctaLabel, onCta, visible }) {
  return (
    <div className="coupon-stage" aria-hidden={!visible} style={{ pointerEvents: visible ? "auto" : "none" }}>
      <div className={`coupon-card ${visible ? "s-rise" : ""}`}>
        <div className="coupon-inner">
          <div className={`coupon-flap ${visible ? "s-open" : ""}`}>
            <div className="coupon-eyebrow">{brandName} · A token</div>
            <h3 className="coupon-headline">{headline}</h3>
          </div>

          <div className={`coupon-offer ${visible ? "s-in" : ""}`}>
            <div className="coupon-percent">
              {percent}<span className="sup">% off</span>
            </div>
            <p className="coupon-body">{body}</p>
          </div>

          <button
            className={`coupon-cta ${visible ? "s-in" : ""}`}
            onClick={onCta}
          >
            {ctaLabel}
            <span className="coupon-cta__arrow" />
          </button>

          <div className={`wax-seal ${visible ? "s-stamp" : ""}`} aria-hidden="true">
            Y&amp;G
          </div>
        </div>
      </div>
    </div>
  );
}

// ─── The main reusable egg component
function CrackableEgg({
  brandName = "Yolk & Gold",
  couponHeadline = "You cracked it.",
  couponBody = "10% off your table — just show us this when you sit down.",
  percentOff = 10,
  ctaLabel = "Reserve a table",
  tapCount = 10,
  hintAfterMs = 8000,
  onHatch,
  onReserve,
}) {
  const [taps, setTaps]         = useState(0);
  const [hatched, setHatched]   = useState(false);
  const [showHint, setShowHint] = useState(false);
  const [tapping, setTapping]   = useState(false);
  const [showCoupon, setShowCoupon] = useState(false);
  const [showReopen, setShowReopen] = useState(false);
  const [flash, setFlash]       = useState(null); // {text, key}
  const [shards, setShards]     = useState(null); // [{tx,ty,r,d}]
  const [sparkles, setSparkles] = useState(null);
  const [hatchFlash, setHatchFlash] = useState(false);

  const buttonRef    = useRef(null);
  const lastTapAt    = useRef(0);
  const hintTimer    = useRef(null);
  const tapClassTimer = useRef(null);
  const flashKey     = useRef(0);

  // Hint timer — show after N ms of idle (no taps)
  useEffect(() => {
    if (hatched) return;
    clearTimeout(hintTimer.current);
    hintTimer.current = setTimeout(() => {
      if (Date.now() - lastTapAt.current >= hintAfterMs - 100) {
        setShowHint(true);
      }
    }, hintAfterMs);
    return () => clearTimeout(hintTimer.current);
  }, [taps, hatched, hintAfterMs]);

  const handleTap = useCallback((e) => {
    if (hatched) return;
    e.preventDefault();
    lastTapAt.current = Date.now();
    setShowHint(false);

    // per-tap spring class
    setTapping(false);
    requestAnimationFrame(() => {
      setTapping(true);
      clearTimeout(tapClassTimer.current);
      tapClassTimer.current = setTimeout(() => setTapping(false), 380);
    });

    const next = taps + 1;
    setTaps(next);

    // micro-feedback for the final escalating moments
    const txt = feedbackForTap(next, tapCount);
    if (txt) {
      flashKey.current += 1;
      setFlash({ text: txt, key: flashKey.current });
      setTimeout(() => setFlash(null), 1100);
    }

    // HATCH
    if (next >= tapCount) {
      setTimeout(() => triggerHatch(), 120);
    }
  }, [taps, hatched, tapCount]);

  const triggerHatch = useCallback(() => {
    setHatched(true);
    setShards(makeShards(12));
    setSparkles(makeSparkles(14));
    setHatchFlash(true);
    // Reveal the coupon after the burst peak
    setTimeout(() => setShowCoupon(true), 380);
    setTimeout(() => setShowReopen(true), 2400);
    setTimeout(() => setHatchFlash(false), 1000);
    onHatch?.();
  }, [onHatch]);

  const closeCoupon = useCallback(() => {
    setShowCoupon(false);
  }, []);
  const reopenCoupon = useCallback(() => {
    setShowCoupon(true);
  }, []);

  const isFragile = taps >= Math.max(6, tapCount - 3) && !hatched;

  return (
    <div className="egg-stage">
      <div className="egg-floor" aria-hidden="true" />
      <NestSVG />

      {!hatched && (
        <button
          ref={buttonRef}
          className={[
            "egg-button",
            tapping ? "is-tapping" : "",
            isFragile ? "is-fragile" : "",
          ].join(" ")}
          onPointerDown={handleTap}
          aria-label={`Tap to crack the egg. ${tapCount - taps} taps left.`}
        >
          <EggSVG tapStage={taps} hatched={false} />
        </button>
      )}

      {/* Floating micro-feedback */}
      {flash && (
        <div key={flash.key} className="egg-flash">{flash.text}</div>
      )}

      {/* "psst — give the egg a tap" hint */}
      {!hatched && (
        <div className={`egg-hint ${showHint ? "is-visible" : ""}`}>
          psst — give the egg a tap
        </div>
      )}

      {/* Hatch burst layers */}
      <div className={`hatch-flash ${hatchFlash ? "is-on" : ""}`} aria-hidden="true" />
      {shards && (
        <div className="shards" aria-hidden="true">
          {shards.map((s) => (
            <span
              key={`s${s.i}`}
              className="shard"
              style={{
                "--tx": `${s.tx}px`,
                "--ty": `${s.ty}px`,
                "--r":  `${s.r}deg`,
                "--d":  `${s.d}ms`,
              }}
            />
          ))}
          {sparkles && sparkles.map((p, i) => (
            <span
              key={`p${i}`}
              className="sparkle"
              style={{
                "--tx": `${p.tx}px`,
                "--ty": `${p.ty}px`,
                "--d":  `${p.d}ms`,
                width: `${p.size}px`, height: `${p.size}px`,
              }}
            />
          ))}
        </div>
      )}

      {/* Coupon — sits on top once hatched */}
      {hatched && (
        <CouponCard
          brandName={brandName}
          headline={couponHeadline}
          body={couponBody}
          percent={percentOff}
          ctaLabel={ctaLabel}
          visible={showCoupon}
          onCta={() => onReserve?.()}
        />
      )}

      {/* Gentle re-open pill — sits beneath the egg stage area, visible only after hatched */}
      {hatched && (
        <button
          className={`coupon-reopen ${showReopen ? "s-show" : ""}`}
          onClick={showCoupon ? closeCoupon : reopenCoupon}
          style={{ position: "absolute", bottom: "-10px", left: "50%", transform: "translateX(-50%)" }}
        >
          {showCoupon ? "hide coupon" : "show coupon again"}
        </button>
      )}
    </div>
  );
}

// Export to window for app.jsx
Object.assign(window, { CrackableEgg });
