// app/api/admin/upload/finalize/route.ts
import { NextResponse } from "next/server";
import fs from "fs";
import path from "path";
import { spawn } from "child_process";
import { prisma } from "@/lib/prisma";
import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth-options";

const UPLOADS_DIR = process.env.UPLOADS_DIR || "/uploads";

async function getVideoDurationFromFile(filePath: string): Promise<number | null> {
  return new Promise((resolve) => {
    try {
      const ffprobe = spawn("ffprobe", [
        "-v", "error",
        "-show_entries", "format=duration",
        "-of", "default=noprint_wrappers=1:nokey=1:nokey=1",
        filePath,
      ]);

      let output = "";
      let timedOut = false;

      const timeoutId = setTimeout(() => {
        timedOut = true;
        ffprobe.kill();
        resolve(null);
      }, 30000);

      ffprobe.stdout.on("data", (data) => {
        output += data.toString();
      });

      ffprobe.on("close", (code) => {
        clearTimeout(timeoutId);
        if (!timedOut && code === 0) {
          const duration = parseFloat(output.trim());
          if (!isNaN(duration) && isFinite(duration) && duration > 0) {
            resolve(Math.round(duration));
          } else {
            resolve(null);
          }
        } else {
          resolve(null);
        }
      });

      ffprobe.on("error", () => {
        clearTimeout(timeoutId);
        resolve(null);
      });
    } catch (err) {
      resolve(null);
    }
  });
}

async function checkAdmin() {
  const session = await getServerSession(authOptions);
  if (!session?.user?.email) throw { status: 401, message: "Unauthorized" };
  const allowed = (process.env.ALLOWED_ADMINS || "")
    .split(",")
    .map((s) => s.trim())
    .filter(Boolean);
  if (allowed.length && !allowed.includes(session.user.email))
    throw { status: 403, message: "Forbidden" };
  return session;
}

export async function POST(req: Request) {
  try {
    console.log('[Upload/Finalize] Request received');
    
    await checkAdmin();
    
    const body = await req.json();
    const { videoId } = body;
    
    if (!videoId) {
      return NextResponse.json({ error: "videoId required" }, { status: 400 });
    }
    
    console.log('[Upload/Finalize] Checking for video:', videoId);
    
    // Check if video exists in DB
    const video = await prisma.video.findUnique({
      where: { id: videoId },
    });
    
    if (!video) {
      return NextResponse.json({ error: "video not found" }, { status: 404 });
    }
    
    // Check if file exists at the expected path
    const videoPath = path.join(UPLOADS_DIR, "videos", `${videoId}.mp4`);
    console.log('[Upload/Finalize] Checking file at:', videoPath);
    
    try {
      await fs.promises.access(videoPath, fs.constants.F_OK);
    } catch {
      return NextResponse.json(
        { error: `File not found at ${videoPath}. Please copy the file there first.` },
        { status: 404 }
      );
    }
    
    console.log('[Upload/Finalize] File found, extracting duration');
    
    // Extract duration if not already set
    let durationSec = video.durationSec;
    if (!durationSec) {
      try {
        const extractedDuration = await getVideoDurationFromFile(videoPath);
        if (extractedDuration !== null) {
          durationSec = extractedDuration;
          console.log('[Upload/Finalize] Extracted duration:', durationSec);
        } else {
          console.warn('[Upload/Finalize] Could not extract duration');
        }
      } catch (err) {
        console.warn('[Upload/Finalize] Duration extraction error:', err);
      }
    }
    
    // Update video: set URL, duration, and transcoding status to trigger processing
    const videoUrl = `/uploads/videos/${videoId}.mp4`;
    const updatedVideo = await prisma.video.update({
      where: { id: videoId },
      data: {
        url: videoUrl,
        transcodingStatus: 'uploaded', // Mark as ready for transcoding
        ...(durationSec !== null && { durationSec }),
      },
    });
    
    console.log('[Upload/Finalize] Video updated successfully with URL:', videoUrl);
    
    return NextResponse.json({
      success: true,
      video: updatedVideo,
      message: `Video finalized${durationSec ? ` (${durationSec}s)` : ''}. HLS transcoding will start shortly.`,
    }, { status: 200 });
  } catch (err: any) {
    console.error("[Upload/Finalize] Error:", err);
    const status = err?.status ?? 500;
    const message = err?.message ?? "server error";
    return NextResponse.json({ error: message }, { status });
  }
}
