/* TowerSystem — promo video scenes
   Exports scene components + shared visual primitives to window. */

const TS = {
  bg:      '#0E0F12',
  bg2:     '#16181C',
  panel:   '#1B1E23',
  red:     '#DE2F2F',
  redDim:  '#A81C1C',
  white:   '#F5F6F7',
  gray:    '#9AA0A6',
  grayDim: '#5C6166',
  line:    'rgba(255,255,255,0.10)',
  lineFaint:'rgba(255,255,255,0.05)',
};

const DISPLAY = "'Archivo', system-ui, sans-serif";
const BODY = "'Archivo', system-ui, sans-serif";

// ── Shared easing-driven helpers ────────────────────────────────────────────
function rampIn(localTime, dur = 0.5, ease = Easing.easeOutCubic) {
  return ease(clamp(localTime / dur, 0, 1));
}

// ── Small uppercase technical label with red tick ───────────────────────────
function Kicker({ text, x, y, delay = 0, color = TS.red }) {
  const t = useTime();
  const lt = t - delay;
  const op = clamp(lt / 0.4, 0, 1);
  const w = clamp(lt / 0.5, 0, 1);
  return (
    <div style={{
      position: 'absolute', left: x, top: y, opacity: op,
      display: 'flex', alignItems: 'center', gap: 12,
      fontFamily: BODY, fontSize: 18, fontWeight: 700,
      letterSpacing: '0.28em', textTransform: 'uppercase', color: TS.white,
    }}>
      <span style={{ display: 'inline-block', width: 38 * w, height: 4, background: color, transformOrigin: 'left' }}></span>
      <span>{text}</span>
    </div>
  );
}

// ── Animated scaffold grid (the brand motif) ────────────────────────────────
// Draws vertical standards + horizontal ledgers + one red diagonal brace,
// each member fading/extending in with a stagger driven by `build` (0..1).
function ScaffoldFrame({ x, y, cols, rows, cell, build, faint = false, redBrace = true }) {
  const W = cols * cell, H = rows * cell;
  const members = [];
  let idx = 0;
  const total = (cols + 1) + (rows + 1) + (redBrace ? 1 : 0);
  const stagger = 0.6 / Math.max(1, total);

  const memberP = (i) => clamp((build - i * stagger) / 0.4, 0, 1);
  const stroke = faint ? TS.lineFaint : TS.line;

  // verticals (standards)
  for (let c = 0; c <= cols; c++) {
    const p = Easing.easeOutCubic(memberP(idx++));
    members.push(<line key={'v'+c} x1={c*cell} y1={0} x2={c*cell} y2={H*p}
      stroke={stroke} strokeWidth={c % cols === 0 ? 3 : 2} />);
  }
  // horizontals (ledgers)
  for (let r = 0; r <= rows; r++) {
    const p = Easing.easeOutCubic(memberP(idx++));
    members.push(<line key={'h'+r} x1={0} y1={r*cell} x2={W*p} y2={r*cell}
      stroke={stroke} strokeWidth={2} />);
  }
  // node dots
  const dotP = clamp((build - 0.55) / 0.4, 0, 1);
  const dots = [];
  if (!faint) for (let c = 0; c <= cols; c++) for (let r = 0; r <= rows; r++) {
    dots.push(<circle key={'d'+c+'-'+r} cx={c*cell} cy={r*cell} r={2.5}
      fill="rgba(255,255,255,0.22)" opacity={dotP} />);
  }
  // red diagonal brace across one bay
  let brace = null;
  if (redBrace) {
    const p = Easing.easeOutCubic(memberP(idx++));
    brace = <line x1={0} y1={H} x2={cell*p} y2={H - cell*p}
      stroke={TS.red} strokeWidth={4} opacity={0.95} />;
  }

  return (
    <svg width={W} height={H} style={{ position: 'absolute', left: x, top: y, overflow: 'visible' }}>
      {members}{dots}{brace}
    </svg>
  );
}

