/**
 * Backfill HLS transcoding for existing videos.
 *
 * Finds every Video record that has never been queued for HLS (hlsStatus is
 * NULL) and is otherwise transcodable, then enqueues a transcode job for
 * each. Idempotent — re-runs only pick up still-NULL rows. Skips invalid or
 * zero-duration videos.
 *
 * Bypasses the ENABLE_HLS_TRANSCODE flag (calls forceSubmitTranscode)
 * because the flag is meant to gate the *upload-time* enqueue; once an
 * operator runs this script they're explicitly asking for transcoding.
 *
 * Usage:
 *   docker compose exec api tsx scripts/backfill-hls.ts
 *   # or after building:
 *   docker compose exec api node dist/scripts/backfill-hls.js
 */

import { prisma } from '../src/config/database';
import { hlsTranscodeQueueService } from '../src/services/hls-transcode-queue.service';
import { logger } from '../src/utils/logger';

async function main() {
  const candidates = await prisma.video.findMany({
    where: {
      hlsStatus: null,
      isValid: true,
      durationSeconds: { gt: 0 },
      width: { gt: 0 },
      height: { gt: 0 },
    },
    select: { id: true, filename: true, durationSeconds: true },
    orderBy: { id: 'asc' },
  });

  if (candidates.length === 0) {
    logger.info('[backfill-hls] No videos require HLS transcoding.');
    process.exit(0);
  }

  logger.info(`[backfill-hls] Enqueueing ${candidates.length} video(s) for HLS transcoding`);

  let enqueued = 0;
  for (const video of candidates) {
    try {
      const jobId = await hlsTranscodeQueueService.forceSubmitTranscode(video.id);
      enqueued++;
      logger.info(`[backfill-hls] Enqueued video ${video.id} (${video.filename}) → job ${jobId}`);
    } catch (err) {
      logger.error(`[backfill-hls] Failed to enqueue video ${video.id}: ${err instanceof Error ? err.message : String(err)}`);
    }
  }

  logger.info(`[backfill-hls] Done. ${enqueued}/${candidates.length} jobs enqueued. Worker concurrency is 1, so total wall time depends on per-video transcode duration (~2 min per 1080p video).`);

  // Give BullMQ a moment to flush, then exit cleanly.
  await new Promise((r) => setTimeout(r, 500));
  await hlsTranscodeQueueService.close();
  await prisma.$disconnect();
  process.exit(0);
}

main().catch(async (err) => {
  logger.error(`[backfill-hls] Fatal: ${err instanceof Error ? err.stack : String(err)}`);
  await prisma.$disconnect().catch(() => {});
  process.exit(1);
});
