/* ──────────────────────────────────────────────────────────────────
   PRESENTER — pilota le SCHERMATE REALI dell'app dentro la timeline.
   Niente UI ridisegnata: monta PlannerScreen / NotificationsScreen /
   BachecaScreen reali e ci sovrappone un livello "presentatore":
   scroll automatico, cursore touch, tap, e stato reale (toast).
   ────────────────────────────────────────────────────────────────── */

const PRES_ORANGE = '#F97316';
const DEVICE_W = 384;
const DEVICE_H = 800;

/* easing path helper: interpola un campo lungo keyframe {t, ...} */
function trackField(time, keys, field, ease = Easing.easeInOutCubic) {
  return interpolate(keys.map(k => k.t), keys.map(k => k[field]), ease)(time);
}

/* ── Driver di scroll ──────────────────────────────────────────────
   Trova lo scroller reale, ne incapsula il contenuto una sola volta e
   lo trasla con un transform (robusto per live, screenshot ed export
   video — a differenza di scrollTop nativo, non sempre catturato). */
function useScrollDrive(hostRef, keys) {
  const time = useTime();
  React.useEffect(() => {
    const host = hostRef.current;
    if (!host || !keys) return;

    let wrap = host.querySelector('[data-scrollwrap]');
    let sc;
    if (wrap) {
      sc = wrap.parentElement;
    } else {
      const cands = [...host.querySelectorAll('div')].filter(d => {
        const s = getComputedStyle(d);
        return s.overflowY === 'auto' || s.overflowY === 'scroll';
      });
      let best = 4;
      for (const d of cands) {
        const diff = d.scrollHeight - d.clientHeight;
        if (diff > best) { best = diff; sc = d; }
      }
      if (!sc) return;
      wrap = document.createElement('div');
      wrap.setAttribute('data-scrollwrap', '');
      while (sc.firstChild) wrap.appendChild(sc.firstChild);
      sc.appendChild(wrap);
      sc.style.overflow = 'hidden';
    }

    const max = Math.max(0, wrap.scrollHeight - sc.clientHeight);
    const off = interpolate(keys.map(k => k.t), keys.map(k => k.v * max), Easing.easeInOutCubic)(time);
    wrap.style.transform = 'translateY(' + (-off) + 'px)';
  });
}

/* ── Cursore touch (cerchio morbido + ripple sul tap) ── */
function TouchCursor({ x, y, tap = 0 }) {
  return (
    <div style={{ position: 'absolute', left: x, top: y, transform: 'translate(-50%,-50%)', zIndex: 60, pointerEvents: 'none' }}>
      {tap > 0 && tap < 1 && (
        <div style={{
          position: 'absolute', left: '50%', top: '50%', width: 56, height: 56,
          marginLeft: -28, marginTop: -28, borderRadius: '50%',
          border: '3px solid rgba(249,115,22,.55)',
          transform: `scale(${0.4 + tap * 1.5})`, opacity: 1 - tap,
        }}/>
      )}
      <div style={{
        width: 30, height: 30, borderRadius: '50%',
        background: 'rgba(249,115,22,.22)', border: '2.5px solid rgba(249,115,22,.95)',
        boxShadow: '0 3px 10px rgba(15,23,42,.28)',
        transform: `scale(${tap > 0 && tap < 1 ? 0.86 : 1})`, transition: 'transform .08s',
      }}/>
    </div>
  );
}

/* ── Caption pill (crossfade per finestre temporali) ── */
function Caption({ time, list }) {
  let cur = null;
  for (const c of list) if (time >= c.s && time <= c.e) cur = c;
  if (!cur) return null;
  const fin = Easing.easeOutCubic(clamp((time - cur.s) / 0.35, 0, 1));
  const fout = 1 - Easing.easeInQuad(clamp((time - (cur.e - 0.35)) / 0.35, 0, 1));
  const op = Math.max(0, Math.min(fin, fout));
  return (
    <div style={{ position: 'absolute', left: 14, right: 14, bottom: 30, display: 'flex', justifyContent: 'center', pointerEvents: 'none', zIndex: 55 }}>
      <div style={{
        background: 'rgba(15,23,42,.94)', color: '#fff',
        padding: '11px 18px', borderRadius: 14,
        fontFamily: "'DM Sans', sans-serif", fontWeight: 600, fontSize: 14.5, lineHeight: 1.35,
        letterSpacing: '-.01em', textAlign: 'center', maxWidth: 310,
        opacity: op, transform: `translateY(${(1 - op) * 10}px)`,
        boxShadow: '0 10px 30px rgba(0,0,0,.4)',
        backdropFilter: 'blur(2px)',
      }}>{cur.text}</div>
    </div>
  );
}

