import { corsHeaders, handleCors } from "../_shared/cors.ts";
import { verifyAdmin, AuthError } from "../_shared/auth.ts";
import { createServiceClient } from "../_shared/supabase-client.ts";
import { downloadAndUploadAudio } from "../_shared/youtube-client.ts";

Deno.serve(async (req: Request) => {
  // Handle CORS preflight
  const corsResponse = handleCors(req);
  if (corsResponse) return corsResponse;

  try {
    // Only accept POST
    if (req.method !== "POST") {
      return new Response(JSON.stringify({ error: "Method not allowed" }), {
        status: 405,
        headers: { ...corsHeaders, "Content-Type": "application/json" },
      });
    }

    // Verify admin auth
    await verifyAdmin(req);

    // Parse request body
    const { jobId } = await req.json();
    if (!jobId || typeof jobId !== "string") {
      return new Response(JSON.stringify({ error: "jobId is required" }), {
        status: 400,
        headers: { ...corsHeaders, "Content-Type": "application/json" },
      });
    }

    const supabase = createServiceClient();

    // Get the job
    const { data: job, error: jobError } = await supabase
      .from("download_jobs")
      .select("*")
      .eq("id", jobId)
      .single();

    if (jobError || !job) {
      return new Response(JSON.stringify({ error: "Job not found" }), {
        status: 404,
        headers: { ...corsHeaders, "Content-Type": "application/json" },
      });
    }

    // Get the next pending item
    const { data: item, error: itemError } = await supabase
      .from("download_items")
      .select("*")
      .eq("job_id", jobId)
      .eq("status", "pending")
      .order("created_at", { ascending: true })
      .limit(1)
      .single();

    // No pending items -- finalize the job
    if (itemError || !item) {
      const finalStatus =
        job.completed_items > 0 ? "completed" : "failed";

      await supabase
        .from("download_jobs")
        .update({ status: finalStatus })
        .eq("id", jobId);

      return new Response(
        JSON.stringify({
          status: finalStatus,
          progress: {
            completed: job.completed_items,
            failed: job.failed_items,
            total: job.total_items,
          },
          processedItem: null,
          done: true,
        }),
        {
          status: 200,
          headers: { ...corsHeaders, "Content-Type": "application/json" },
        }
      );
    }

    // Mark item as downloading, job as processing
    await Promise.all([
      supabase
        .from("download_items")
        .update({ status: "downloading" })
        .eq("id", item.id),
      supabase
        .from("download_jobs")
        .update({ status: "processing" })
        .eq("id", jobId),
    ]);

    try {
      // Download audio + upload to storage via the sidecar worker
      const { storagePath, publicUrl } = await downloadAndUploadAudio(
        item.video_id,
        jobId
      );

      // Mark item as completed
      await supabase
        .from("download_items")
        .update({
          status: "completed",
          storage_path: storagePath,
          public_url: publicUrl,
        })
        .eq("id", item.id);

      // Increment completed count on job
      await supabase
        .from("download_jobs")
        .update({
          completed_items: job.completed_items + 1,
        })
        .eq("id", jobId);

      return new Response(
        JSON.stringify({
          status: "processing",
          progress: {
            completed: job.completed_items + 1,
            failed: job.failed_items,
            total: job.total_items,
          },
          processedItem: {
            id: item.id,
            videoId: item.video_id,
            title: item.title,
            status: "completed",
            publicUrl,
            storagePath,
          },
          done: false,
        }),
        {
          status: 200,
          headers: { ...corsHeaders, "Content-Type": "application/json" },
        }
      );
    } catch (downloadError) {
      const errorMessage =
        downloadError instanceof Error
          ? downloadError.message
          : "Unknown download error";

      await supabase
        .from("download_items")
        .update({
          status: "failed",
          error_message: errorMessage,
        })
        .eq("id", item.id);

      await supabase
        .from("download_jobs")
        .update({
          failed_items: job.failed_items + 1,
        })
        .eq("id", jobId);

      return new Response(
        JSON.stringify({
          status: "processing",
          progress: {
            completed: job.completed_items,
            failed: job.failed_items + 1,
            total: job.total_items,
          },
          processedItem: {
            id: item.id,
            videoId: item.video_id,
            title: item.title,
            status: "failed",
            error: errorMessage,
          },
          done: false,
        }),
        {
          status: 200,
          headers: { ...corsHeaders, "Content-Type": "application/json" },
        }
      );
    }
  } catch (error) {
    const status = error instanceof AuthError ? error.status : 500;
    const message =
      error instanceof Error ? error.message : "Unknown error occurred";

    return new Response(JSON.stringify({ error: message }), {
      status,
      headers: { ...corsHeaders, "Content-Type": "application/json" },
    });
  }
});
