/**
 * Download API Route
 * Handles social media video download requests
 *
 * Supports:
 * - YouTube: MP4 video, MP3 audio
 * - Instagram: Video/Image
 * - TikTok: Video
 * - Twitter/X: Video
 * - Facebook: Video
 */

import { NextRequest, NextResponse } from "next/server";
import { validateUrl } from "@/lib/security/url-validator";
import { withRateLimit } from "@/lib/security/rate-limiter";
import { detectPlatform } from "@/lib/download/platform-detector";
import { fetchVideo, fetchYoutubeAudio, fetchYoutubeVideo } from "@/lib/download/downloader";
import { DownloadRequest, DownloadResponse } from "@/types/download";

/**
 * POST /api/download
 * Downloads a social media video
 */
export async function POST(
  request: NextRequest,
): Promise<NextResponse<DownloadResponse>> {
  console.log("========== DOWNLOAD API START ==========");
  
  try {
    // 1. Rate limiting check
    console.log("[1] Checking rate limit...");
    const rateLimitResult = withRateLimit(request);
    if (!rateLimitResult.success) {
      console.log("[1] Rate limit exceeded:", rateLimitResult.error);
      return NextResponse.json(
        {
          success: false,
          error: {
            code: "RATE_LIMITED",
            message: rateLimitResult.error,
          },
        },
        {
          status: 429,
          headers: {
            "Retry-After": rateLimitResult.retryAfter.toString(),
          },
        },
      );
    }
    console.log("[1] Rate limit passed");

    // 2. Parse request body
    console.log("[2] Parsing request body...");
    let body: DownloadRequest;
    try {
      body = await request.json();
      console.log("[2] Request body:", JSON.stringify(body, null, 2));
    } catch (parseError) {
      console.log("[2] Failed to parse body:", parseError);
      return NextResponse.json(
        {
          success: false,
          error: {
            code: "INVALID_BODY",
            message: "Invalid request body",
          },
        },
        { status: 400 },
      );
    }

    // 3. Validate URL
    console.log("[3] Validating URL:", body.url);
    const validation = validateUrl(body.url);
    console.log("[3] Validation result:", JSON.stringify(validation, null, 2));
    
    if (!validation.valid) {
      console.log("[3] URL validation failed:", validation.error);
      return NextResponse.json(
        {
          success: false,
          error: {
            code: "INVALID_URL",
            message: validation.error || "Invalid URL",
          },
        },
        { status: 400 },
      );
    }
    console.log("[3] URL is valid, sanitized:", validation.sanitizedUrl);

    // 4. Detect platform
    console.log("[4] Detecting platform...");
    const platformResult = detectPlatform(validation.sanitizedUrl!);
    console.log("[4] Platform detected:", JSON.stringify(platformResult, null, 2));
    
    if (platformResult.platform === "unknown") {
      console.log("[4] Unknown platform");
      return NextResponse.json(
        {
          success: false,
          error: {
            code: "UNSUPPORTED_PLATFORM",
            message:
              "Unsupported platform. Supported: YouTube, Instagram, TikTok, Twitter/X, Facebook",
          },
        },
        { status: 400 },
      );
    }

    // 5. Fetch video/media using appropriate downloader
    console.log("[5] Fetching media...");
    console.log("[5] Sending URL:", validation.sanitizedUrl);
    console.log("[5] Platform:", platformResult.platform);
    console.log("[5] Audio format requested:", body.audioFormat);
    
    let downloadResponse: DownloadResponse;
    
    // YouTube: Support both MP4 video and MP3 audio with quality options
    if (platformResult.platform === "youtube") {
      // If audioFormat is specified, download as MP3 audio
      if (body.audioFormat) {
        console.log("[5] Downloading YouTube audio (MP3)...");
        console.log("[5] Audio bitrate:", body.audioBitrate);
        downloadResponse = await fetchYoutubeAudio(validation.sanitizedUrl!, body.audioBitrate);
      } else {
        console.log("[5] Downloading YouTube video (MP4)...");
        console.log("[5] Video quality:", body.quality);
        downloadResponse = await fetchYoutubeVideo(validation.sanitizedUrl!, body.quality);
      }
    } else {
      // Other platforms: Use default fetchVideo
      downloadResponse = await fetchVideo({
        url: validation.sanitizedUrl!,
        quality: body.quality,
      });
    }
    
    console.log("[5] Download response:", JSON.stringify(downloadResponse, null, 2));

    // 6. Handle errors
    if (!downloadResponse.success || downloadResponse.error) {
      console.log("[6] Download failed:", downloadResponse.error);
      return NextResponse.json(
        {
          success: false,
          error: downloadResponse.error || {
            code: "DOWNLOAD_FAILED",
            message: "Failed to download video",
          },
        },
        { status: 400 },
      );
    }

    // 7. Return success response
    console.log("[7] Success! Returning download URL");
    console.log("========== DOWNLOAD API END (SUCCESS) ==========");
    
    return NextResponse.json({
      success: true,
      data: downloadResponse.data,
    });
  } catch (error) {
    console.error("========== DOWNLOAD API ERROR ==========");
    console.error("Error type:", error?.constructor?.name);
    console.error("Error message:", error instanceof Error ? error.message : String(error));
    console.error("Error stack:", error instanceof Error ? error.stack : "No stack trace");
    console.error("=========================================");
    
    return NextResponse.json(
      {
        success: false,
        error: {
          code: "INTERNAL_ERROR",
          message: error instanceof Error ? error.message : "An unexpected error occurred",
        },
      },
      { status: 500 },
    );
  }
}
