import path from 'path';
import fs from 'fs';
import { fileURLToPath } from 'url';
import sqlite3 from 'sqlite3';
import { open } from 'sqlite';
import { spawn } from 'child_process';

// Find ffmpeg binary
const FFMPEG = ['/opt/homebrew/bin/ffmpeg', '/usr/bin/ffmpeg'].find(p => fs.existsSync(p)) || 'ffmpeg';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const mediaDir = path.join(__dirname, '..', 'public', 'media');

const transcodeToMp4 = (inputPath, outputPath) => new Promise((resolve, reject) => {
  const args = [
    '-y',
    '-i', inputPath,
    '-vf', 'scale=trunc(iw/2)*2:trunc(ih/2)*2',
    '-c:v', 'libx264',
    '-profile:v', 'baseline',
    '-level', '3.0',
    '-pix_fmt', 'yuv420p',
    '-c:a', 'aac',
    '-b:a', '128k',
    '-movflags', '+faststart',
    outputPath
  ];

  const ffmpeg = spawn(FFMPEG, args, { stdio: 'ignore' });
  ffmpeg.on('error', reject);
  ffmpeg.on('close', (code) => {
    if (code === 0) {
      resolve();
    } else {
      reject(new Error(`ffmpeg exited with code ${code}`));
    }
  });
});

const toMediaPath = (filename) => `/media/${filename}`;

async function run() {
  const db = await open({
    filename: path.join(__dirname, 'signsync.db'),
    driver: sqlite3.Database
  });

  const addColumnIfMissing = async (columnDef) => {
    try {
      await db.exec(`ALTER TABLE recordings ADD COLUMN ${columnDef}`);
    } catch (error) {
      if (!String(error.message).toLowerCase().includes('duplicate column')) {
        console.error('Error adding column:', error);
      }
    }
  };

  await addColumnIfMissing('recorded_video_processing INTEGER DEFAULT 0');
  await addColumnIfMissing('recorded_video_processing_2 INTEGER DEFAULT 0');

  const rows = await db.all('SELECT id, recorded_video_path, recorded_video_path_2 FROM recordings');

  for (const row of rows) {
    const updates = {};

    for (const key of ['recorded_video_path', 'recorded_video_path_2']) {
      const currentPath = row[key];
      if (!currentPath || !currentPath.endsWith('.webm')) continue;

      const inputPath = path.join(mediaDir, path.basename(currentPath));
      if (!fs.existsSync(inputPath)) {
        console.warn(`Missing file for ${key} on row ${row.id}: ${inputPath}`);
        continue;
      }

      const outputPath = inputPath.replace(/\.webm$/i, '.mp4');
      if (!fs.existsSync(outputPath)) {
        console.log(`Transcoding ${inputPath} -> ${outputPath}`);
        await transcodeToMp4(inputPath, outputPath);
      }

      updates[key] = toMediaPath(path.basename(outputPath));
      fs.unlinkSync(inputPath);
    }

    if (Object.keys(updates).length > 0) {
      await db.run(
        `UPDATE recordings
         SET recorded_video_path = COALESCE(?, recorded_video_path),
             recorded_video_path_2 = COALESCE(?, recorded_video_path_2),
             recorded_video_processing = 0,
             recorded_video_processing_2 = 0
         WHERE id = ?`,
        [updates.recorded_video_path || null, updates.recorded_video_path_2 || null, row.id]
      );
    }
  }

  await db.close();
  console.log('Conversion complete.');
}

run().catch((err) => {
  console.error(err);
  process.exit(1);
});