/* ── Frame del telefono con schermata reale + slot overlay ── */
function DeviceScene({ hostRef, screen, children }) {
  return (
    <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
      <IOSDevice width={DEVICE_W} height={DEVICE_H}>
        <div style={{ position: 'relative', height: '100%', paddingTop: 47, paddingBottom: 16, boxSizing: 'border-box', display: 'flex', flexDirection: 'column' }}>
          <div ref={hostRef} style={{ flex: 1, display: 'flex', flexDirection: 'column', minHeight: 0, position: 'relative' }}>
            {screen}
            <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none', zIndex: 40, overflow: 'hidden' }}>
              {children}
            </div>
          </div>
        </div>
      </IOSDevice>
    </div>
  );
}

/* Overlay che usa il tempo: scroll + cursore + caption + extra */
function Presenter({ hostRef, scroll, captions = [], cursor = null, extra = null }) {
  const time = useTime();
  useScrollDrive(hostRef, scroll);

  let cz = null;
  if (cursor) {
    const x = trackField(time, cursor.path, 'x');
    const y = trackField(time, cursor.path, 'y');
    let tap = 0;
    for (const w of (cursor.taps || [])) if (time >= w[0] && time <= w[1]) tap = clamp((time - w[0]) / (w[1] - w[0]), 0, 1);
    cz = <TouchCursor x={x} y={y} tap={tap}/>;
  }

  return (
    <>
      {extra && extra(time)}
      {cz}
      <Caption time={time} list={captions}/>
    </>
  );
}

/* ════════════════ SCENE — config dati condivise (player + embed sito) */
const proponeToast = (t) => {
  if (t < 3.9) return null;
  const k = Easing.easeOutBack(clamp((t - 3.9) / 0.5, 0, 1));
  const op = clamp((t - 3.9) / 0.3, 0, 1);
  return (
    <div style={{ position: 'absolute', inset: 0, opacity: op, transform: `translateY(${(1 - k) * 40}px)` }}>
      <Toast text="Fatto. La squadra è aggiornata per domani." action="Annulla"/>
    </div>
  );
};

/* Storia meteo: planner REALE (chip meteo sui cantieri) → crossfade su
   Notifiche REALE (pioggia → Bruno propone → confermi). Nessuna UI inventata. */
function MeteoStory() {
  const time = useTime();
  const k = Easing.easeInOutCubic(clamp((time - 3.4) / 0.6, 0, 1));
  return (
    <div style={{position:'relative',height:'100%'}}>
      <div style={{position:'absolute',inset:0,opacity:1-k,display:'flex',flexDirection:'column'}}><AnimPlanner/></div>
      {k > 0 && <div style={{position:'absolute',inset:0,opacity:k,display:'flex',flexDirection:'column'}}><AnimNotifications/></div>}
    </div>
  );
}

const meteoToast = (t) => {
  if (t < 6.1) return null;
  const k = Easing.easeOutBack(clamp((t - 6.1) / 0.5, 0, 1));
  const op = clamp((t - 6.1) / 0.3, 0, 1);
  return (
    <div style={{ position: 'absolute', inset: 0, opacity: op, transform: `translateY(${(1 - k) * 40}px)` }}>
      <Toast text="Fatto. La squadra è aggiornata per domani." action="Annulla"/>
    </div>
  );
};