// Persistent faint background lattice that slowly drifts the whole video
function BackdropLattice() {
  const t = useTime();
  const drift = Math.sin(t * 0.18) * 14;
  const build = clamp(t / 1.2, 0, 1);
  return (
    <div style={{ position: 'absolute', inset: 0, overflow: 'hidden' }}>
      {/* vignette */}
      <div style={{ position: 'absolute', inset: 0,
        background: 'radial-gradient(120% 90% at 70% 20%, rgba(40,44,52,0.55) 0%, rgba(14,15,18,0) 55%)' }}></div>
      <div style={{ position: 'absolute', left: -40 + drift, top: -40 }}>
        <ScaffoldFrame x={0} y={0} cols={9} rows={6} cell={160} build={build} faint redBrace={false} />
      </div>
      {/* floor line */}
      <div style={{ position: 'absolute', left: 0, right: 0, bottom: 92, height: 1, background: TS.line }}></div>
    </div>
  );
}

// ── Photo panel: real image, Ken Burns drift, technical frame + corner ticks ─
// `images` is an array of src strings; if more than one they crossfade across
// the [start,end] window. Stays composited; slow zoom keeps the frame alive.
function PhotoPanel({ images, start, end, x, y, w, h, label, focus = '50% 50%', zoom = 0.12 }) {
  const t = useTime();
  const list = Array.isArray(images) ? images : [images];

  // container entry / exit
  let cOp = 0, ty = 26;
  if (t >= start) {
    const inP = Easing.easeOutCubic(clamp((t - start) / 0.6, 0, 1));
    cOp = inP; ty = (1 - inP) * 26;
    if (t > end - 0.5) {
      const outP = Easing.easeInCubic(clamp((t - (end - 0.5)) / 0.5, 0, 1));
      cOp = 1 - outP; ty = -outP * 14;
    }
  }
  if (cOp <= 0 && t < start) return null;

  const total = end - start;
  const seg = total / list.length;
  const xf = 0.55;

  return (
    <div style={{ position: 'absolute', left: x, top: y, width: w, height: h,
      opacity: cOp, transform: `translateY(${ty}px)`, willChange: 'transform,opacity', overflow: 'hidden' }}>
      <div style={{ position: 'absolute', inset: 0, background: TS.bg2 }}></div>
      {list.map((src, i) => {
        const segStart = start + i * seg, segEnd = segStart + seg;
        let op = 1;
        if (list.length > 1) {
          if (i > 0 && t < segStart + xf) op = clamp((t - segStart) / xf, 0, 1);
          if (i < list.length - 1 && t > segEnd - xf) op = 1 - clamp((t - (segEnd - xf)) / xf, 0, 1);
          if (t < segStart - xf || t > segEnd + xf) op = (i === 0 && t < segStart) ? 1 : (i === list.length-1 && t>segEnd?1:0);
        }
        const kp = clamp((t - segStart) / seg, 0, 1);
        const ease = Easing.easeInOutSine ? Easing.easeInOutSine(kp) : kp;
        // Ken Burns: alternate zoom-in / zoom-out per image, with a gentle pan.
        // Baseline scale stays ≥1.06 so thin lines are always downsampled (no shimmer).
        const dir = i % 2 === 0 ? 1 : -1;
        const baseScale = 1.06;
        const scale = baseScale + zoom * (dir > 0 ? ease : (1 - ease));
        const panX = (dir > 0 ? 1 : -1) * (ease - 0.5) * 2.2;   // % drift
        const panY = (dir > 0 ? -1 : 1) * (ease - 0.5) * 1.6;
        return (
          <img key={i} src={src} alt="" style={{ position:'absolute', inset:0, width:'100%', height:'100%',
            objectFit:'cover', objectPosition:focus, opacity:op,
            transform:`translate3d(${panX}%, ${panY}%, 0) scale(${scale})`, transformOrigin:focus,
            willChange:'transform,opacity', backfaceVisibility:'hidden' }} />
        );
      })}
      {/* subtle dark grade for text legibility near edges */}
      <div style={{ position:'absolute', inset:0, background:'linear-gradient(180deg, rgba(14,15,18,0.05) 0%, rgba(14,15,18,0) 30%, rgba(14,15,18,0.45) 100%)' }}></div>
      <div style={{ position: 'absolute', inset: 0, border: `1px solid rgba(255,255,255,0.18)`, pointerEvents: 'none', zIndex: 2 }}></div>
      {[['0','0'],['100%','0'],['0','100%'],['100%','100%']].map((p,i)=>(
        <div key={i} style={{ position:'absolute', left:p[0], top:p[1], width:16, height:16,
          borderTop: (p[1]==='0'?`2px solid ${TS.red}`:'none'),
          borderBottom:(p[1]!=='0'?`2px solid ${TS.red}`:'none'),
          borderLeft:(p[0]==='0'?`2px solid ${TS.red}`:'none'),
          borderRight:(p[0]!=='0'?`2px solid ${TS.red}`:'none'),
          transform:'translate(-1px,-1px)', zIndex:3 }}></div>
      ))}
      {label && <div style={{ position:'absolute', left:14, bottom:14, zIndex:3,
        fontFamily: BODY, fontSize:13, fontWeight:700, letterSpacing:'0.18em',
        textTransform:'uppercase', color:TS.white }}>
        <span style={{ display:'inline-block', width:22, height:3, background:TS.red, marginRight:10, transform:'translateY(-3px)' }}></span>
        {label}</div>}
    </div>
  );
}
const IMG = 'assets/img/';

