/* SOURCING SCROLL - COMBO v2 (full-glass, bold text behind, solid finish).
   Story: gazillions of golden pixels = "Your TAM Universe" → collapse into a
   dense shape → the whole viewport is frosted GLASS with big bold steps behind
   it (MATCH · DEDUPE · SUPPRESS · FILTER) → glass clears → a SOLID shape with
   "12,486" inside = Total Clean Serviceable Available Market.
   Variations: shape circle|square · palette gold|white|multi.
   Depends on window.SS2. Exposes window.SS2_COMBO. */
const { clamp2: K, lerp2: LL, span2: SS, eio2: EE, TAU2: TT, GOLD: GG, STORY: STY, ScrollStage: CStage, buildPixels: CBP } = window.SS2;
const { useMemo: uMemo } = React;

const CATS = ["Industry-specific data", "Custom scrapers", "Open-source intel", "LinkedIn & Maps"];
const STEPS = STY.layers;
const MULTI = [[216, 162, 70], [206, 110, 80], [96, 158, 134], [122, 150, 188]];
const GLITCH = [[224, 55, 158], [55, 214, 214], [82, 201, 100], [200, 54, 74], [91, 110, 224], [155, 87, 200]];
const PAPER = [236, 234, 227], INK = [12, 10, 7];
const mix3 = (a, b, t) => [(a[0] + (b[0] - a[0]) * t) | 0, (a[1] + (b[1] - a[1]) * t) | 0, (a[2] + (b[2] - a[2]) * t) | 0];
const cfmt = (n) => Math.round(n).toLocaleString();

function rrect(ctx, x, y, w, h, r) { ctx.beginPath(); ctx.moveTo(x + r, y); ctx.arcTo(x + w, y, x + w, y + h, r); ctx.arcTo(x + w, y + h, x, y + h, r); ctx.arcTo(x, y + h, x, y, r); ctx.arcTo(x, y, x + w, y, r); ctx.closePath(); }

