import { type NextRequest, NextResponse } from "next/server"

import { env } from "@/env/server"

import { warmup } from "@/services/warmup"
import { isWarmupKey } from "@/services/warmup/warmupKeys"
import { createLogger } from "@/utils/logger"

export const dynamic = "force-dynamic"

const logger = createLogger("Warmup")

export async function GET(req: NextRequest) {
  const url = new URL(req.url)
  const key = url.searchParams.get("key")

  if (!isAuthroized(req)) {
    return unauthorizedResponse()
  }

  const executionStart = performance.now()

  if (!isWarmupKey(key)) {
    return invalidKeyResponse(key)
  }

  logger.debug("Warming up:", key)
  const warmupResult = await warmup(key)
  const executionTime = performance.now() - executionStart

  switch (warmupResult.status) {
    case "completed":
      return warmupCompletedResponse(warmupResult, key, executionTime)
    case "error":
      return warmupErrorResponse(warmupResult, key, executionTime)
    case "skipped":
      return warmupSkippedResponse(warmupResult, key, executionTime)
    default:
      const status = (warmupResult as unknown as { status: string }).status
      throw new Error(`Unknown warmup status '${status}'`)
  }
}

function isAuthroized(req: NextRequest) {
  const authHeader = req.headers.get("Authorization")
  if (!authHeader || !env.WARMUP_TOKEN) {
    return false
  }

  const token = authHeader.split(" ")[1]
  if (!token) {
    return false
  }

  return token === env.WARMUP_TOKEN
}

function warmupCompletedResponse(
  warmupResult: Awaited<ReturnType<typeof warmup>>,
  key: string,
  executionTime: number
) {
  logger.debug(`Warmup completed: ${key} in ${executionTime.toFixed(2)}ms`)
  return NextResponse.json(
    {
      ...warmupResult,
      key,
      executionTime: `${executionTime.toFixed(2)}ms`,
    },
    { status: 200 }
  )
}

function warmupSkippedResponse(
  warmupResult: Awaited<ReturnType<typeof warmup>>,
  key: string,
  executionTime: number
) {
  logger.debug("Warmup skipped:", key)

  return NextResponse.json(
    {
      key,
      status: warmupResult.status,
      executionTime: `${executionTime.toFixed(2)}ms`,
    },
    { status: 200 }
  )
}

function warmupErrorResponse(
  warmupResult: Awaited<ReturnType<typeof warmup>>,
  key: string,
  executionTime: number
) {
  if (warmupResult.status !== "error") {
    throw new Error("Warmup result is not an error")
  }

  logger.error("Warmup error", {
    key,
    error: warmupResult.error.message,
  })

  return NextResponse.json(
    {
      key,
      status: warmupResult.status,
      error: warmupResult.error.message,
      executionTime: `${executionTime.toFixed(2)}ms`,
    },
    { status: 500 }
  )
}

function unauthorizedResponse() {
  return NextResponse.json(
    {
      error: "Unauthorized access",
    },
    { status: 401 }
  )
}

function invalidKeyResponse(key: string | null) {
  if (isWarmupKey(key)) {
    throw new Error("Invalid invocation with valid cache key")
  }

  logger.error(`Invalid key ${key}`)

  return NextResponse.json(
    {
      key,
      error: `Invalid warmup key: '${key}'`,
    },
    { status: 400 }
  )
}