// ── List item that slides in with an index number ───────────────────────────
function ServiceRow({ n, text, x, y, start, accent = false }) {
  const t = useTime();
  const lt = t - start;
  const p = Easing.easeOutCubic(clamp(lt / 0.5, 0, 1));
  const op = clamp(lt / 0.4, 0, 1);
  return (
    <div style={{ position:'absolute', left:x, top:y, opacity:op,
      transform:`translateX(${(1-p)*-26}px)`, display:'flex', alignItems:'baseline', gap:18 }}>
      <span style={{ fontFamily:BODY, fontSize:16, fontWeight:700, color:accent?TS.red:TS.grayDim,
        fontVariantNumeric:'tabular-nums', letterSpacing:'0.1em', width:28 }}>{n}</span>
      <span style={{ fontFamily:DISPLAY, fontSize:34, fontWeight:600, color:TS.white,
        letterSpacing:'-0.01em' }}>{text}</span>
    </div>
  );
}

// ════════════════════════════════════════════════════════════════════════════
// SCENES
// ════════════════════════════════════════════════════════════════════════════

// 1 — INTRO (0–4.5)  logo build
function IntroScene() {
  const t = useTime();
  const build = clamp((t - 0.2) / 1.4, 0, 1);
  const logoP = Easing.easeOutCubic(clamp((t - 1.3) / 0.7, 0, 1));
  const logoOut = t > 4.0 ? clamp((t - 4.0) / 0.5, 0, 1) : 0;
  const taglineP = clamp((t - 2.0) / 0.6, 0, 1);
  return (
    <Sprite start={0} end={4.5}>
      {/* central scaffold tower assembling behind the logo */}
      <div style={{ position:'absolute', left:'50%', top:170, transform:'translateX(-50%)' }}>
        <ScaffoldFrame x={-240} y={0} cols={3} rows={3} cell={160} build={build} />
      </div>
      <div style={{ position:'absolute', left:'50%', top:300, transform:`translate(-50%, ${(1-logoP)*18}px)`,
        opacity: logoP * (1 - logoOut), textAlign:'center' }}>
        <img src="assets/logo-towersystem.png" alt="TowerSystem"
          style={{ height:66, display:'block', margin:'0 auto', filter:'drop-shadow(0 6px 20px rgba(0,0,0,0.5))' }} />
        <div style={{ marginTop:26, height:1, width: 360*taglineP, background:TS.line, marginLeft:'auto', marginRight:'auto' }}></div>
        <div style={{ marginTop:18, opacity:taglineP, fontFamily:BODY, fontSize:20, fontWeight:600,
          letterSpacing:'0.32em', textTransform:'uppercase', color:TS.gray }}>
          Échafaudages&nbsp;&nbsp;Fixes&nbsp;&nbsp;&amp;&nbsp;&nbsp;Mobiles
        </div>
      </div>
    </Sprite>
  );
}

