import Config from "@rahoot/socket/services/config"
import { mimeForStoredFile } from "@rahoot/web/server/media"
import fs from "fs"
import { promises as fsp } from "fs"
import { Readable } from "node:stream"
import path from "path"
import { NextRequest, NextResponse } from "next/server"

export const runtime = "nodejs"
export const dynamic = "force-dynamic"

export async function GET(
  _request: NextRequest,
  context: { params: Promise<{ file: string }> },
) {
  const params = await context.params
  const safeName = path.basename(params.file)

  if (safeName !== params.file) {
    return NextResponse.json({ error: "Invalid file name" }, { status: 400 })
  }

  const filePath = Config.getMediaPath(safeName)

  if (!fs.existsSync(filePath)) {
    return NextResponse.json({ error: "File not found" }, { status: 404 })
  }

  try {
    const stat = await fsp.stat(filePath)
    const fileSize = stat.size
    const mime = mimeForStoredFile(safeName)
    const range = _request.headers.get("range")

    // Basic range support improves Safari/iOS playback
    if (range) {
      const bytesPrefix = "bytes="
      if (!range.startsWith(bytesPrefix)) {
        return new NextResponse(null, { status: 416 })
      }

      const [rawStart, rawEnd] = range.replace(bytesPrefix, "").split("-")
      const start = Number(rawStart)
      const end = rawEnd ? Number(rawEnd) : fileSize - 1

      if (
        Number.isNaN(start) ||
        Number.isNaN(end) ||
        start < 0 ||
        end >= fileSize ||
        start > end
      ) {
        return new NextResponse(null, { status: 416 })
      }

      const chunkSize = end - start + 1
      const stream = fs.createReadStream(filePath, { start, end })

      return new NextResponse(Readable.toWeb(stream) as any, {
        status: 206,
        headers: {
          "Content-Range": `bytes ${start}-${end}/${fileSize}`,
          "Accept-Ranges": "bytes",
          "Content-Length": chunkSize.toString(),
          "Content-Type": mime,
          "Cache-Control": "public, max-age=31536000, immutable",
        },
      })
    }

    const stream = fs.createReadStream(filePath)

    return new NextResponse(Readable.toWeb(stream) as any, {
      status: 200,
      headers: {
        "Content-Type": mime,
        "Content-Length": fileSize.toString(),
        "Accept-Ranges": "bytes",
        "Cache-Control": "public, max-age=31536000, immutable",
      },
    })
  } catch (error) {
    console.error("Failed to read media file", error)
    return NextResponse.json({ error: "Unable to read file" }, { status: 500 })
  }
}
