/* tulip.jsx — lifelike vector tulips + bouquet builder
   Layered tepals (back + front cup), gradient volume, sheen, crease, veins.
   Animation only ever changes group transforms via --grow / --open (60fps).
   Exposes refs so the rAF loop in app.jsx can scrub per frame. */

// a cupped tulip tepal: base at (0,0), tip up, widest mid, softly pointed top
const TEPAL = "M0,0 C -15,-9 -23,-42 -20,-84 C -18,-107 -8,-120 0,-123 C 8,-120 18,-107 20,-84 C 23,-42 15,-9 0,0 Z";
const LEAF_PATH = "M0,0 C -30,-30 -38,-112 -10,-168 C -3,-150 2,-150 1,-110 C 6,-60 4,-26 0,0 Z";

// layers: back peeking tepals (drawn first), then front cup (drawn last)
const BACK_PETALS  = [ { a0: -10, da: -9 }, { a0: 0, da: 0 }, { a0: 10, da: 9 } ];
const FRONT_PETALS = [ { a0: -4, da: -18, sheen: true, vein: true },
                       { a0:  4, da:  18, sheen: true, vein: true },
                       { a0:  0, da:   0, sheen: true, vein: true, center: true } ];

const CREASE = { rose: "rgba(70,12,38,0.34)", blush: "rgba(80,20,52,0.30)",
                 gold: "rgba(120,70,12,0.26)", cream: "rgba(150,110,40,0.22)",
                 red: "rgba(70,10,12,0.36)" };