// 2 — SPÉCIALISTE (4.5–9)
function SpecialisteScene() {
  return (
    <Sprite start={4.5} end={9}>
      <Kicker text="Suisse romande · depuis 2005" x={96} y={150} delay={4.7} />
      <Sprite start={4.9} end={9}>
        <TextSprite text="Le spécialiste" x={92} y={206} size={90} weight={800} color={TS.white} font={DISPLAY} letterSpacing="-0.03em" />
      </Sprite>
      <Sprite start={5.05} end={9}>
        <TextSprite text="de l'échafaudage" x={92} y={308} size={90} weight={800} color={TS.white} font={DISPLAY} letterSpacing="-0.03em" />
      </Sprite>
      <Sprite start={5.2} end={9}>
        <TextSprite text="fixe & mobile." x={92} y={410} size={90} weight={800} color={TS.red} font={DISPLAY} letterSpacing="-0.03em" />
      </Sprite>
      <Sprite start={5.8} end={9}>
        <TextSprite text="Pour les professionnels du bâtiment." x={96} y={540} size={26} weight={500} color={TS.gray} font={BODY} letterSpacing="0" />
      </Sprite>
      <PhotoPanel images={[IMG+'01-pont-roulant-lausanne.jpg']} start={5.2} end={9}
        x={904} y={150} w={300} h={430} label="Chantier · Lausanne" focus="50% 30%" />
    </Sprite>
  );
}

// 3 — ÉCHAFAUDAGE FIXE (9–14)
function FixeScene() {
  return (
    <Sprite start={9} end={14}>
      <Kicker text="01 — Échafaudage fixe" x={96} y={132} delay={9.1} />
      <Sprite start={9.2} end={14}>
        <TextSprite text="Vente & location" x={92} y={172} size={76} weight={800} color={TS.white} font={DISPLAY} letterSpacing="-0.025em" />
      </Sprite>
      <ServiceRow n="01" text="Échafaudage de façade" x={96} y={304} start={9.6} />
      <ServiceRow n="02" text="Ferblantier & couvreur" x={96} y={360} start={9.75} />
      <ServiceRow n="03" text="Toiture provisoire & d'acrotère" x={96} y={416} start={9.9} />
      <ServiceRow n="04" text="Tours d'accès" x={96} y={472} start={10.05} />
      <ServiceRow n="05" text="Protections : tunnels, enceintes" x={96} y={528} start={10.2} accent />
      <PhotoPanel images={[IMG+'08-echafaudage-mobile-lausanne.jpg', IMG+'21-echafaudage-mobile-crissier.jpg']}
        start={9.4} end={14} x={748} y={150} w={436} h={430} label="Façade · Vaud" focus="50% 45%" />
    </Sprite>
  );
}

// 4 — ÉCHAFAUDAGE MOBILE (14–19)
function MobileScene() {
  return (
    <Sprite start={14} end={19}>
      <Kicker text="02 — Échafaudage mobile" x={96} y={132} delay={14.1} />
      <Sprite start={14.2} end={19}>
        <TextSprite text="Ponts roulants" x={92} y={172} size={76} weight={800} color={TS.white} font={DISPLAY} letterSpacing="-0.025em" />
      </Sprite>
      <ServiceRow n="01" text="Tours d'accès & échafaudages mobiles" x={96} y={304} start={14.6} />
      <ServiceRow n="02" text="Location au jour, à la semaine, au mois" x={96} y={360} start={14.75} />
      <ServiceRow n="03" text="Vente & location" x={96} y={416} start={14.9} />
      {/* Instant UpRight callout */}
      <Sprite start={15.1} end={19}>
        {({ localTime }) => {
          const p = Easing.easeOutBack(clamp(localTime / 0.6, 0, 1));
          return (
            <div style={{ position:'absolute', left:96, top:486,
              transform:`scale(${0.9 + 0.1*p})`, transformOrigin:'left center',
              opacity: clamp(localTime/0.4,0,1),
              border:`1px solid ${TS.red}`, padding:'14px 22px', display:'inline-flex',
              alignItems:'center', gap:14 }}>
              <span style={{ fontFamily:BODY, fontSize:13, fontWeight:700, letterSpacing:'0.2em',
                textTransform:'uppercase', color:TS.red }}>Représentant agréé</span>
              <span style={{ fontFamily:DISPLAY, fontSize:26, fontWeight:800, color:TS.white,
                letterSpacing:'-0.01em' }}>Instant UpRight</span>
            </div>
          );
        }}
      </Sprite>
      <PhotoPanel images={[IMG+'05-pont-roulant-lausanne.jpg', IMG+'13-echafaudage-roulant-vaud.jpg', IMG+'16-echafaudage-mobile-suisse.jpg']}
        start={14.4} end={19} x={748} y={150} w={436} h={430} label="Pont roulant" focus="50% 40%" />
    </Sprite>
  );
}