function ComboUniverse({ shape, palette, field = "stars", catsLayout = "corners", heroFont = "anton", endStyle = "white", endFont = "disp" }) {
  const isSq = shape === "square";
  const isGlitch = field === "glitch";
  const px = uMemo(() => {
    const a = CBP(isGlitch ? 6000 : 3000, 31), g = 24, rng = window.SS2.mul2(77);
    for (const pt of a) {
      if (isGlitch) { pt.hx = Math.round(pt.hx * 88) / 88; pt.hy = Math.round(pt.hy * 52) / 52; const r = rng(); if (r < 0.075) pt.gc = GLITCH[(rng() * GLITCH.length) | 0]; else { pt.gc = null; pt.dark = r < 0.62; } }
      pt.qx = Math.round((pt.hx * 2 - 1) * g) / g; pt.qy = Math.round((pt.hy * 2 - 1) * g) / g;
    }
    return a;
  }, []);
  const numColor = endStyle === "dark" ? "#F4F0EA" : endStyle === "mix" ? "#FFFFFF" : "#16130D";
  const labelColor = endStyle === "dark" ? "rgba(244,240,234,0.62)" : endStyle === "mix" ? "rgba(255,255,255,0.85)" : "rgba(22,19,13,0.6)";
  const END_FONT = { archivo: "'Archivo Black',sans-serif", syne: "'Syne',sans-serif", anton: "'Anton',sans-serif", disp: "var(--ss2-disp)" };

  const colorFor = (pt, b, a) => {
    if (palette === "white") { const v = 0.55 + b * 0.45; return `rgba(${(224 * v + 20) | 0},${(222 * v + 20) | 0},${(212 * v + 18) | 0},${a})`; }
    if (palette === "multi") { const c = MULTI[pt.lane], v = 0.5 + b * 0.5; return `rgba(${(c[0] * v) | 0},${(c[1] * v) | 0},${(c[2] * v) | 0},${a})`; }
    return GG.ramp(b, a);
  };
  // the clean TAM solid - colour-mixed / bordered / dark-accent / white, near-sharp corners
  const CARD4 = ["#E0379E", "#37D6D6", "#52C964", "#6E7BE6"];
  const solidPaint = (ctx, cx, cy, R, alpha) => {
    ctx.globalAlpha = alpha;
    const rad = R * 0.06;
    const box = () => rrect(ctx, cx - R, cy - R, R * 2, R * 2, rad);
    const grad4 = () => { const lg = ctx.createLinearGradient(cx - R, cy - R, cx + R, cy + R); lg.addColorStop(0, CARD4[0]); lg.addColorStop(0.34, CARD4[1]); lg.addColorStop(0.67, CARD4[2]); lg.addColorStop(1, CARD4[3]); return lg; };
    if (endStyle === "mix") { ctx.fillStyle = grad4(); box(); ctx.fill(); }
    else if (endStyle === "border") {
      ctx.fillStyle = "#F6F4EF"; box(); ctx.fill();
      ctx.lineWidth = Math.max(5, R * 0.085); ctx.strokeStyle = grad4(); box(); ctx.stroke();
    } else if (endStyle === "dark") {
      ctx.fillStyle = "#0E0D11"; box(); ctx.fill();
      ctx.lineWidth = 1.5; ctx.strokeStyle = "rgba(255,255,255,0.12)"; box(); ctx.stroke();
      const s = R * 0.17;
      [[cx - R, cy - R, 0], [cx + R - s, cy - R, 1], [cx - R, cy + R - s, 2], [cx + R - s, cy + R - s, 3]].forEach(([ax, ay, i]) => { ctx.fillStyle = CARD4[i]; ctx.fillRect(ax, ay, s, s); });
    } else {
      const grad = ctx.createRadialGradient(cx - R * 0.32, cy - R * 0.36, R * 0.12, cx, cy, R);
      grad.addColorStop(0, "#FCFBF8"); grad.addColorStop(0.62, "#EAE7DF"); grad.addColorStop(1, "#CFCBC2");
      ctx.fillStyle = grad;
      if (isSq) { rrect(ctx, cx - R, cy - R, R * 2, R * 2, R * 0.26); ctx.fill(); }
      else { ctx.beginPath(); ctx.arc(cx, cy, R, 0, TT); ctx.fill(); }
    }
    ctx.globalAlpha = 1;
  };

  const draw = (ctx, p, t, W, H) => {
    const darkenF = isGlitch ? EE(SS(p, 0.05, 0.30)) : 1;
    if (isGlitch) {
      const bg = mix3(PAPER, INK, darkenF);
      ctx.fillStyle = `rgb(${bg[0]},${bg[1]},${bg[2]})`; ctx.fillRect(0, 0, W, H);
      const ga = (1 - darkenF) * 0.4;
      if (ga > 0.01) { ctx.strokeStyle = `rgba(120,118,112,${ga})`; ctx.lineWidth = 1; const stp = Math.max(12, Math.round(W / 88)); ctx.beginPath(); for (let x = 0; x <= W; x += stp) { ctx.moveTo(x + 0.5, 0); ctx.lineTo(x + 0.5, H); } for (let y = 0; y <= H; y += stp) { ctx.moveTo(0, y + 0.5); ctx.lineTo(W, y + 0.5); } ctx.stroke(); }
    } else { ctx.fillStyle = GG.ink; ctx.fillRect(0, 0, W, H); }
    const cx = W * 0.5, cy = H * 0.52, mn = Math.min(W, H);
    const Rbig = mn * (isSq ? 0.27 : 0.30), Rsolid = mn * (isSq ? 0.18 : 0.155);
    const collapse = EE(SS(p, 0.12, 0.32));
    const tighten = SS(p, 0.36, 0.84);
    const land = EE(SS(p, 0.86, 1.0));
    const Rcur = LL(Rbig, Rsolid * 1.06, EE(tighten));
    let dens = 1; if (p > 0.36) { const s = K(Math.floor(SS(p, 0.36, 0.84) * 4), 0, 3); dens = [0.70, 0.52, 0.40, 0.20][s]; }

    // soft glow
    const gA = collapse * (0.10 + land * 0.45) * (isGlitch ? darkenF : 1);
    if (gA > 0.01) { const gg = ctx.createRadialGradient(cx, cy, 4, cx, cy, Rcur * 2.4); const gc = (palette === "white" || isGlitch) ? "230,228,220" : palette === "multi" ? "200,150,90" : "196,150,52"; gg.addColorStop(0, `rgba(${gc},${0.4 * gA})`); gg.addColorStop(1, `rgba(${gc},0)`); ctx.fillStyle = gg; ctx.beginPath(); ctx.arc(cx, cy, Rcur * 2.4, 0, TT); ctx.fill(); }

    // solid shape grows at the end (white, ~88% opaque)
    if (land > 0.01) solidPaint(ctx, cx, cy, LL(Rsolid * 1.05, Rsolid, land), land * (endStyle === "white" ? 0.88 : 0.96));

    const gcell = Math.max(6, mn / 62);
    // gentle, STILL light spots for the glitch field (no movement, slow shimmer)
    const fieldLight = isGlitch ? (1 - collapse) : 0;
    let centers = null, R2 = 1;
    if (fieldLight > 0.01) {
      const R = mn * 0.19; R2 = R * R;
      centers = [[0.22, 0.30], [0.74, 0.24], [0.50, 0.52], [0.20, 0.74], [0.82, 0.70], [0.60, 0.84]].map((c) => [c[0] * W, c[1] * H]);
    }
    for (let k = 0; k < px.length; k++) {
      const pt = px[k];
      const dx = Math.sin(t * 0.5 + pt.tw) * 5, dy = Math.cos(t * 0.4 + pt.tw) * 5;
      let x = pt.hx * W + (isGlitch ? 0 : dx);
      let y = pt.hy * H + (isGlitch ? 0 : dy);
      let ux, uy;
      if (isSq) { ux = cx + pt.qx * Rcur; uy = cy + pt.qy * Rcur; }
      else { ux = cx + Math.cos(pt.ang) * Rcur * pt.rr; uy = cy + Math.sin(pt.ang) * Rcur * pt.rr; }
      x = LL(x, ux, collapse); y = LL(y, uy, collapse);
      const lx = cx + (isSq ? pt.qx : Math.cos(pt.ang) * pt.rr) * Rsolid * 0.85;
      const ly = cy + (isSq ? pt.qy : Math.sin(pt.ang) * pt.rr) * Rsolid * 0.85;
      x = LL(x, lx, land); y = LL(y, ly, land);

      // per-cell light-up / grey-out factor (slow, no positional movement)
      let litF = 1;
      if (centers) {
        const tw2 = Math.sin(t * 0.55 + pt.tw * 6.3);
        const litT = tw2 > 0.55 ? (tw2 - 0.55) / 0.45 : 0, greyT = tw2 < -0.6 ? 1 : 0;
        let near = 0;
        for (let ci = 0; ci < 6; ci++) { const ddx = x - centers[ci][0], ddy = y - centers[ci][1]; const v = 1 - (ddx * ddx + ddy * ddy) / R2; if (v > near) near = v; }
        if (near < 0) near = 0;
        let f = 0.55 + litT * 0.4 + near * 0.45 - greyT * 0.38;
        litF = LL(f < 0 ? 0 : f > 1 ? 1 : f, 1, collapse);
      }

      let a;
      if (isGlitch) a = 0.95 * (0.16 + 0.84 * litF);
      else if (p < 0.10) { const tw = 0.5 + 0.5 * Math.sin(t * 1.8 + pt.tw); a = 0.45 + 0.5 * tw; }
      else a = 0.9;
      if (p > 0.36) a *= K((dens - pt.rank) / 0.05 + 0.5);
      a *= (1 - land);
      if (a <= 0.02) continue;
      let fill;
      if (isGlitch) {
        if (pt.gc) fill = `rgba(${pt.gc[0]},${pt.gc[1]},${pt.gc[2]},${a})`;
        else { const c = mix3(pt.dark ? [22, 24, 27] : [240, 238, 232], pt.dark ? [148, 146, 140] : [232, 229, 221], darkenF); fill = `rgba(${c[0]},${c[1]},${c[2]},${a})`; }
      } else fill = colorFor(pt, 0.55 + pt.gold * 0.45, a);
      const sz = isGlitch ? LL(gcell, 3.4, collapse) * (0.82 + 0.32 * litF) : (isSq ? (2.0 + pt.gold * 1.4) : (1.7 + pt.gold * 1.6));
      ctx.fillStyle = fill;
      ctx.fillRect(x - sz / 2, y - sz / 2, sz, sz);
    }
  };

  return (
    <CStage vh={540} draw={draw}>
      {(p) => {
        const introA = 1 - SS(p, 0.07, 0.13);
        const conv = EE(SS(p, 0.06, 0.30));
        const catA = (1 - SS(p, 0.22, 0.30));
        const corners = [
          { c: CATS[0], cls: "tl", l: 17, t: 24 }, { c: CATS[1], cls: "tr", l: 83, t: 24 },
          { c: CATS[2], cls: "bl", l: 17, t: 76 }, { c: CATS[3], cls: "br", l: 83, t: 76 },
        ];
        const stepF = SS(p, 0.36, 0.84) * 4, sIdx = K(Math.floor(stepF), 0, 3), local = stepF - sIdx;
        const stepVis = (p > 0.34 && p < 0.86) ? Math.min(SS(local, 0, 0.16), 1) * (1 - SS(local, 0.84, 1)) : 0;
        const St = STEPS[sIdx];
        const finalTitleA = SS(p, 0.87, 0.95);
        const numA = SS(p, 0.91, 1.0);
        return (
          <React.Fragment>
            {/* intro */}
            {introA > 0.01 && (catsLayout === "list" ? (
              <div className="ss2-hero ss2-hero--center" style={{ opacity: introA }}>
                <div className="ss2-hero-kick"><span className="bar" />Sourcing &amp; TAM build</div>
                <div className={"ss2-hero-ttl ss2-ttl--" + heroFont}>YOUR TAM<br />UNIVERSE</div>
                <div className="ss2-hero-sub">{STY.raw} raw records · scroll to resolve ↓</div>
                <div className="ss2-hero-cards">
                  {[["Industry-specific", "Vertical & niche sources", 0], ["Custom scrapers", "Built in-house", 1], ["Open-source intel", "The public web", 2], ["LinkedIn & Maps", "Social + local", 3]].map(([t, d, i]) => (
                    <div key={t} className={"ss2-card c" + i}><b>{t}</b><span>{d}</span></div>
                  ))}
                </div>
              </div>
            ) : (
              <div className="ss2-intro" style={{ opacity: introA }}>
                <div className="ss2-bigtext">Your TAM<br />Universe</div>
                <div className="ss2-bigsub">{STY.raw} records</div>
              </div>
            ))}
            {/* four category labels in the corners, converging inward */}
            {catsLayout === "corners" && catA > 0.01 && corners.map((cc, i) => (
              <div key={i} className={"ss2-cat " + cc.cls} style={{ left: `${LL(cc.l, 50, conv * 0.82)}%`, top: `${LL(cc.t, 50, conv * 0.82)}%`, opacity: catA }}>
                <span className="tag">{String(i + 1).padStart(2, "0")} · Source</span>{cc.c}
              </div>
            ))}
            {/* big processing step - ghost behind + sharp + solid sub */}
            {stepVis > 0.01 && (
              <div className="ss2-step" style={{ opacity: stepVis }}>
                <div className="ss2-step-ghost">{St.name}</div>
                <div className="ss2-step-name">{St.name}</div>
                <div className="ss2-step-sub"><span className="plate">{St.sub}<span className="ct">{St.count}</span></span></div>
              </div>
            )}
            {/* final solid title + number-inside + caption below box */}
            <div className="ss2-final-title" style={{ opacity: finalTitleA }}>
              <div className="t" style={{ fontFamily: END_FONT[endFont] }}>Total Serviceable<br />Market</div>
            </div>
            <div className="ss2-solidnum" style={{ opacity: numA }}>
              <div className="n" style={{ color: numColor }}>{STY.tam}</div>
            </div>
            <div className="ss2-solidlabel" style={{ opacity: numA }}>Net new accounts · cleaned up</div>
            {p < 0.04 && <div className="ss2-cue"><span className="dot" />Scroll to resolve your market</div>}
          </React.Fragment>
        );
      }}
    </CStage>
  );
}

