// ─────────────────────────────────────────────────────────────
// POSTER CAROUSEL — Netflix-style, full-bleed, drag tátil 1:1
// Auto-scroll contínuo + momentum + arrasto direto pelo dedo
// ─────────────────────────────────────────────────────────────

const { useState: _useState, useEffect: _useEffect, useRef: _useRef, useMemo: _useMemo, useCallback: _useCallback } = React;

// AUTO-SCROLL constant (pixels per millisecond) — bem lento, ambiente
const AUTO_SPEED = 0.018;
const FRICTION = 0.93;
const VELOCITY_THRESHOLD = 0.02;
const DRAG_THRESHOLD = 8; // px — abaixo disso é clique, acima é arrasto

// ───────── PÔSTER UNITÁRIO ─────────
function PosterCard({ module, t, isCenter, onOpen, onBuy, onCode, unlocked, width, height }) {
  const isSoon = module.status === "soon";
  const isCombo = !!module.isCombo;
  const comboActive = isCombo && unlocked;            // combo com tudo liberado
  const locked = !isSoon && !unlocked;                // seção bloqueada

  // tonalidade sutil por módulo
  const TONES = {
    stone:    { wash: "rgba(180,170,150,0.06)", glow: "rgba(220,200,160,0.10)" },
    olive:    { wash: "rgba(140,160,120,0.06)", glow: "rgba(160,180,130,0.10)" },
    ink:      { wash: "rgba(120,130,160,0.05)", glow: "rgba(150,160,200,0.08)" },
    ash:      { wash: "rgba(180,180,180,0.04)", glow: "rgba(200,200,200,0.06)" },
    sage:     { wash: "rgba(150,170,140,0.06)", glow: "rgba(175,195,150,0.13)" },
    premium:  { wash: "rgba(220,190,130,0.12)", glow: "rgba(240,210,150,0.18)" },
  };
  const tone = TONES[module.accent] || TONES.stone;

  const accessPill = (() => {
    if (isSoon)  return { label: "Em breve" };
    if (module.free) return { label: "Grátis" };
    if (isCombo) return { label: comboActive ? "Ativo" : "Combo" };
    return { label: unlocked ? "Liberado" : "Bloqueado" };
  })();

  // Decide rótulo do botão principal
  const buttonLabel = isCombo ? (comboActive ? "Acesso ativo" : "Adquirir") :
                      module.free ? "Acessar grátis" :
                      unlocked ? "Acessar" :
                      "Comprar";

  const countLabelStyle = {
    fontFamily: TYPE.sans, fontSize: 10, color: t.ink3,
    letterSpacing: "0.14em", textTransform: "uppercase", fontWeight: 700,
    marginBottom: 6, whiteSpace: "nowrap",
  };
  const buttonBase = {
    fontFamily: TYPE.sans, fontSize: 12,
    letterSpacing: "0.12em", textTransform: "uppercase", fontWeight: 800,
    display: "flex", alignItems: "center", justifyContent: "center", gap: 8,
    width: "100%", padding: "16px 18px",
    borderRadius: 12, whiteSpace: "nowrap", boxSizing: "border-box",
  };

  return (
    <div
      data-poster
      style={{
        flexShrink: 0,
        width: `${width}px`,
        height: `${height}px`,
        marginRight: 14,
        position: "relative",
        borderRadius: 24,
        overflow: "hidden",
        background: `
          radial-gradient(at 20% 0%, ${tone.glow} 0%, transparent 50%),
          radial-gradient(at 100% 100%, ${tone.wash} 0%, transparent 60%),
          linear-gradient(180deg, ${t.bg1} 0%, ${t.bg0} 100%)
        `,
        border: `1px solid ${t.border}`,
        boxShadow: isCenter
          ? `0 30px 70px rgba(0,0,0,0.55), 0 0 0 1px ${t.borderStrong} inset`
          : `0 18px 40px rgba(0,0,0,0.4)`,
        transform: `scale(${isCenter ? 1 : 0.94})`,
        opacity: isCenter ? 1 : 0.62,
        transition: "transform 0.35s cubic-bezier(0.2, 0.8, 0.2, 1), opacity 0.35s ease, box-shadow 0.35s ease",
        cursor: isSoon ? "default" : "pointer",
        WebkitUserSelect: "none",
        userSelect: "none",
      }}
    >
      {/* textura de papel sutil */}
      <div style={{
        position: "absolute", inset: 0,
        backgroundImage: `repeating-linear-gradient(45deg, ${t.border} 0 1px, transparent 1px 14px)`,
        opacity: 0.18, pointerEvents: "none",
      }}></div>

      {/* faixa de luz sutil */}
      <div className="poster-shine" style={{
        position: "absolute", top: 0, left: "-30%", width: "60%", height: "100%",
        background: `linear-gradient(105deg, transparent 0%, ${tone.glow} 50%, transparent 100%)`,
        filter: "blur(40px)",
        pointerEvents: "none",
      }}></div>

      {/* moldura interior */}
      <div style={{
        position: "absolute", inset: 24,
        border: `1px solid ${t.border}`,
        borderRadius: 16,
        pointerEvents: "none",
        opacity: 0.4,
      }}></div>

      {/* ÁREA DE TOQUE — abre o módulo / lista. NÃO cobre a área dos botões. */}
      {!isSoon && (
        <button
          data-poster-open
          onClick={(e) => { e.stopPropagation(); onOpen?.(); }}
          aria-label={`Abrir ${module.name}`}
          style={{
            position: "absolute",
            top: 0, left: 0, right: 0,
            bottom: 110,
            background: "transparent",
            border: "none",
            cursor: "pointer",
            zIndex: 2,
          }}
        ></button>
      )}

      {/* CONTEÚDO */}
      <div style={{
        position: "absolute", inset: 0,
        display: "flex", flexDirection: "column",
        padding: "40px 32px 36px",
        pointerEvents: "none", // os filhos relevantes reativam
      }}>
        {/* TOP META */}
        <div style={{
          display: "flex", justifyContent: "space-between", alignItems: "flex-start",
          fontFamily: TYPE.sans, fontSize: 10.5, color: t.ink3,
          letterSpacing: "0.18em", textTransform: "uppercase", fontWeight: 700,
        }}>
          <div style={{ flex: 1, minWidth: 0, paddingRight: 10 }}>
            <div style={{ color: t.ink3 }}>{isCombo ? "Combo" : module.sub}</div>
          </div>
          {/* caixa de largura FIXA p/ o selo — mantém a quebra do texto à esquerda
              idêntica em qualquer estado (Bloqueado/Liberado/Grátis/etc) */}
          <div style={{ flexShrink: 0, width: 110, display: "flex", justifyContent: "flex-end" }}>
          <div style={{
            display: "inline-flex", alignItems: "center", gap: 5,
            padding: "5px 11px", borderRadius: 999,
            background: (unlocked || comboActive) ? t.accentMuted : "transparent",
            border: `1px solid ${(unlocked || comboActive) ? t.borderStrong : t.border}`,
            color: (unlocked || comboActive) ? t.ink1 : t.ink3,
            fontSize: 9.5, letterSpacing: "0.14em", fontWeight: 700,
            whiteSpace: "nowrap",
          }}>
            {locked && (
              <svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4"><rect x="4" y="11" width="16" height="9" rx="2"></rect><path d="M8 11V8a4 4 0 0 1 8 0v3"></path></svg>
            )}
            {accessPill.label}
          </div>
          </div>
        </div>

        {/* CENTRO: número grande (borrado quando bloqueado) */}
        <div style={{
          flex: 1,
          display: "flex", alignItems: "center", justifyContent: "center",
          position: "relative",
        }}>
          <div style={{
            position: "absolute", inset: 0,
            display: "flex", alignItems: "center", justifyContent: "center",
            fontFamily: TYPE.display,
            fontSize: Math.min(width, height) * 0.85,
            color: t.ink4, opacity: isCombo ? 0.20 : 0.14,
            lineHeight: 1, letterSpacing: "-0.02em",
            pointerEvents: "none",
            transform: "translate3d(var(--gx, 0px), -4%, 0)",
            filter: locked ? "blur(12px)" : "none",
          }}>{module.chapter}</div>
        </div>

        {/* BOTTOM TÍTULO */}
        <div style={{ pointerEvents: "auto", flex: 1, display: "flex", flexDirection: "column" }}>
          <div style={{
            fontFamily: TYPE.display,
            fontSize: 38,
            lineHeight: 0.95,
            color: t.ink1,
            letterSpacing: "-0.01em",
            marginBottom: 10,
            height: 72,
            display: "flex",
            alignItems: "flex-end",
            wordBreak: "break-word",
            textTransform: "uppercase",
            pointerEvents: "none",
          }}>{nl2br(module.name)}</div>

          <div style={{
            fontFamily: TYPE.sans,
            fontSize: 13, lineHeight: 1.55,
            color: t.ink2,
            marginBottom: 16,
            maxWidth: "94%",
            minHeight: 82,
            overflow: "hidden",
            pointerEvents: "none",
          }}>{nl2br(module.desc)}</div>

          <div style={{ flex: 1, minHeight: 14 }}></div>

          {/* PREÇO + AÇÃO */}
          <div style={{
            paddingTop: 18,
            borderTop: `1px solid ${t.border}`,
          }}>
            {isSoon ? (
              <div style={{ marginBottom: 18, minHeight: 78, display: "flex", flexDirection: "column", justifyContent: "flex-end", pointerEvents: "none" }}>
                <div style={countLabelStyle}>{module.count}</div>
                <div style={{
                  fontFamily: TYPE.display, fontSize: 30, color: t.ink2,
                  lineHeight: 1, letterSpacing: "-0.01em", textTransform: "uppercase",
                }}>Em breve</div>
              </div>
            ) : (unlocked || comboActive) ? (
              <div style={{ marginBottom: 18, minHeight: 78, display: "flex", flexDirection: "column", justifyContent: "flex-end", pointerEvents: "none" }}>
                <div style={countLabelStyle}>{module.count}</div>
                <div style={{
                  fontFamily: TYPE.display, fontSize: 30, color: t.ink1,
                  lineHeight: 1, letterSpacing: "-0.01em", textTransform: "uppercase",
                }}>{module.free ? "Grátis" : "Acesso liberado"}</div>
              </div>
            ) : (
              <div style={{ marginBottom: 18, minHeight: 78, display: "flex", flexDirection: "column", justifyContent: "flex-end", pointerEvents: "none" }}>
                <div style={countLabelStyle}>{module.count}</div>
                {module.term === "ano" ? (
                  <div>
                    <div style={{ display: "flex", alignItems: "baseline", gap: 7 }}>
                      <span style={{
                        fontFamily: TYPE.sans, fontSize: 15, color: t.ink2, fontWeight: 700, whiteSpace: "nowrap",
                      }}>12x</span>
                      <span style={{
                        fontFamily: TYPE.display, fontSize: 40, color: t.ink1,
                        lineHeight: 1, letterSpacing: "-0.01em", whiteSpace: "nowrap",
                      }}>R$ {(module.price / 12).toFixed(2).replace(".", ",")}</span>
                    </div>
                    <div style={{
                      marginTop: 6, fontFamily: TYPE.sans, fontSize: 11.5, color: t.ink3,
                      letterSpacing: "0.02em", whiteSpace: "nowrap",
                    }}>
                      {module.priceOld && <span style={{ textDecoration: "line-through", color: t.ink4, marginRight: 7 }}>R$ {module.priceOld}</span>}
                      ou R$ {module.price} à vista · 1 ano de acesso
                    </div>
                  </div>
                ) : (
                  <div style={{ display: "flex", alignItems: "baseline", gap: 10 }}>
                    {module.priceOld && (
                      <span style={{
                        fontFamily: TYPE.sans, fontSize: 14, color: t.ink4,
                        textDecoration: "line-through", whiteSpace: "nowrap",
                      }}>R$ {module.priceOld}</span>
                    )}
                    <span style={{
                      fontFamily: TYPE.display, fontSize: 40, color: t.ink1,
                      lineHeight: 1, letterSpacing: "-0.01em", whiteSpace: "nowrap",
                    }}>R$ {module.price}</span>
                  </div>
                )}
              </div>
            )}
            {comboActive ? (
              <div style={{
                ...buttonBase,
                background: t.accentMuted, color: t.ink1,
                border: `1px solid ${t.borderStrong}`, pointerEvents: "none",
              }}>
                Acesso ativo
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
                  <path d="m5 12 5 5 9-11"></path>
                </svg>
              </div>
            ) : (
              <button
                data-poster-buy
                onClick={(e) => { e.stopPropagation(); (unlocked ? onOpen : onBuy)?.(); }}
                style={{
                  ...buttonBase,
                  background: (unlocked || isSoon) ? "transparent" : t.ink1,
                  color: isSoon ? t.ink2 : (unlocked ? t.ink1 : t.bg0),
                  border: isSoon ? `1px dashed ${t.border}` : `1px solid ${unlocked ? t.border : t.ink1}`,
                  cursor: "pointer", zIndex: 3, position: "relative",
                }}
              >
                {isSoon ? "Avisar quando sair" : buttonLabel}
                {isSoon ? (
                  <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8"><path d="M12 5v14M5 12h14"></path></svg>
                ) : (
                  <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8"><path d="m5 12h14M13 6l6 6-6 6"></path></svg>
                )}
              </button>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

// ───────── CARROSSEL ─────────
function PosterCarousel({ modules, t, onOpenModule, onBuyModule, onCodeModule, isUnlocked, frameWidth, frameHeight }) {
  const posterW = Math.round(frameWidth * 0.78);
  const posterH = Math.max(Math.round(frameHeight * 0.70) + 78, 460);
  const gap = 14;
  const itemW = posterW + gap;
  const sidePad = (frameWidth - posterW) / 2;

  const REPS = 3;
  const repeated = _useMemo(() => {
    const arr = [];
    for (let i = 0; i < REPS; i++) modules.forEach((m, idx) => arr.push({ ...m, _key: `${i}-${idx}` }));
    return arr;
  }, [modules]);

  const trackRef = _useRef(null);
  const wrapRef = _useRef(null);
  const offsetRef = _useRef(0);
  const velocityRef = _useRef(0);
  const rafRef = _useRef(0);
  const lastTimeRef = _useRef(0);

  const draggingRef = _useRef(false);
  const startXRef = _useRef(0);
  const startYRef = _useRef(0);
  const startOffsetRef = _useRef(0);
  const lastPxRef = _useRef(0);
  const lastTRef = _useRef(0);
  const movedRef = _useRef(false); // já passou do threshold?

  const [centerIdx, setCenterIdx] = _useState(0);

  const baseLen = modules.length * itemW;

  _useEffect(() => {
    offsetRef.current = -baseLen;
    if (trackRef.current) trackRef.current.style.transform = `translate3d(${offsetRef.current}px,0,0)`;
  }, [baseLen]);

  // loop principal
  _useEffect(() => {
    let canceled = false;
    const loop = (now) => {
      if (canceled) return;
      const dt = Math.min(50, now - (lastTimeRef.current || now));
      lastTimeRef.current = now;

      if (!draggingRef.current) {
        offsetRef.current += velocityRef.current * dt;
        velocityRef.current *= FRICTION;
        if (Math.abs(velocityRef.current) < VELOCITY_THRESHOLD) {
          velocityRef.current = -AUTO_SPEED;
        }
      }

      while (offsetRef.current <= -2 * baseLen) offsetRef.current += baseLen;
      while (offsetRef.current > -baseLen) offsetRef.current -= baseLen;

      if (trackRef.current) {
        trackRef.current.style.transform = `translate3d(${offsetRef.current}px,0,0)`;
      }

      const localOffset = offsetRef.current % baseLen;
      const adjusted = (-localOffset - sidePad) / itemW;
      const idx = ((Math.round(adjusted) % modules.length) + modules.length) % modules.length;
      setCenterIdx((cur) => (cur === idx ? cur : idx));

      // parallax sutil do glow interno (baseado na posição real na tela)
      const wrapEl = wrapRef.current, trEl = trackRef.current;
      if (wrapEl && trEl) {
        const half = wrapEl.clientWidth / 2;
        const base = wrapEl.getBoundingClientRect().left;
        const kids = trEl.children;
        for (let i = 0; i < kids.length; i++) {
          const r = kids[i].getBoundingClientRect();
          const d = (r.left - base + r.width / 2) - half;
          kids[i].style.setProperty("--gx", (d * 0.05).toFixed(1) + "px");
        }
      }

      rafRef.current = requestAnimationFrame(loop);
    };
    rafRef.current = requestAnimationFrame(loop);
    return () => { canceled = true; cancelAnimationFrame(rafRef.current); };
  }, [baseLen, itemW, sidePad, modules.length]);

  // ─── POINTER HANDLERS (sem capture — deixa clicks passarem) ───
  _useEffect(() => {
    const wrap = wrapRef.current;
    if (!wrap) return;

    const onDown = (e) => {
      if (e.pointerType === "mouse" && e.button !== 0) return;
      draggingRef.current = true;
      movedRef.current = false;
      startXRef.current = e.clientX;
      startYRef.current = e.clientY;
      startOffsetRef.current = offsetRef.current;
      lastPxRef.current = e.clientX;
      lastTRef.current = performance.now();
      velocityRef.current = 0;
    };

    const onMove = (e) => {
      if (!draggingRef.current) return;
      const dx = e.clientX - startXRef.current;
      const dy = e.clientY - startYRef.current;

      // Se moveu mais vertical que horizontal nos primeiros pixels, é scroll da página
      if (!movedRef.current && Math.abs(dy) > Math.abs(dx) && Math.abs(dy) > DRAG_THRESHOLD) {
        draggingRef.current = false;
        return;
      }

      if (Math.abs(dx) > DRAG_THRESHOLD) {
        movedRef.current = true;
        e.preventDefault?.();
      }

      if (movedRef.current) {
        offsetRef.current = startOffsetRef.current + dx;
        const now = performance.now();
        const ddt = now - lastTRef.current;
        if (ddt > 0) {
          const dxLocal = e.clientX - lastPxRef.current;
          velocityRef.current = dxLocal / ddt;
        }
        lastPxRef.current = e.clientX;
        lastTRef.current = now;
      }
    };

    const onUp = () => {
      draggingRef.current = false;
    };

    // Listeners de move/up no documento garantem que continuamos
    // recebendo eventos mesmo se o dedo sair do wrap.
    // Click bubbles normalmente, sem ser sequestrado por pointer capture.
    wrap.addEventListener("pointerdown", onDown);
    window.addEventListener("pointermove", onMove, { passive: false });
    window.addEventListener("pointerup", onUp);
    window.addEventListener("pointercancel", onUp);

    return () => {
      wrap.removeEventListener("pointerdown", onDown);
      window.removeEventListener("pointermove", onMove);
      window.removeEventListener("pointerup", onUp);
      window.removeEventListener("pointercancel", onUp);
    };
  }, []);

  // Bloqueia o click no poster se foi arrasto (capture phase)
  const onClickCapture = (e) => {
    if (movedRef.current) {
      e.stopPropagation();
      e.preventDefault();
      movedRef.current = false;
    }
  };

  return (
    <div
      ref={wrapRef}
      data-carousel
      onClickCapture={onClickCapture}
      style={{
        position: "relative", width: "100%", height: posterH + 4,
        overflow: "hidden",
        touchAction: "pan-y",
      }}
    >
      <div ref={trackRef} style={{
        display: "flex", alignItems: "stretch",
        paddingLeft: sidePad,
        willChange: "transform",
      }}>
        {repeated.map((m, i) => {
          const realIdx = i % modules.length;
          return (
            <PosterCard
              key={m._key}
              module={m}
              t={t}
              width={posterW}
              height={posterH}
              isCenter={realIdx === centerIdx}
              unlocked={isUnlocked ? !!isUnlocked(m) : false}
              onOpen={() => onOpenModule?.(m)}
              onBuy={() => onBuyModule?.(m)}
              onCode={() => onCodeModule?.(m)}
            />
          );
        })}
      </div>

      {/* PAGINAÇÃO — pontos */}
      <div style={{
        position: "absolute", bottom: -28, left: 0, right: 0,
        display: "flex", justifyContent: "center", gap: 6, pointerEvents: "none",
      }}>
        {modules.map((m, i) => (
          <span key={i} style={{
            width: i === centerIdx ? 24 : 6, height: 6,
            background: i === centerIdx ? t.accent : t.border,
            borderRadius: 999,
            transition: "all 0.35s cubic-bezier(0.2, 0.8, 0.2, 1)",
          }}></span>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { PosterCarousel });