// 5 — ATOUTS (19–24)
function AtoutsScene() {
  const pillars = [
    ['Livraison rapide', 'Pose par des professionnels'],
    ['Montage & démontage', 'Pris en charge de A à Z'],
    ['Normes SIA & SUVA', 'Sécurité conforme, sur-mesure'],
  ];
  return (
    <Sprite start={19} end={24}>
      <Kicker text="Ce qui est inclus" x={96} y={150} delay={19.1} />
      <Sprite start={19.2} end={24}>
        <TextSprite text="Tout, sans compromis." x={92} y={196} size={68} weight={800} color={TS.white} font={DISPLAY} letterSpacing="-0.025em" />
      </Sprite>
      {pillars.map((p, i) => (
        <Sprite key={i} start={19.6 + i*0.18} end={24}>
          {({ localTime }) => {
            const pr = Easing.easeOutCubic(clamp(localTime / 0.55, 0, 1));
            return (
              <div style={{ position:'absolute', left: 96 + i*364, top: 340,
                width: 332, opacity: clamp(localTime/0.4,0,1),
                transform:`translateY(${(1-pr)*22}px)` }}>
                <div style={{ height:4, width: 56*pr, background:TS.red, marginBottom:26 }}></div>
                <div style={{ fontFamily:DISPLAY, fontSize:38, fontWeight:800, color:TS.white,
                  letterSpacing:'-0.02em', lineHeight:1.05 }}>{p[0]}</div>
                <div style={{ marginTop:14, fontFamily:BODY, fontSize:22, fontWeight:500,
                  color:TS.gray, lineHeight:1.3 }}>{p[1]}</div>
              </div>
            );
          }}
        </Sprite>
      ))}
    </Sprite>
  );
}

// 6 — PROMO (24–27.5)
function PromoScene() {
  return (
    <Sprite start={24} end={27.5}>
      {/* black wash sweeping in */}
      <Sprite start={24} end={27.5}>
        {({ localTime }) => {
          const p = Easing.easeOutQuart(clamp(localTime / 0.5, 0, 1));
          return <div style={{ position:'absolute', inset:0,
            background:`linear-gradient(105deg, #050608 0%, #0C0E12 100%)`,
            clipPath:`inset(0 ${(1-p)*100}% 0 0)` }}></div>;
        }}
      </Sprite>
      <Sprite start={24.25} end={27.5}>
        <TextSprite text="Promotion en cours" x={96} y={158} size={20} weight={700} color={TS.red} font={BODY} letterSpacing="0.3em" />
      </Sprite>
      <Sprite start={24.4} end={27.5}>
        {({ localTime }) => {
          const p = Easing.easeOutBack(clamp(localTime / 0.7, 0, 1));
          return (
            <div style={{ position:'absolute', left:88, top:196,
              transform:`scale(${0.6 + 0.4*p})`, transformOrigin:'left top',
              opacity: clamp(localTime/0.3,0,1),
              fontFamily:DISPLAY, fontSize:280, fontWeight:800, color:TS.white,
              letterSpacing:'-0.04em', lineHeight:0.85 }}>−20%</div>
          );
        }}
      </Sprite>
      <Sprite start={25.1} end={27.5}>
        <TextSprite text="sur le pont roulant Snappy 300" x={100} y={520} size={44} weight={700} color={TS.white} font={DISPLAY} letterSpacing="-0.01em" />
      </Sprite>
      <Sprite start={25.4} end={27.5}>
        <TextSprite text="largeur 0,75 m · offre limitée" x={102} y={584} size={24} weight={500} color={TS.gray} font={BODY} letterSpacing="0.02em" />
      </Sprite>
      {/* Snappy 300 product photo, right */}
      <Sprite start={24.7} end={27.5}>
        {({ localTime }) => {
          const p = Easing.easeOutCubic(clamp(localTime / 0.6, 0, 1));
          const out = localTime > (3.5 - 0.5) ? clamp((localTime - 3.0) / 0.5, 0, 1) : 0;
          const span = 27.5 - 24.7;
          const kp = clamp(localTime / span, 0, 1);
          return (
            <div style={{ position:'absolute', right: 64, top: 96, width: 360, height: 528,
              opacity: p * (1 - out), transform:`translateY(${(1-p)*26}px)`, overflow:'hidden',
              filter:'drop-shadow(0 30px 50px rgba(0,0,0,0.45))' }}>
              <img src={IMG+'snappy-300.jpg'} alt="Pont roulant Snappy 300" style={{ width:'100%', height:'100%',
                objectFit:'cover', objectPosition:'50% 50%' }} />
            </div>
          );
        }}
      </Sprite>
    </Sprite>
  );
}