function mulberry(seed) {
  return function () {
    let t = (seed += 0x6d2b79f5);
    t = Math.imul(t ^ (t >>> 15), t | 1);
    t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}

function FlowerDefs() {
  const grad = (id, c0, c1, c2, c3) => (
    <linearGradient id={id} x1="0.35" y1="0" x2="0.62" y2="1" key={id}>
      <stop offset="0" stopColor={c0} />
      <stop offset="0.36" stopColor={c1} />
      <stop offset="0.72" stopColor={c2} />
      <stop offset="1" stopColor={c3} />
    </linearGradient>
  );
  return (
    <defs>
      {grad("g-rose", "#f9aec5", "#ec5d86", "#c83567", "#8c1e45")}
      {grad("g-blush", "#fdd2e1", "#f28fb0", "#d9628f", "#ab3c69")}
      {grad("g-gold", "#fbe7a2", "#f1c455", "#d99e2d", "#a3661a")}
      {grad("g-cream", "#fffaf0", "#fbeac6", "#eed399", "#cba85f")}
      {grad("g-red", "#f4796a", "#dd3a33", "#b21f22", "#771215")}
      <linearGradient id="g-stem" x1="0.2" y1="0" x2="0.8" y2="1">
        <stop offset="0" stopColor="#8aa766" />
        <stop offset="0.55" stopColor="#5f7c43" />
        <stop offset="1" stopColor="#3d5530" />
      </linearGradient>
      <linearGradient id="g-leaf" x1="0" y1="0.2" x2="1" y2="0.8">
        <stop offset="0" stopColor="#9cb673" />
        <stop offset="0.5" stopColor="#688a47" />
        <stop offset="1" stopColor="#42602f" />
      </linearGradient>
      <radialGradient id="g-sheen" cx="0.5" cy="0.32" r="0.55">
        <stop offset="0" stopColor="rgba(255,255,255,0.62)" />
        <stop offset="0.6" stopColor="rgba(255,255,255,0.12)" />
        <stop offset="1" stopColor="rgba(255,255,255,0)" />
      </radialGradient>
      <radialGradient id="g-throat" cx="0.5" cy="0.4" r="0.6">
        <stop offset="0" stopColor="rgba(40,6,20,0.7)" />
        <stop offset="1" stopColor="rgba(40,6,20,0)" />
      </radialGradient>
      <linearGradient id="g-paper" x1="0.3" y1="0" x2="0.7" y2="1">
        <stop offset="0" stopColor="#ecc4d0" />
        <stop offset="0.5" stopColor="#c98aa0" />
        <stop offset="1" stopColor="#824f66" />
      </linearGradient>
      <linearGradient id="g-paper-back" x1="0.3" y1="0" x2="0.7" y2="1">
        <stop offset="0" stopColor="#c89aa9" />
        <stop offset="0.5" stopColor="#9c6379" />
        <stop offset="1" stopColor="#583a4b" />
      </linearGradient>
      <linearGradient id="g-bow" x1="0" y1="0" x2="0.4" y2="1">
        <stop offset="0" stopColor="#f7df96" />
        <stop offset="0.5" stopColor="#e3bb55" />
        <stop offset="1" stopColor="#b1842a" />
      </linearGradient>
    </defs>
  );
}

// ---- florist wrap: tissue cone behind + folded cuff & satin bow in front ----
const CINCH_X = 280, CINCH_Y = 806;
function fanPath(spread, topY) {
  const cx = CINCH_X, cy = CINCH_Y;
  return `M${cx},${cy} `
    + `C ${cx - spread * 0.45},${cy - (cy - topY) * 0.5} ${cx - spread * 0.85},${topY + 44} ${cx - spread},${topY} `
    + `C ${cx - spread * 0.4},${topY + 20} ${cx + spread * 0.4},${topY + 20} ${cx + spread},${topY} `
    + `C ${cx + spread * 0.85},${topY + 44} ${cx + spread * 0.45},${cy - (cy - topY) * 0.5} ${cx},${cy} Z`;
}

function WrapBack() {
  return (
    <g className="wrap-grow">
      <g transform={`rotate(-7 ${CINCH_X} ${CINCH_Y})`}>
        <path d={fanPath(178, 560)} fill="url(#g-paper-back)" opacity="0.92" />
      </g>
      <g transform={`rotate(7 ${CINCH_X} ${CINCH_Y})`}>
        <path d={fanPath(178, 560)} fill="url(#g-paper-back)" opacity="0.92" />
      </g>
      <path d={fanPath(138, 596)} fill="url(#g-paper)" opacity="0.96" />
      {/* fold creases */}
      <g stroke="rgba(70,30,46,0.28)" strokeWidth="1.4" fill="none" strokeLinecap="round">
        <path d={`M${CINCH_X},${CINCH_Y} C 250,720 230,650 196,576`} />
        <path d={`M${CINCH_X},${CINCH_Y} C 280,710 282,650 280,600`} />
        <path d={`M${CINCH_X},${CINCH_Y} C 310,720 330,650 364,576`} />
      </g>
      <g stroke="rgba(255,225,235,0.22)" strokeWidth="1" fill="none" strokeLinecap="round">
        <path d={`M${CINCH_X},${CINCH_Y} C 264,716 252,652 224,584`} />
        <path d={`M${CINCH_X},${CINCH_Y} C 296,716 312,652 338,584`} />
      </g>
    </g>
  );
}

function Bow() {
  const x = CINCH_X, y = 742;
  return (
    <g>
      {/* tails */}
      <path d={`M${x - 6},${y + 6} C ${x - 22},${y + 40} ${x - 30},${y + 70} ${x - 40},${y + 96} L ${x - 22},${y + 92} L ${x - 12},${y + 64} Z`}
            fill="url(#g-bow)" opacity="0.95" />
      <path d={`M${x + 6},${y + 6} C ${x + 22},${y + 42} ${x + 30},${y + 72} ${x + 42},${y + 98} L ${x + 22},${y + 94} L ${x + 12},${y + 66} Z`}
            fill="url(#g-bow)" opacity="0.95" />
      {/* loops */}
      <path d={`M${x},${y + 4} C ${x - 30},${y - 30} ${x - 70},${y - 22} ${x - 60},${y + 8} C ${x - 54},${y + 26} ${x - 24},${y + 18} ${x},${y + 8} Z`}
            fill="url(#g-bow)" />
      <path d={`M${x},${y + 4} C ${x + 30},${y - 30} ${x + 70},${y - 22} ${x + 60},${y + 8} C ${x + 54},${y + 26} ${x + 24},${y + 18} ${x},${y + 8} Z`}
            fill="url(#g-bow)" />
      {/* loop shading */}
      <path d={`M${x},${y + 5} C ${x - 24},${y - 14} ${x - 48},${y - 12} ${x - 50},${y + 4}`}
            fill="none" stroke="rgba(120,86,18,0.4)" strokeWidth="1.4" />
      <path d={`M${x},${y + 5} C ${x + 24},${y - 14} ${x + 48},${y - 12} ${x + 50},${y + 4}`}
            fill="none" stroke="rgba(120,86,18,0.4)" strokeWidth="1.4" />
      {/* knot */}
      <path d={`M${x - 11},${y - 8} C ${x - 13},${y + 14} ${x + 13},${y + 14} ${x + 11},${y - 8} C ${x + 7},${y - 16} ${x - 7},${y - 16} ${x - 11},${y - 8} Z`}
            fill="url(#g-bow)" />
      <ellipse cx={x} cy={y + 1} rx="6" ry="9" fill="rgba(255,240,200,0.35)" />
    </g>
  );
}

function WrapFront() {
  const x = CINCH_X;
  return (
    <g className="wrap-grow">
      {/* folded cuff in front of the stems, narrowing to a point */}
      <path d={`M${x - 70},740 C ${x - 40},724 ${x + 40},724 ${x + 70},740 C ${x + 78},744 ${x + 78},744 ${x + 70},756 L ${x + 1},872 L ${x - 70},756 C ${x - 78},744 ${x - 78},744 ${x - 70},740 Z`}
            fill="url(#g-paper)" />
      {/* cuff fold lines */}
      <g stroke="rgba(70,30,46,0.3)" strokeWidth="1.4" fill="none" strokeLinecap="round">
        <path d={`M${x - 44},744 L ${x - 8},864`} />
        <path d={`M${x},740 L ${x},872`} />
        <path d={`M${x + 44},744 L ${x + 8},864`} />
      </g>
      <g stroke="rgba(255,225,235,0.25)" strokeWidth="1" fill="none" strokeLinecap="round">
        <path d={`M${x - 22},742 L ${x - 4},866`} />
        <path d={`M${x + 22},742 L ${x + 4},866`} />
      </g>
      {/* top folded-over highlight edge */}
      <path d={`M${x - 70},740 C ${x - 40},724 ${x + 40},724 ${x + 70},740`}
            fill="none" stroke="rgba(255,232,240,0.5)" strokeWidth="2.4" strokeLinecap="round" />
      <Bow />
    </g>
  );
}

function Petal({ p, variety }) {
  const crease = CREASE[variety] || CREASE.rose;
  return (
    <g className="petal" style={{ "--a0": `${p.a0}deg`, "--da": `${p.da}deg`,
                                  "--sx": `${p.sx}px`, "--sy": `${p.sy}px` }}>
      <path d={TEPAL} fill={`url(#g-${variety})`} stroke="rgba(255,255,255,0.10)" strokeWidth="0.6" />
      {/* center crease shadow */}
      <path d={TEPAL} fill={crease} opacity="0.85"
            style={{ transformBox: "fill-box", transformOrigin: "50% 100%", transform: "scaleX(0.3)" }} />
      {p.vein && (
        <g fill="none" stroke="rgba(90,20,46,0.16)" strokeWidth="0.8" strokeLinecap="round">
          <path d="M0,-6 C -6,-44 -8,-82 -4,-112" />
          <path d="M0,-6 C 6,-44 8,-82 4,-112" />
          <path d="M0,-6 C 0,-50 0,-90 0,-116" stroke="rgba(255,255,255,0.06)" />
        </g>
      )}
      {p.sheen && (
        <path d={TEPAL} fill="url(#g-sheen)" opacity="0.7"
              style={{ transformBox: "fill-box", transformOrigin: "50% 50%",
                       transform: "scale(0.62,0.74) translateY(-10px)" }} />
      )}
    </g>
  );
}

function Flower({ variety, scale, rand }) {
  const mk = (defs) => defs.map((d) => ({
    ...d,
    sx: (rand() * 2 - 1) * 96,
    sy: (rand() * 2 - 1) * 64 - 26,
  }));
  const back = mk(BACK_PETALS);
  const front = mk(FRONT_PETALS);
  return (
    <g style={{ transform: `scale(${scale})`, transformBox: "fill-box", transformOrigin: "50% 100%" }}>
      <g className="petals">
        {back.map((p, i) => <Petal key={"b" + i} p={p} variety={variety} />)}
        <ellipse cx="0" cy="-12" rx="17" ry="26" fill="url(#g-throat)" />
        {front.map((p, i) => <Petal key={"f" + i} p={p} variety={variety} />)}
      </g>
    </g>
  );
}

function Tulip({ cfg, registerRef }) {
  const growRef = React.useRef(null);
  const swayRef = React.useRef(null);
  React.useEffect(() => {
    const petalsEl = swayRef.current ? swayRef.current.querySelector(".petals") : null;
    registerRef({ growEl: growRef.current, petalsEl, cfg });
  }, []);
  const L = cfg.len;
  return (
    <g transform={`translate(${cfg.bx},${cfg.baseY}) rotate(${cfg.angle})`} opacity={cfg.dim}>
      <g ref={growRef} className="tulip-grow">
        <g className="tulip-sway" ref={swayRef}
           style={{ "--sway-amp": `${cfg.swayAmp}deg`, "--sway-dur": `${cfg.swayDur}s`, "--sway-delay": `${cfg.swayDelay}s` }}>
          {/* stem with curve + highlight */}
          <path d={`M0,0 C ${cfg.bend},${-L * 0.34} ${-cfg.bend * 0.6},${-L * 0.72} 0,${-L}`}
                fill="none" stroke="url(#g-stem)" strokeWidth={cfg.stemW} strokeLinecap="round" />
          <path d={`M0,0 C ${cfg.bend},${-L * 0.34} ${-cfg.bend * 0.6},${-L * 0.72} 0,${-L}`}
                fill="none" stroke="rgba(255,255,255,0.12)" strokeWidth={cfg.stemW * 0.3}
                strokeLinecap="round" transform="translate(-1.4,0)" />
          {/* leaves */}
          <g transform={`translate(0,${-L * 0.36})`}>
            <g transform={`rotate(-12) scale(${cfg.leafScale})`}>
              <path d={LEAF_PATH} fill="url(#g-leaf)" />
              <path d="M-2,-6 C -14,-44 -18,-100 -8,-150" fill="none" stroke="rgba(30,50,20,0.3)" strokeWidth="1" />
            </g>
            <g transform={`scale(-1,1) rotate(-12) scale(${cfg.leafScale * 0.88})`}>
              <path d={LEAF_PATH} fill="url(#g-leaf)" />
              <path d="M-2,-6 C -14,-44 -18,-100 -8,-150" fill="none" stroke="rgba(30,50,20,0.3)" strokeWidth="1" />
            </g>
          </g>
          {/* flower head */}
          <g transform={`translate(0,${-L})`}>
            <Flower variety={cfg.variety} scale={cfg.headScale} rand={cfg.rand} />
          </g>
        </g>
      </g>
    </g>
  );
}

function buildConfigs(count, seed) {
  const rand = mulberry(seed || 7);
  const VARIETIES = ["rose", "blush", "gold", "rose", "cream", "blush", "gold", "rose", "blush"];
  const baseY = 818;
  const cx = 280;
  const cfgs = [];
  for (let i = 0; i < count; i++) {
    const frac = count > 1 ? i / (count - 1) : 0.5;
    const centerness = 1 - Math.abs(frac - 0.5) * 2;
    const depth = (i % 2 === 0) ? 1 : 0; // alternate front/back for fullness
    const angle = (frac - 0.5) * 58 + (rand() * 2 - 1) * 4;
    const len = 300 + centerness * 150 + (rand() * 2 - 1) * 24 - depth * 24;
    const bx = cx + (frac - 0.5) * 36 + (rand() * 2 - 1) * 5;
    const gStart = rand() * 0.34;
    cfgs.push({
      angle, len, bx, baseY, depth,
      dim: depth ? 0.82 : 1,
      bend: (rand() * 2 - 1) * 14,
      variety: VARIETIES[i % VARIETIES.length],
      headScale: (0.74 + centerness * 0.26) * (depth ? 0.9 : 1),
      stemW: 7 + centerness * 1.8,
      leafScale: 0.92 + centerness * 0.3,
      swayAmp: 0.9 + rand() * 1.0,
      swayDur: 4.4 + rand() * 2.6,
      swayDelay: -rand() * 3,
      gStart, gSpan: 0.5,
      oStart: gStart + 0.34, oSpan: 0.44,
      rand: mulberry((seed || 7) * 131 + i * 17),
    });
  }
  // draw back-depth tulips first so front ones overlap them
  cfgs.sort((a, b) => b.depth - a.depth);
  return cfgs;
}

function Bouquet({ count, seed, registerRef }) {
  const cfgs = React.useMemo(() => buildConfigs(count, seed), [count, seed]);
  return (
    <svg className="bouquet-svg" viewBox="0 0 560 880" preserveAspectRatio="xMidYMax meet">
      <FlowerDefs />
      <WrapBack />
      {cfgs.map((cfg, i) => (
        <Tulip key={i} cfg={cfg} registerRef={registerRef} />
      ))}
      <WrapFront />
    </svg>
  );
}

Object.assign(window, { Bouquet, FlowerDefs });
