import { type NextRequest, NextResponse } from "next/server"
import { sql, safeQuery } from "@/lib/db"
import { createHash } from "crypto"
import { streamRateLimit } from "@/lib/rate-limit"

export const runtime = "nodejs"

// Stream audio from Vercel Blob storage
export async function GET(request: NextRequest, { params }: { params: Promise<{ trackId: string }> }) {
  try {
    const { trackId } = await params

    const clientIp = request.headers.get("x-forwarded-for") || request.headers.get("x-real-ip") || "anonymous"
    const rateLimitResult = await streamRateLimit(clientIp)

    if (!rateLimitResult.allowed) {
      console.log(`[Stream] Rate limit exceeded for IP: ${clientIp}`)
      return new NextResponse("Too many stream requests", { status: 429 })
    }

    const rangeHeader = request.headers.get("range")

    console.log(`[Stream] Request for track ${trackId}, Range: ${rangeHeader || "full"}`)

    const dbUrl = process.env.DATABASE_URL || process.env.POSTGRES_URL
    if (!dbUrl) {
      console.log("[Stream] Database not configured - cannot stream track")
      return new NextResponse("Database not configured", { status: 503 })
    }

    // Get track info
    const tracks = await safeQuery<{ audio_url: string }>`
      SELECT audio_url FROM tracks WHERE id = ${trackId} AND is_playable = true
    `

    if (tracks.length === 0 || !tracks[0].audio_url) {
      console.log(`[Stream] Track not found or not playable: ${trackId}`)
      return new NextResponse("Track not found", { status: 404 })
    }

    const audioUrl = tracks[0].audio_url
    console.log(`[Stream] Track audio URL: ${audioUrl}`)

    // For Vercel Blob URLs, redirect to the blob URL directly
    // The blob URL already supports range requests
    const headers: Record<string, string> = {
      "Cache-Control": "public, max-age=31536000, immutable",
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "GET, HEAD, OPTIONS",
      "Access-Control-Allow-Headers": "Range, Content-Type",
    }

    // Redirect to the actual audio URL
    return NextResponse.redirect(audioUrl, { headers })
  } catch (error) {
    console.error("[Stream] Error:", error)
    return new NextResponse("Internal error", { status: 500 })
  }
}

// Verify streaming token (called by CDN/proxy)
export async function POST(request: NextRequest, { params }: { params: Promise<{ trackId: string }> }) {
  try {
    const { trackId } = await params
    const { token, signature } = await request.json()

    if (!token || !signature) {
      return NextResponse.json({ error: "Token ou signature manquant" }, { status: 400 })
    }

    // Verify token exists and hasn't expired
    const tokens = await sql`
      SELECT st.*, t.audio_url, t.audio_url_low, t.audio_url_normal, t.audio_url_high, t.audio_url_very_high
      FROM stream_tokens st
      JOIN tracks t ON st.track_id = t.id
      WHERE st.token = ${token} 
        AND st.track_id = ${trackId}
        AND st.expires_at > NOW()
    `

    if (tokens.length === 0) {
      return NextResponse.json({ error: "Token invalide ou expiré" }, { status: 403 })
    }

    const streamToken = tokens[0]

    // Verify signature
    const expectedSignature = createHash("sha256")
      .update(
        `${trackId}:${token}:${new Date(streamToken.expires_at).getTime()}:${process.env.STREAM_SECRET || "default-secret"}`,
      )
      .digest("hex")

    if (signature !== expectedSignature) {
      return NextResponse.json({ error: "Signature invalide" }, { status: 403 })
    }

    // Select audio URL based on quality
    let audioUrl = streamToken.audio_url
    switch (streamToken.quality) {
      case "low":
        audioUrl = streamToken.audio_url_low || streamToken.audio_url_normal || streamToken.audio_url
        break
      case "normal":
        audioUrl = streamToken.audio_url_normal || streamToken.audio_url
        break
      case "high":
        audioUrl = streamToken.audio_url_high || streamToken.audio_url
        break
      case "very_high":
        audioUrl = streamToken.audio_url_very_high || streamToken.audio_url_high || streamToken.audio_url
        break
    }

    return NextResponse.json({
      valid: true,
      audioUrl,
      quality: streamToken.quality,
    })
  } catch (error) {
    console.error("Token verification error:", error)
    return NextResponse.json({ error: "Erreur de vérification du token" }, { status: 500 })
  }
}

export async function OPTIONS() {
  return new NextResponse(null, {
    status: 204,
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "GET, HEAD, OPTIONS",
      "Access-Control-Allow-Headers": "Range, Content-Type",
    },
  })
}
