import type { NextRequest } from "next/server"
import { successResponse, errorResponse } from "@/lib/api-response"
import { createHash, createHmac } from "crypto"
import { uploadRateLimit } from "@/lib/rate-limit"

export const runtime = "nodejs"

const MAX_FILE_SIZE = 100 * 1024 * 1024 // 100MB
const ALLOWED_AUDIO_TYPES = ["audio/mpeg", "audio/mp3", "audio/wav", "audio/ogg", "audio/flac"]
const ALLOWED_IMAGE_TYPES = ["image/jpeg", "image/png", "image/webp", "image/jpg"]
const EXPIRATION_SECONDS = 300 // 5 minutes

function generateSignedUrl(
  accountId: string,
  bucketName: string,
  key: string,
  accessKeyId: string,
  secretAccessKey: string,
  expiresIn: number,
  contentType: string,
): string {
  const host = `${accountId}.r2.cloudflarestorage.com`
  const path = `/${bucketName}/${key}`
  const region = "auto"
  const service = "s3"

  const now = new Date()
  const amzDate = now.toISOString().replace(/[:-]|\.\d{3}/g, "")
  const dateStamp = amzDate.slice(0, 8)

  const credentialScope = `${dateStamp}/${region}/${service}/aws4_request`
  const credential = `${accessKeyId}/${credentialScope}`

  const queryParams = new URLSearchParams({
    "X-Amz-Algorithm": "AWS4-HMAC-SHA256",
    "X-Amz-Credential": credential,
    "X-Amz-Date": amzDate,
    "X-Amz-Expires": expiresIn.toString(),
    "X-Amz-SignedHeaders": "host",
  })

  const canonicalQueryString = queryParams.toString()

  const canonicalRequest = ["PUT", path, canonicalQueryString, `host:${host}\n`, "host", "UNSIGNED-PAYLOAD"].join("\n")

  const stringToSign = [
    "AWS4-HMAC-SHA256",
    amzDate,
    credentialScope,
    createHash("sha256").update(canonicalRequest).digest("hex"),
  ].join("\n")

  const kDate = createHmac("sha256", `AWS4${secretAccessKey}`).update(dateStamp).digest()
  const kRegion = createHmac("sha256", kDate).update(region).digest()
  const kService = createHmac("sha256", kRegion).update(service).digest()
  const kSigning = createHmac("sha256", kService).update("aws4_request").digest()
  const signature = createHmac("sha256", kSigning).update(stringToSign).digest("hex")

  return `https://${host}${path}?${canonicalQueryString}&X-Amz-Signature=${signature}`
}

export async function POST(request: NextRequest) {
  try {
    const clientIp = request.headers.get("x-forwarded-for") || request.headers.get("x-real-ip") || "anonymous"
    const rateLimitResult = await uploadRateLimit(clientIp)

    if (!rateLimitResult.allowed) {
      console.log(`[v0] [Sign] Rate limit exceeded for IP: ${clientIp}`)
      return errorResponse("Upload rate limit exceeded. Please wait before uploading again.", 429)
    }

    console.log(`[v0] [Sign] Processing signed URL request from IP: ${clientIp}`)

    const body = await request.json()
    const { filename, contentType, fileSize, fileType } = body

    if (!filename || !contentType || !fileSize) {
      console.log(`[v0] [Sign] Missing required fields`)
      return errorResponse("Missing required fields: filename, contentType, fileSize")
    }

    // Validate file size
    if (fileSize > MAX_FILE_SIZE) {
      console.log(`[v0] [Sign] File size ${fileSize} exceeds maximum ${MAX_FILE_SIZE}`)
      return errorResponse(`File size exceeds maximum of ${MAX_FILE_SIZE / 1024 / 1024}MB`)
    }

    // Validate content type
    const isAudio = ALLOWED_AUDIO_TYPES.includes(contentType)
    const isImage = ALLOWED_IMAGE_TYPES.includes(contentType)

    if (!isAudio && !isImage) {
      console.log(`[v0] [Sign] Invalid content type: ${contentType}`)
      return errorResponse("Invalid file type. Only audio and image files are allowed")
    }

    // Get R2 credentials
    const accountId = process.env.R2_ACCOUNT_ID
    const accessKeyId = process.env.R2_ACCESS_KEY_ID
    const secretAccessKey = process.env.R2_SECRET_ACCESS_KEY
    const bucketName = process.env.R2_BUCKET_NAME || "africa-music"

    if (!accountId || !accessKeyId || !secretAccessKey) {
      console.error("[v0] [Sign] R2 credentials not configured")
      return errorResponse("Storage service not configured", 503)
    }

    // Generate unique key
    const folder = isAudio ? "audio" : "images"
    const timestamp = Date.now()
    const randomString = Math.random().toString(36).substring(2, 15)
    const extension = filename.split(".").pop()
    const key = `${folder}/${timestamp}-${randomString}.${extension}`

    console.log(`[v0] [Sign] Generating signed URL for key: ${key}`)

    // Generate presigned URL
    const signedUrl = generateSignedUrl(
      accountId,
      bucketName,
      key,
      accessKeyId,
      secretAccessKey,
      EXPIRATION_SECONDS,
      contentType,
    )

    const publicUrl = `https://pub-382b9f268758437ab64616c1255565dd.r2.dev/${key}`

    console.log(`[v0] [Sign] Successfully generated signed URL. Public URL: ${publicUrl}`)

    return successResponse({
      signedUrl,
      publicUrl,
      key,
      expiresIn: EXPIRATION_SECONDS,
    })
  } catch (error) {
    console.error("[v0] [Sign] Error:", error)
    return errorResponse("Failed to generate signed URL", 500)
  }
}
