import puppeteer from 'puppeteer';
import { execSync } from 'child_process';
import { mkdirSync, rmSync, existsSync } from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const FRAMES_DIR = path.join(__dirname, 'frames');
const OUTPUT = path.join(__dirname, 'banner-loop.mp4');
const HTML_PATH = path.join(__dirname, 'banner-mega.html');

const FPS = 30;
const DURATION = 20; // 20s = one full loop (covers 16s crossfade + 20s feature rotation)
const TOTAL_FRAMES = FPS * DURATION;

// Display: 1m x 2.5m → render at 1080 x 2700px (1:2.5)
const WIDTH = 1080;
const HEIGHT = 2700;

async function wait(ms) {
  return new Promise(r => setTimeout(r, ms));
}

async function main() {
  // Clean up old frames
  if (existsSync(FRAMES_DIR)) rmSync(FRAMES_DIR, { recursive: true });
  mkdirSync(FRAMES_DIR, { recursive: true });

  console.log(`Recording ${DURATION}s at ${FPS}fps → ${TOTAL_FRAMES} frames`);
  console.log(`Resolution: ${WIDTH}×${HEIGHT}`);

  const browser = await puppeteer.launch({
    headless: true,
    args: ['--no-sandbox', '--disable-setuid-sandbox']
  });

  const page = await browser.newPage();
  await page.setViewport({ width: WIDTH, height: HEIGHT, deviceScaleFactor: 1 });

  // Load the banner
  await page.goto(`file://${HTML_PATH}`, { waitUntil: 'networkidle0' });
  await wait(1000); // let animations initialize

  // Capture frames by advancing CSS animations
  // We override animation play state and manually seek time
  await page.evaluate(() => {
    // Pause all animations initially
    document.getAnimations().forEach(a => a.pause());
  });

  const msPerFrame = (DURATION * 1000) / TOTAL_FRAMES;

  for (let i = 0; i < TOTAL_FRAMES; i++) {
    const t = i * msPerFrame;

    // Set all animations to the correct time
    await page.evaluate((time) => {
      document.getAnimations().forEach(a => {
        a.currentTime = time;
      });
    }, t);

    // Small delay to let browser paint
    await wait(20);

    const frameNum = String(i).padStart(5, '0');
    await page.screenshot({
      path: path.join(FRAMES_DIR, `frame_${frameNum}.png`),
      type: 'png'
    });

    if (i % 60 === 0) {
      console.log(`  Frame ${i}/${TOTAL_FRAMES} (${Math.round(t/1000)}s)`);
    }
  }

  await browser.close();
  console.log('Screenshots done. Encoding video...');

  // Stitch frames into video with ffmpeg
  const ffmpegCmd = [
    'ffmpeg', '-y',
    '-framerate', String(FPS),
    '-i', path.join(FRAMES_DIR, 'frame_%05d.png'),
    '-c:v', 'libx264',
    '-preset', 'slow',
    '-crf', '18',
    '-pix_fmt', 'yuv420p',
    '-vf', 'scale=1080:2700',
    OUTPUT
  ].join(' ');

  console.log(`Running: ${ffmpegCmd}`);
  execSync(ffmpegCmd, { stdio: 'inherit' });

  // Clean up frames
  rmSync(FRAMES_DIR, { recursive: true });

  console.log(`\n✅ Done! Video saved to: ${OUTPUT}`);
  console.log(`   Duration: ${DURATION}s, ${WIDTH}×${HEIGHT}, ${FPS}fps`);
}

main().catch(e => { console.error(e); process.exit(1); });
