import { getSessionUser } from "@/lib/auth";
import {
  deleteAllMailboxDrawerItemsByEmail,
  deleteMailboxDrawerItemsByEmail,
  getMailboxFileDrawerSnapshotByEmail,
  MailboxFileDrawerQuotaExceededError,
  uploadMailboxDrawerFilesForUserEmail,
} from "@/lib/mailbox-file-drawer";

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

const MAX_FILES_PER_REQUEST = 20;
const MAX_FILE_BYTES = 25 * 1024 * 1024;

function parsePositiveInteger(value: string | null, fallback: number) {
  const parsed = Number(value ?? "");
  return Number.isFinite(parsed) && parsed > 0 ? Math.floor(parsed) : fallback;
}

function mapUploadError(error: unknown) {
  const code = error instanceof Error ? error.message : "";

  if (code === "file-drawer-empty") {
    return { message: "비어 있는 파일은 업로드할 수 없습니다.", status: 400 };
  }
  if (code === "file-drawer-too-large") {
    return { message: "파일 한 개의 업로드 가능 용량을 초과했습니다.", status: 413 };
  }
  if (error instanceof MailboxFileDrawerQuotaExceededError) {
    const quotaGb = error.quotaBytes / (1024 * 1024 * 1024);
    const formattedQuota = Number.isInteger(quotaGb) ? String(quotaGb) : quotaGb.toFixed(1);
    return { message: `파일서랍의 ${formattedQuota}GB 보관 용량을 초과합니다.`, status: 409 };
  }
  if (code === "file-drawer-mailbox-not-found") {
    return { message: "연결된 메일함을 찾을 수 없습니다.", status: 404 };
  }

  return { message: "NCP 스토리지에 파일을 저장하지 못했습니다. 잠시 후 다시 시도해주세요.", status: 500 };
}

export async function GET(request: Request) {
  const user = await getSessionUser();
  if (!user) return Response.json({ error: "unauthorized" }, { status: 401 });

  const url = new URL(request.url);
  const snapshot = await getMailboxFileDrawerSnapshotByEmail({
    email: user.email,
    filter: url.searchParams.get("filter"),
    page: parsePositiveInteger(url.searchParams.get("page"), 1),
    pageSize: parsePositiveInteger(url.searchParams.get("pageSize"), 60),
    query: url.searchParams.get("q"),
  });

  if (!snapshot) {
    return Response.json({ error: "mailbox-not-found", message: "연결된 메일함을 찾을 수 없습니다." }, { status: 404 });
  }

  return Response.json({ ok: true, snapshot });
}

export async function POST(request: Request) {
  const user = await getSessionUser();
  if (!user) return Response.json({ error: "unauthorized" }, { status: 401 });

  try {
    const formData = await request.formData();
    const files = formData.getAll("files").filter((value): value is File => value instanceof File);

    if (files.length === 0) {
      return Response.json({ error: "no-files", message: "업로드할 파일을 선택해주세요." }, { status: 400 });
    }
    if (files.length > MAX_FILES_PER_REQUEST) {
      return Response.json(
        { error: "too-many-files", message: "파일은 한 번에 최대 20개까지 올릴 수 있습니다." },
        { status: 400 },
      );
    }
    if (files.some((file) => file.size > MAX_FILE_BYTES)) {
      return Response.json(
        { error: "file-too-large", message: "파일 한 개는 최대 25MB까지 올릴 수 있습니다." },
        { status: 413 },
      );
    }

    const items = await uploadMailboxDrawerFilesForUserEmail({
      email: user.email,
      files: await Promise.all(
        files.map(async (file) => ({
          body: Buffer.from(await file.arrayBuffer()),
          filename: file.name || "file",
          mimeType: file.type || "application/octet-stream",
          sizeBytes: file.size,
        })),
      ),
    });

    return Response.json({ items, ok: true });
  } catch (error) {
    const mapped = mapUploadError(error);
    return Response.json({ error: "file-upload-failed", message: mapped.message }, { status: mapped.status });
  }
}

export async function DELETE(request: Request) {
  const user = await getSessionUser();
  if (!user) return Response.json({ error: "unauthorized" }, { status: 401 });

  try {
    const payload = await request.json().catch(() => null) as {
      all?: boolean;
      itemIds?: unknown;
    } | null;

    if (payload?.all === true) {
      const result = await deleteAllMailboxDrawerItemsByEmail(user.email);
      if (!result) {
        return Response.json(
          { error: "mailbox-not-found", message: "연결된 메일함을 찾을 수 없습니다." },
          { status: 404 },
        );
      }
      return Response.json({ cleanupQueued: true, ok: true, ...result }, { status: 202 });
    }

    const itemIds = Array.isArray(payload?.itemIds)
      ? payload.itemIds.filter((value): value is string => typeof value === "string")
      : [];
    if (itemIds.length === 0) {
      return Response.json(
        { error: "no-files", message: "삭제할 파일을 선택해주세요." },
        { status: 400 },
      );
    }

    const deletedCount = await deleteMailboxDrawerItemsByEmail(user.email, itemIds);
    return Response.json({ cleanupQueued: true, deletedCount, ok: true }, { status: 202 });
  } catch {
    return Response.json(
      { error: "delete-failed", message: "파일 삭제 요청을 저장하지 못했습니다." },
      { status: 500 },
    );
  }
}