const ComboCircleGold = () => <ComboUniverse shape="circle" palette="gold" />;
const ComboSquareGold = () => <ComboUniverse shape="square" palette="gold" />;
const ComboSquareWhite = () => <ComboUniverse shape="square" palette="white" />;
const ComboSquareMulti = () => <ComboUniverse shape="square" palette="multi" />;
const ComboGlitch = () => <ComboUniverse shape="square" palette="white" field="glitch" catsLayout="list" heroFont="archivo" />;
const ComboGlitchB = () => <ComboUniverse shape="square" palette="white" field="glitch" catsLayout="list" heroFont="syne" />;
const ComboEndMix = () => <ComboUniverse shape="square" palette="white" field="glitch" catsLayout="list" heroFont="archivo" endStyle="mix" endFont="archivo" />;
const ComboEndBorder = () => <ComboUniverse shape="square" palette="white" field="glitch" catsLayout="list" heroFont="archivo" endStyle="border" endFont="syne" />;
const ComboEndDark = () => <ComboUniverse shape="square" palette="white" field="glitch" catsLayout="list" heroFont="archivo" endStyle="dark" endFont="archivo" />;

Object.assign(window, { SS2_COMBO: { ComboCircleGold, ComboSquareGold, ComboSquareWhite, ComboSquareMulti, ComboGlitch, ComboGlitchB, ComboEndMix, ComboEndBorder, ComboEndDark } });
