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

import { gatewayUrl } from "@/lib/api/gateway";
import { getAccessToken } from "@/lib/auth/session";
import { decodeJwt } from "@/lib/auth/jwt";
import { MINIO_PUBLIC_URL } from "@/lib/files";

export const dynamic = "force-dynamic";

/**
 * Browser → Next → MinIO upload proxy. The browser can't reach the presigned MinIO
 * host (minio:9000) directly, but the Next server (in the docker network) can. So:
 *   1. ask file-svc for a presigned PUT URL
 *   2. PUT the bytes server-side
 *   3. confirm the upload
 *   4. return the public object URL (user-uploads bucket is public-read)
 */
export async function POST(req: NextRequest) {
  const token = await getAccessToken();
  if (!token) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  const claims = decodeJwt(token);
  const isAdmin =
    String(claims?.is_admin) === "true" || claims?.is_admin === true ||
    String(claims?.is_tenant_admin) === "true";
  if (!isAdmin) return NextResponse.json({ error: "Forbidden" }, { status: 403 });

  const form = await req.formData().catch(() => null);
  const file = form?.get("file");
  if (!(file instanceof File)) {
    return NextResponse.json({ error: "No file provided" }, { status: 400 });
  }

  const auth = { Authorization: `Bearer ${token}` };

  // 1. presigned PUT URL
  const presignRes = await fetch(gatewayUrl("/v1/files/presigned-upload"), {
    method: "POST",
    cache: "no-store",
    headers: { ...auth, "Content-Type": "application/json" },
    body: JSON.stringify({
      filename: file.name,
      mime_type: file.type || "application/octet-stream",
      size_bytes: file.size,
    }),
  });
  const presign = await presignRes.json().catch(() => null);
  if (!presignRes.ok || !presign?.upload_url || !presign?.file_id) {
    return NextResponse.json(
      { error: presign?.error?.message ?? "Could not start upload" },
      { status: presignRes.status || 502 }
    );
  }

  // 2. PUT the bytes to MinIO (server-side; reaches minio:9000)
  const put = await fetch(presign.upload_url, {
    method: "PUT",
    headers: { "Content-Type": file.type || "application/octet-stream" },
    body: Buffer.from(await file.arrayBuffer()),
  });
  if (!put.ok) {
    return NextResponse.json({ error: "Upload to storage failed" }, { status: 502 });
  }

  // 3. confirm
  await fetch(gatewayUrl(`/v1/files/${presign.file_id}/confirm`), {
    method: "POST",
    cache: "no-store",
    headers: auth,
  });

  // 4. fetch the record to get bucket/key → build the public URL
  const detailRes = await fetch(gatewayUrl(`/v1/files/${presign.file_id}`), {
    cache: "no-store",
    headers: auth,
  });
  const detail = await detailRes.json().catch(() => null);
  const bucket = detail?.minio_bucket ?? "user-uploads";
  const key = detail?.minio_key;
  const url = key ? `${MINIO_PUBLIC_URL}/${bucket}/${key}` : null;

  return NextResponse.json({
    id: presign.file_id,
    name: file.name,
    mime_type: file.type,
    url,
  });
}