// 7 — OUTRO (27.5–31)
function OutroScene() {
  const t = useTime();
  const build = clamp((t - 27.6) / 1.2, 0, 1);
  const logoP = Easing.easeOutCubic(clamp((t - 27.9) / 0.6, 0, 1));
  return (
    <Sprite start={27.5} end={31}>
      <div style={{ position:'absolute', right:-30, top:120, opacity:0.5 }}>
        <ScaffoldFrame x={0} y={0} cols={3} rows={3} cell={150} build={build} />
      </div>
      <div style={{ position:'absolute', left:96, top:250, opacity:logoP,
        transform:`translateY(${(1-logoP)*14}px)` }}>
        <img src="assets/logo-towersystem.png" alt="TowerSystem" style={{ height:54, display:'block' }} />
      </div>
      <Sprite start={28.1} end={31}>
        <TextSprite text="Échafaudage fixe & mobile — vente & location" x={98} y={362} size={28} weight={600} color={TS.gray} font={BODY} letterSpacing="0" />
      </Sprite>
      <Sprite start={28.4} end={31}>
        {({ localTime }) => {
          const p = clamp(localTime/0.5,0,1);
          return (
            <div style={{ position:'absolute', left:98, top:430, opacity:p,
              display:'flex', gap:48, alignItems:'flex-start' }}>
              <ContactBlock label="Téléphone" value="021 702 28 67" />
              <ContactBlock label="Web" value="towersystem.ch" />
              <ContactBlock label="Adresse" value={'Crissier · à 800 m de\nla sortie d\u2019autoroute'} />
            </div>
          );
        }}
      </Sprite>
      <Sprite start={28.7} end={31}>
        <TextSprite text="Parking disponible sur place" x={98} y={612} size={18} weight={600} color={TS.grayDim} font={BODY} letterSpacing="0.16em" />
      </Sprite>
    </Sprite>
  );
}

function ContactBlock({ label, value }) {
  return (
    <div style={{ flexShrink: 0 }}>
      <div style={{ fontFamily:BODY, fontSize:13, fontWeight:700, letterSpacing:'0.22em',
        textTransform:'uppercase', color:TS.red, marginBottom:10 }}>{label}</div>
      <div style={{ fontFamily:DISPLAY, fontSize:26, fontWeight:700, color:TS.white,
        letterSpacing:'-0.01em', whiteSpace:'pre', lineHeight:1.25 }}>{value}</div>
    </div>
  );
}

Object.assign(window, {
  TS, DISPLAY, BODY,
  Kicker, ScaffoldFrame, BackdropLattice, PhotoPanel, ServiceRow, ContactBlock,
  IntroScene, SpecialisteScene, FixeScene, MobileScene, AtoutsScene, PromoScene, OutroScene,
});
