// ACT 1 — Luxury opening: restrained editorial reveal + scroll-synced product study

const HERO_FRAME_NUMBERS = [1,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120];
const HERO_FRAME_SRCS = HERO_FRAME_NUMBERS.map(n => `images/belgha-360/frame-${String(n).padStart(3,'0')}.webp`);

function ActHero({ lang, tweaks }) {
  const content = window.CONTENT[lang].hero;
  const study = window.CONTENT[lang].rot;
  const sectionRef = useRef(null);
  const canvasRef = useRef(null);
  const frameImagesRef = useRef([]);
  const rawP = useStickyProgress(sectionRef);
  const [p, setP] = useState(0);
  const [framesReady, setFramesReady] = useState(false);
  const isRTL = lang === 'ar';
  const { isPhone, isTablet } = useResponsive();

  useEffect(() => {
    let cancelled = false;
    let loaded = 0;
    const frames = HERO_FRAME_SRCS.map((src, index) => {
      const img = new Image();
      img.decoding = 'async';
      img.onload = () => {
        loaded += 1;
        if (index === 0 && !cancelled) {
          frameImagesRef.current = frames;
          drawHeroFrame(canvasRef.current, frames[0]);
        }
        if (loaded === HERO_FRAME_SRCS.length && !cancelled) {
          frameImagesRef.current = frames;
          setFramesReady(true);
        }
      };
      img.src = src;
      return img;
    });

    return () => {
      cancelled = true;
    };
  }, []);

  useEffect(() => {
    let raf;
    const tick = () => {
      setP(current => {
        const next = current + (rawP - current) * 0.24;
        return Math.abs(next - current) < 0.0005 ? current : next;
      });
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [rawP]);

  const intro = clamp(p / 0.08, 0, 1);
  const titleOut = clamp((p - 0.045) / 0.22, 0, 1);
  const objectMode = clamp((p - 0.12) / 0.28, 0, 1);
  const studyMode = clamp((p - 0.34) / 0.16, 0, 1);
  const studyHeadVisible = studyMode > 0.08;
  const frameProgress = clamp((p - 0.48) / 0.42, 0, 1);
  const frameIdx = framesReady
    ? Math.min(HERO_FRAME_SRCS.length - 1, Math.floor(frameProgress * HERO_FRAME_SRCS.length))
    : 0;

  const productX = isPhone
    ? lerp(isRTL ? -1.5 : 1.5, 0, easeInOut(objectMode))
    : lerp(isRTL ? -19 : 20, 0, easeInOut(objectMode));
  const baseProductY = isPhone ? lerp(4, 1, easeInOut(objectMode)) : lerp(-2, -1, easeInOut(objectMode));
  const productY = isPhone
    ? lerp(baseProductY, -14, easeInOut(studyMode))
    : isTablet
      ? lerp(baseProductY, -5, easeInOut(studyMode))
      : baseProductY;
  const baseProductScale = isPhone ? lerp(0.86, 0.98, easeInOut(objectMode)) : isTablet ? lerp(0.88, 1, easeInOut(objectMode)) : lerp(0.92, 1, easeInOut(objectMode));
  const productScale = isPhone
    ? lerp(baseProductScale, 1.1, easeInOut(studyMode))
    : isTablet
      ? lerp(baseProductScale, 1.08, easeInOut(studyMode))
      : baseProductScale;
  const productRotate = lerp(-4, 0, easeInOut(objectMode));
  const titleOpacity = 1 - easeInOut(titleOut);
  const titleY = lerp(0, -16, easeInOut(titleOut));
  const monogramScale = lerp(1, 4.4, easeInOut(clamp((p - 0.22) / 0.52, 0, 1)));
  const monogramOpacity = isPhone
    ? lerp(lerp(0.11, 0.28, intro) * (1 - objectMode * 0.42), 0.23, easeInOut(studyMode))
    : lerp(0.11, 0.28, intro) * (1 - objectMode * 0.42);

  const words = isRTL
    ? [content.line1, content.line2, content.line3]
    : [content.line1, content.line2, content.line3];

  useEffect(() => {
    const draw = () => {
      const frames = frameImagesRef.current;
      const img = frames[frameIdx] || frames[0];
      drawHeroFrame(canvasRef.current, img);
    };

    draw();
    window.addEventListener('resize', draw);
    return () => window.removeEventListener('resize', draw);
  }, [frameIdx, framesReady]);

  return (
    <section ref={sectionRef} className="act luxury-hero-act" style={{ height: isPhone ? '430vh' : '500vh' }}>
      <div className="luxury-hero">
        <div className="luxury-hero__veil" />
        <div className="luxury-hero__silk" />
        <div className="luxury-hero__light" style={{ opacity: lerp(0.75, 1, objectMode) }} />
        <div className="luxury-hero__study-grid" style={{ opacity: 0.08 * studyMode }}>
          <svg viewBox="0 0 1600 950" preserveAspectRatio="none">
            <defs>
              <pattern id="hero-study-grid" width="88" height="88" patternUnits="userSpaceOnUse">
                <path d="M88 0H0V88" fill="none" stroke="currentColor" strokeWidth="0.6" />
              </pattern>
            </defs>
            <rect width="1600" height="950" fill="url(#hero-study-grid)" />
          </svg>
        </div>

        <div
          className="luxury-hero__architecture"
          style={{
            opacity: lerp(0.09, 0.02, objectMode),
            transform: `translate3d(${lerp(0, -6, objectMode)}vw, -50%, 0) scale(${lerp(1, 1.05, objectMode)})`
          }}
        />

        <div
          className="luxury-hero__monogram"
          style={{
            opacity: monogramOpacity,
            transform: `translate(-50%, -50%) scale(${monogramScale})`
          }}
        >
          <img src="images/logo-dark.png" alt="" />
        </div>

        <div
          className="luxury-hero__copy"
          style={{
            opacity: titleOpacity * (1 - studyMode),
            transform: `translate3d(0, ${titleY}vh, 0)`
          }}
        >
          <div className="luxury-hero__sup mono">{content.sup}</div>
          <h1 className={isRTL ? 'is-arabic' : ''}>
            {words.map((word, i) => (
              <span
                key={`${word}-${i}`}
                className={!isRTL && i === 1 ? 'is-italic' : ''}
                style={{ animationDelay: `${0.18 + i * 0.13}s` }}
              >
                {word}
              </span>
            ))}
          </h1>
          <p>{content.body}</p>
        </div>

        <div
          className="luxury-hero__product"
          style={{
            opacity: lerp(0.84, 1, intro),
            transform: `translate3d(calc(-50% + ${productX}vw), calc(-50% + ${productY}vh), 0) scale(${productScale}) rotate(${productRotate}deg)`
          }}
        >
          <div className="luxury-hero__aura" />
          <div className="luxury-hero__disc" style={{ opacity: lerp(0.18, 0.34, objectMode) }} />
          <canvas ref={canvasRef} className="luxury-hero__canvas" aria-hidden="true" />
          <div className="luxury-hero__shadow" />
        </div>

        <div className="luxury-hero__details" style={{ opacity: titleOpacity }}>
          {(content.details || []).map(detail => (
            <span key={detail}>{detail}</span>
          ))}
        </div>

        <div className="luxury-hero__study-head" style={{ opacity: studyHeadVisible ? 1 : 0 }}>
          <div className="mono">{study.eyebrow}</div>
          <h2 className={isRTL ? 'is-arabic' : ''}>
            {study.h} <span style={{ fontStyle: isRTL ? 'normal' : 'italic' }}>{study.hIt}</span>
          </h2>
        </div>

        {tweaks.showCallouts && study.callouts.map((callout, i) => {
          const phases = [0.12, 0.32, 0.54, 0.74];
          const phase = phases[i];
          const on = frameProgress >= phase;
          const off = i < 3 && frameProgress >= phases[i + 1] + (isPhone ? 0 : 0.08);
          const visible = studyMode && on && !off;

          return (
            <div
              key={callout.title}
              className={`luxury-hero__callout ${callout.x < 50 ? 'is-left' : ''}`}
              style={{
                left: isPhone
                  ? callout.x < 50 ? 'max(22px, env(safe-area-inset-left))' : 'auto'
                  : `${callout.x}%`,
                right: isPhone
                  ? callout.x >= 50 ? 'max(22px, env(safe-area-inset-right))' : 'auto'
                  : 'auto',
                top: isPhone
                  ? `clamp(calc(152px + env(safe-area-inset-top)), ${callout.y}svh, calc(100svh - 164px - env(safe-area-inset-bottom)))`
                  : `${callout.y}%`,
                bottom: 'auto',
                opacity: visible ? 1 : 0,
                transform: visible ? 'translateY(0)' : `translateY(${isPhone ? 14 : 10}px)`
              }}
            >
              <i />
              <span />
              <div>
                <strong>{callout.title}</strong>
                <small>{callout.body}</small>
              </div>
            </div>
          );
        })}

      </div>
    </section>
  );
}

function drawHeroFrame(canvas, img) {
  if (!canvas || !img || !img.complete || !img.naturalWidth) return;

  const rect = canvas.getBoundingClientRect();
  if (!rect.width || !rect.height) return;

  const dpr = Math.min(window.devicePixelRatio || 1, 2);
  const width = Math.round(rect.width * dpr);
  const height = Math.round(rect.height * dpr);

  if (canvas.width !== width || canvas.height !== height) {
    canvas.width = width;
    canvas.height = height;
  }

  const ctx = canvas.getContext('2d');
  ctx.clearRect(0, 0, width, height);
  ctx.imageSmoothingEnabled = true;
  ctx.imageSmoothingQuality = 'high';

  const scale = Math.min(width / img.naturalWidth, height / img.naturalHeight);
  const drawWidth = img.naturalWidth * scale;
  const drawHeight = img.naturalHeight * scale;
  const x = (width - drawWidth) / 2;
  const y = (height - drawHeight) / 2;

  ctx.drawImage(img, x, y, drawWidth, drawHeight);
}

window.ActHero = ActHero;
