import { getSessionUser } from "@/lib/auth";
import { getAppSessionUserByToken, readAppBearerToken } from "@/lib/app-auth";
import {
  discardUnsentLargeComposeAttachmentsForUserEmail,
  storeLargeComposeAttachmentStreamForUserEmail,
} from "@/lib/mail-compose-uploads";
import { GROWTH_LARGE_ATTACHMENT_LIMIT_BYTES } from "@/lib/mail-attachment-policy";

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

function sizeFromHeaders(headers: Headers) {
  const value = headers.get("x-file-size") ?? headers.get("content-length");
  if (!value || !/^\d+$/.test(value)) return null;
  const size = Number(value);
  return Number.isSafeInteger(size) && size > 0 && size <= GROWTH_LARGE_ATTACHMENT_LIMIT_BYTES
    ? size
    : null;
}

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

  const sizeBytes = sizeFromHeaders(request.headers);
  if (!sizeBytes) return Response.json({ error: "attachment-large-limit" }, { status: 413 });
  if (!request.body) return Response.json({ error: "upload-empty" }, { status: 400 });
  let filename: string;
  try {
    filename = decodeURIComponent(request.headers.get("x-file-name") ?? "");
  } catch {
    return Response.json({ error: "invalid-filename" }, { status: 400 });
  }
  if (!filename.trim() || filename.length > 512 || /[\x00-\x1f]/.test(filename)) {
    return Response.json({ error: "invalid-filename" }, { status: 400 });
  }

  try {
    const uploaded = await storeLargeComposeAttachmentStreamForUserEmail({
      body: request.body,
      contentType: request.headers.get("content-type") || "application/octet-stream",
      email: user.email,
      filename,
      sizeBytes,
    });
    return Response.json({
      id: uploaded.id,
      name: uploaded.filename,
      sizeBytes: uploaded.sizeBytes,
    }, { headers: { "Cache-Control": "no-store" } });
  } catch (error) {
    const code = error instanceof Error ? error.message : "upload-failed";
    if (code === "attachment-growth-required") {
      return Response.json({ error: code }, { status: 403 });
    }
    if (code === "attachment-drawer-quota") {
      return Response.json({ error: code }, { status: 409 });
    }
    if (code === "upload-size-mismatch" || code === "attachment-large-limit") {
      return Response.json({ error: code }, { status: 400 });
    }
    console.error("[compose-large-upload] failed", code);
    return Response.json({ error: "upload-failed" }, { status: 503 });
  }
}

export async function DELETE(request: Request) {
  const user = (await getSessionUser()) ??
    (await getAppSessionUserByToken(readAppBearerToken(request.headers), request.headers));
  if (!user) return Response.json({ error: "unauthorized" }, { status: 401 });
  let body: unknown;
  try {
    body = await request.json();
  } catch {
    return Response.json({ error: "invalid-request" }, { status: 400 });
  }
  const ids = typeof body === "object" && body !== null && "ids" in body
    ? (body as { ids: unknown }).ids
    : null;
  if (!Array.isArray(ids) || ids.length > 100 || ids.some((id) => !Number.isSafeInteger(id) || id < 1)) {
    return Response.json({ error: "invalid-request" }, { status: 400 });
  }
  try {
    const discarded = await discardUnsentLargeComposeAttachmentsForUserEmail(user.email, ids as number[]);
    return Response.json({ discarded }, { headers: { "Cache-Control": "no-store" } });
  } catch {
    return Response.json({ error: "discard-failed" }, { status: 503 });
  }
}
