import { NextResponse } from "next/server"
import { getSessionUser } from "@/lib/session"
import { getAccountContext } from "@/lib/account"
import {
  saveFile,
  isAllowedUploadExt,
  StorageNotConfiguredError,
  contentMatchesExtension,
  extOf,
} from "@/lib/storage"
import { checkStorageLimit } from "@/lib/plan-limits"

const ALLOWED_SCOPES = ["property-images", "maintenance", "documents", "misc"]

// Generic authenticated upload endpoint. Persists the file under the user's
// namespace (DigitalOcean Spaces when configured, else local disk in dev) and
// returns a URL pointing at the auth-gated /api/files route.
export async function POST(request: Request) {
  const user = await getSessionUser()
  if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 })

  // Uploads belong to the effective owner's portfolio. Viewers are read-only.
  const ctx = await getAccountContext(user.id)
  if (!ctx.canWrite) return NextResponse.json({ error: "Forbidden" }, { status: 403 })
  const ownerId = ctx.ownerId

  const fd = await request.formData()
  const file = fd.get("file") as File | null
  const scopeRaw = (fd.get("scope") as string) || "misc"
  const scope = ALLOWED_SCOPES.includes(scopeRaw) ? scopeRaw : "misc"
  const fixedName = (fd.get("fixed_name") as string) || undefined

  if (!file) return NextResponse.json({ error: "No file provided" }, { status: 400 })
  if (file.size > 20 * 1024 * 1024) {
    return NextResponse.json({ error: "File too large (max 20 MB)" }, { status: 400 })
  }

  if (!isAllowedUploadExt(file.name)) {
    return NextResponse.json({ error: "File type not allowed" }, { status: 400 })
  }

  // Reject files whose real content doesn't match the claimed extension.
  const head = Buffer.from(await file.slice(0, 16).arrayBuffer())
  if (!contentMatchesExtension(head, extOf(file.name))) {
    return NextResponse.json({ error: "File content does not match its type" }, { status: 400 })
  }

  // Enforce per-plan storage quota (accounts for everything already stored in
  // the owner's portfolio namespace).
  const storageError = await checkStorageLimit(ownerId, file.size)
  if (storageError) return NextResponse.json({ error: storageError }, { status: 403 })

  let saved
  try {
    saved = await saveFile(file, { userId: ownerId, scope, fixedName })
  } catch (err) {
    if (err instanceof StorageNotConfiguredError) {
      console.error("[upload]", err.message)
      return NextResponse.json(
        { error: "File uploads are temporarily unavailable. Please try again later." },
        { status: 503 }
      )
    }
    throw err
  }
  const { key, size, type } = saved

  return NextResponse.json({
    url: `/api/files/${key}`,
    key,
    size,
    type,
    name: file.name,
  })
}
