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

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

export const dynamic = "force-dynamic";

/**
 * User-scoped upload (avatar / profile media). Same Browser → Next → MinIO proxy as
 * the admin uploader, but available to ANY logged-in user (file-svc only requires
 * auth, not admin). Returns the public object URL.
 */
export async function POST(req: NextRequest) {
  const token = await getAccessToken();
  if (!token) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  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 });
  }
  // Avatars are images and small — guard so a profile upload can't be abused for
  // arbitrary large files. (5 MB is generous for an avatar.)
  if (file.size > 5 * 1024 * 1024) {
    return NextResponse.json({ error: "File too large (max 5MB)" }, { status: 413 });
  }
  if (!file.type.startsWith("image/")) {
    return NextResponse.json({ error: "Only image files are allowed" }, { status: 415 });
  }

  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 → 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;

  // 5. persist as the user's avatar (Identity `POST /v1/users/me/avatar`)
  if (url) {
    await fetch(gatewayUrl("/v1/users/me/avatar"), {
      method: "POST",
      cache: "no-store",
      headers: { ...auth, "Content-Type": "application/json" },
      body: JSON.stringify({ avatar_url: url }),
    }).catch(() => null);
  }

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