const SCENES = {
  planner: {
    duration: 8.0,
    screen: () => <AnimPlanner/>,
    scroll: [{t:0,v:0},{t:1.2,v:0},{t:3.4,v:.34},{t:5.4,v:.7},{t:6.9,v:1},{t:8,v:1}],
    captions: [
      { s: 0.25, e: 2.7, text: 'Tutti i cantieri in una schermata' },
      { s: 2.9, e: 5.1, text: 'Chi è dove — oggi e tutta la settimana' },
      { s: 5.3, e: 7.9, text: 'I non assegnati li metti dove servono' },
    ],
  },
  notifs: {
    duration: 8.0,
    screen: () => <AnimNotifications/>,
    scroll: [{t:0,v:0},{t:8,v:0}],
    cursor: {
      path: [{t:0,x:240,y:520},{t:2.0,x:240,y:520},{t:3.0,x:138,y:392},{t:3.8,x:138,y:392},{t:5.2,x:185,y:470}],
      taps: [[3.2, 3.8]],
    },
    captions: [
      { s: 0.25, e: 2.9, text: 'Domani pioggia su Naturasì → Bruno propone' },
      { s: 4.3, e: 7.8, text: 'Bruno propone, tu confermi. Un tocco.' },
    ],
    extra: proponeToast,
  },
  bacheca: {
    duration: 8.5,
    screen: () => <AnimBacheca/>,
    scroll: [{t:0,v:0},{t:1.2,v:0},{t:3.2,v:.4},{t:5.4,v:.75},{t:7,v:1},{t:8.5,v:1}],
    captions: [
      { s: 0.25, e: 2.7, text: 'Saldo ferie, permessi e ROL' },
      { s: 2.9, e: 5.1, text: 'Buste paga e nota spese, sempre con te' },
      { s: 5.3, e: 8.4, text: 'Foglio ore pronto da scaricare' },
    ],
  },
  anagrafiche: {
    duration: 9.5,
    screen: () => <AnimPlanner/>,
    scroll: [{t:0,v:0},{t:1.4,v:0},{t:3.0,v:.52},{t:4.6,v:.52},{t:6.2,v:1},{t:9.5,v:1}],
    captions: [
      { s: 0.3, e: 2.8, text: "L'anagrafica la carichiamo noi: persone, mezzi, cantieri" },
      { s: 3.2, e: 5.8, text: 'Squadra e mezzi di ogni cantiere — dal tuo Excel' },
      { s: 6.4, e: 9.3, text: 'Ruoli e disponibilità, pronti da assegnare' },
    ],
  },
  setup: {
    duration: 11.0,
    screen: () => <AnimSetupCantiere/>,
    cursor: {
      path: [
        {t:0,x:280,y:560},{t:0.5,x:338,y:685},{t:1.3,x:338,y:685},
        {t:1.9,x:120,y:285},{t:2.9,x:130,y:350},{t:3.9,x:120,y:415},
        {t:4.6,x:150,y:475},{t:5.3,x:140,y:540},{t:6.2,x:160,y:600},
        {t:7.0,x:200,y:695},{t:7.9,x:200,y:695},{t:8.5,x:330,y:700},{t:11,x:330,y:700},
      ],
      taps: [[0.6, 1.05],[7.3, 7.75]],
    },
    captions: [
      { s: 0.2, e: 1.5, text: 'Un cantiere nuovo? Un tap.' },
      { s: 1.8, e: 4.3, text: 'Nome, indirizzo, cliente — scrivi e basta' },
      { s: 4.6, e: 7.0, text: "Date, squadra e mezzo in un'unica scheda" },
      { s: 8.4, e: 10.7, text: 'Fatto: già nel programma di lunedì' },
    ],
  },
  meteo: {
    duration: 9.5,
    screen: () => <MeteoStory/>,
    scroll: [{t:0,v:0},{t:1.0,v:0},{t:2.4,v:.3},{t:9.5,v:.3}],
    cursor: {
      path: [
        {t:0,x:325,y:600},{t:4.2,x:325,y:600},
        {t:5.0,x:138,y:392},{t:6.2,x:138,y:392},{t:6.9,x:185,y:470},{t:9.5,x:185,y:470},
      ],
      taps: [[5.3, 5.9]],
    },
    captions: [
      { s: 0.3, e: 3.0, text: 'Ogni cantiere ha il suo meteo, controllato ogni sera' },
      { s: 3.8, e: 5.1, text: 'Pioggia in arrivo → Bruno propone lo spostamento' },
      { s: 6.5, e: 9.3, text: 'Tu confermi. La squadra è già avvisata' },
    ],
    extra: meteoToast,
  },
};

/* Render di una scena (schermata reale + presentatore) — usato da player ed embed */
function SceneView({ id }) {
  const cfg = SCENES[id] || SCENES.planner;
  const hostRef = React.useRef();
  const screen = React.useMemo(() => cfg.screen(), [id]);
  return (
    <DeviceScene hostRef={hostRef} screen={screen}>
      <Presenter
        hostRef={hostRef}
        scroll={cfg.scroll}
        captions={cfg.captions}
        cursor={cfg.cursor}
        extra={cfg.extra}
      />
    </DeviceScene>
  );
}

/* Wrapper di compatibilità per il player */
function PlannerTour()  { return <SceneView id="planner"/>; }
function ProponeDemo()  { return <SceneView id="notifs"/>; }
function BachecaTour()  { return <SceneView id="bacheca"/>; }
function AnagraficheTour() { return <SceneView id="anagrafiche"/>; }
function SetupTour()       { return <SceneView id="setup"/>; }
function MeteoTour()       { return <SceneView id="meteo"/>; }

Object.assign(window, {
  DeviceScene, Presenter, TouchCursor, Caption, useScrollDrive,
  SCENES, SceneView,
  PlannerTour, ProponeDemo, BachecaTour,
  AnagraficheTour, SetupTour, MeteoTour,
  DEVICE_W, DEVICE_H,
});
