/* avdirector.jsx — drives the screen recording: derives UI state, camera
   (Screen-Studio-style zoom/follow) and cursor from the timeline clock. */

const T = {
  sel: [2.0, 2.7, 3.4, 4.1],
  toActions: 5.0,
  actionsClick: 6.2,
  menuOpen: 6.4,
  exportClick: 7.8,
  modalOpen: 8.0,
  startClick: 10.2,
  exportStart: 10.55,
  done: 12.6,
  slideCut: 13.2,
  end: 15.0,
};

const ease = Easing.easeInOutCubic;

// camera keyframes
const CAM_T = [0, 1.6, 2.0, 2.7, 3.4, 4.1, 5.0, 6.2, 6.6, 7.8, 8.0, 10.2, 10.55, 11.2, 12.6, 13.2];
const CAM_X = [940, 760, 430, 604, 960, 1316, 960, 960, 960, 960, 960, 1080, 1110, 1420, 1450, 960];
const CAM_Y = [560, 430, 500, 500, 500, 500, 320, 250, 330, 360, 540, 720, 745, 825, 832, 540];
const CAM_Z = [1.04, 1.12, 1.22, 1.22, 1.22, 1.22, 1.16, 1.42, 1.46, 1.5, 1.18, 1.4, 1.4, 1.2, 1.24, 1.0];

// cursor keyframes (tip position, screen coords)
const CUR_T = [0, 1.7, 2.0, 2.7, 3.4, 4.1, 5.6, 6.2, 7.2, 7.8, 8.0, 9.6, 10.2, 11.4, 13.0];
const CUR_X = [1500, 248, 248, 604, 960, 1316, 960, 960, 960, 960, 960, 1150, 1150, 1520, 1540];
const CUR_Y = [920, 460, 460, 470, 470, 470, 230, 196, 312, 312, 312, 808, 808, 900, 920];

const camX = interpolate(CAM_T, CAM_X, ease);
const camY = interpolate(CAM_T, CAM_Y, ease);
const camZ = interpolate(CAM_T, CAM_Z, ease);
const curX = interpolate(CUR_T, CUR_X, ease);
const curY = interpolate(CUR_T, CUR_Y, ease);

const CLICKS = [
  { t: T.sel[0], x: 248, y: 460 },
  { t: T.sel[1], x: 604, y: 470 },
  { t: T.sel[2], x: 960, y: 470 },
  { t: T.sel[3], x: 1316, y: 470 },
  { t: T.actionsClick, x: 960, y: 196 },
  { t: T.exportClick, x: 960, y: 312 },
  { t: T.startClick, x: 1150, y: 808 },
];

function Cursor({ x, y, zoom, scale }) {
  return (
    <div style={{ position: 'absolute', left: x, top: y, transformOrigin: '0 0', transform: `scale(${scale / zoom})`, zIndex: 200, pointerEvents: 'none' }}>
      <svg width="30" height="30" viewBox="0 0 24 24" fill="none" style={{ filter: 'drop-shadow(0 2px 3px rgba(0,0,0,0.35))' }}>
        <path d="M5 3l13 8-5.5 1.2L10 18z" fill="#fff" stroke="#111" strokeWidth="1.3" strokeLinejoin="round" />
      </svg>
    </div>
  );
}

function ClickRing({ click, time, zoom }) {
  const age = time - click.t;
  if (age < 0 || age > 0.45) return null;
  const p = age / 0.45;
  const r = 8 + 34 * Easing.easeOutCubic(p);
  return (
    <div style={{ position: 'absolute', left: click.x, top: click.y, transformOrigin: 'center', transform: `translate(-50%,-50%) scale(${1 / zoom})`, zIndex: 199, pointerEvents: 'none' }}>
      <div style={{ width: r * 2, height: r * 2, marginLeft: -r, marginTop: -r, borderRadius: '50%', border: '3px solid rgba(44,123,229,0.9)', opacity: 1 - p }} />
    </div>
  );
}

function Director() {
  const t = useTime();

  // selections
  const selected = [];
  T.sel.forEach((st, i) => { if (t >= st) selected.push(i); });
  const count = selected.length;

  // actions button spring + pulse
  const actionsScale = count > 0 ? animate({ from: 0, to: 1, start: T.sel[0], end: T.sel[0] + 0.42, ease: Easing.easeOutBack })(t) : 0;
  const pulsing = t > T.sel[0] && t < T.actionsClick;
  const actionsPulse = pulsing ? 1 + 0.035 * (0.5 + 0.5 * Math.sin(t * 6.5)) : 1;

  // menu
  const menuUp = clamp((t - T.actionsClick) / 0.22, 0, 1);
  const menuDown = 1 - clamp((t - (T.exportClick - 0.02)) / 0.18, 0, 1);
  const menu = Math.max(0, Math.min(menuUp, menuDown)) * (t < T.modalOpen ? 1 : 0);
  const menuHi = t >= 7.3 && t < T.exportClick + 0.05;

  // modal
  const modalUp = clamp((t - T.modalOpen) / 0.3, 0, 1);
  const modalDown = 1 - clamp((t - (T.startClick + 0.12)) / 0.22, 0, 1);
  const modal = Math.max(0, Math.min(modalUp, modalDown));
  const startHi = t >= 9.8 && t < T.startClick + 0.05;

  // toast + progress
  const toast = t >= T.exportStart && t < T.slideCut ? clamp((t - T.exportStart) / 0.3, 0, 1) : 0;
  const progress = clamp((t - (T.exportStart + 0.15)) / (T.done - (T.exportStart + 0.15)), 0, 1);
  const progEased = Easing.easeInOutSine(progress);

  const s = { selected, count, actionsScale, actionsPulse, menu, menuHi, modal, startHi, toast, progress: progEased };

  // camera
  const cx = camX(t), cy = camY(t), zoom = camZ(t);
  const showSlide = t >= T.slideCut;
  const camTransform = `translate(960px,540px) scale(${zoom}) translate(${-cx}px,${-cy}px)`;

  // cursor press dip
  let dip = 1;
  CLICKS.forEach((c) => { const a = t - c.t; if (a >= -0.06 && a <= 0.1) dip = Math.min(dip, 0.82); });

  const kb = clamp((t - T.slideCut) / 1.8, 0, 1);

  return (
    <div style={{ position: 'absolute', inset: 0, transformOrigin: '0 0', transform: camTransform }}>
      {showSlide ? <OutputSlide kb={kb} /> : <AVScreen s={s} />}
      {!showSlide && CLICKS.map((c, i) => <ClickRing key={i} click={c} time={t} zoom={zoom} />)}
      {!showSlide && <Cursor x={curX(t)} y={curY(t)} zoom={zoom} scale={dip} />}
    </div>
  );
}

Object.assign(window, { Director });
