import { getSessionUser } from "@/lib/auth";
import { isKavenixAdminEmail } from "@/lib/kavenix-admin";
import { uploadKavenixBlogAsset } from "@/lib/kavenix-blog-images";

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

type UploadKind = "audio" | "file" | "image" | "video";

function uploadKindLabel(kind: UploadKind) {
  if (kind === "audio") return "오디오 파일";
  if (kind === "video") return "동영상";
  if (kind === "file") return "파일";
  return "이미지";
}

function uploadErrorResponse(error: unknown, kind: UploadKind) {
  const code = error instanceof Error ? error.message : "blog-image-upload-failed";

  if (code === "blog-image-empty") {
    return { message: "비어 있는 이미지는 업로드할 수 없습니다.", status: 400 };
  }

  if (code === "blog-image-too-large") {
    return { message: "이미지 용량이 업로드 제한을 초과했습니다.", status: 413 };
  }

  if (code === "blog-image-type-invalid" || code === "blog-image-content-invalid") {
    return { message: "JPG, PNG, GIF, WebP, AVIF 이미지만 업로드할 수 있습니다.", status: 400 };
  }

  if (code === "blog-image-draft-token-invalid") {
    return { message: "편집 세션이 만료되었습니다. 페이지를 새로고침한 뒤 다시 시도해 주세요.", status: 400 };
  }

  if (code === "blog-audio-empty") {
    return { message: "비어 있는 오디오 파일은 업로드할 수 없습니다.", status: 400 };
  }

  if (code === "blog-audio-too-large") {
    return { message: "오디오 파일은 최대 50MB까지 업로드할 수 있습니다.", status: 413 };
  }

  if (code === "blog-audio-type-invalid" || code === "blog-audio-content-invalid") {
    return { message: "MP3, WAV, OGG, M4A, AAC, FLAC 오디오만 업로드할 수 있습니다.", status: 400 };
  }

  if (code === "blog-video-empty") {
    return { message: "비어 있는 동영상은 업로드할 수 없습니다.", status: 400 };
  }

  if (code === "blog-video-too-large") {
    return { message: "동영상은 최대 200MB까지 업로드할 수 있습니다.", status: 413 };
  }

  if (code === "blog-video-type-invalid" || code === "blog-video-content-invalid") {
    return { message: "MP4, WebM, MOV 동영상만 업로드할 수 있습니다.", status: 400 };
  }

  if (code === "blog-file-empty") {
    return { message: "비어 있는 파일은 업로드할 수 없습니다.", status: 400 };
  }

  if (code === "blog-file-too-large") {
    return { message: "파일은 최대 50MB까지 업로드할 수 있습니다.", status: 413 };
  }

  if (code === "blog-file-type-invalid" || code === "blog-file-content-invalid") {
    return { message: "PDF, Office 문서, ZIP, TXT 파일만 업로드할 수 있습니다.", status: 400 };
  }

  return {
    message: `${uploadKindLabel(kind)}을 NCP 스토리지에 업로드하지 못했습니다. 잠시 후 다시 시도해 주세요.`,
    status: 500,
  };
}

export async function POST(request: Request) {
  const user = await getSessionUser();

  if (!user || !isKavenixAdminEmail(user.email)) {
    return Response.json({ error: "forbidden" }, { status: 403 });
  }

  const formData = await request.formData();
  const draftToken = formData.get("draftToken");
  const requestedKind = formData.get("kind");
  const kind: UploadKind = requestedKind === "audio" || requestedKind === "file" || requestedKind === "video"
    ? requestedKind
    : "image";
  const files = formData
    .getAll("files")
    .filter((entry): entry is File => entry instanceof File);

  if (files.length === 0) {
    return Response.json({ error: "no-files", message: `업로드할 ${uploadKindLabel(kind)}을 선택해 주세요.` }, { status: 400 });
  }

  if (files.length > (kind === "image" ? 8 : 1)) {
    return Response.json({ error: "too-many-files", message: kind === "image" ? "한 번에 최대 8장까지 업로드할 수 있습니다." : `${uploadKindLabel(kind)}은 한 번에 하나만 업로드할 수 있습니다.` }, { status: 400 });
  }

  if (typeof draftToken !== "string") {
    return Response.json({ error: "invalid-draft-token", message: "편집 세션을 확인하지 못했습니다." }, { status: 400 });
  }

  try {
    const uploads = await Promise.all(
      files.map(async (file) => ({
        ...await uploadKavenixBlogAsset({
        body: Buffer.from(await file.arrayBuffer()),
        contentType: file.type,
        draftToken,
        email: user.email,
        kind,
        sizeBytes: file.size,
        }),
        filename: file.name,
      })),
    );

    return Response.json({
      ok: true,
      uploads,
    });
  } catch (error) {
    const mapped = uploadErrorResponse(error, kind);
    return Response.json({ error: `blog-${kind}-upload-failed`, message: mapped.message }, { status: mapped.status });
  }
}
