import { NextResponse } from "next/server";
import { callPortalBackend } from "@/lib/backend";
import { hasValidClientSession, verificationRequiredResponse } from "@/lib/client-session";
import { checkRateLimit, clientAddress } from "@/lib/rate-limit";

export const dynamic = "force-dynamic";

type RouteContext = { params: Promise<{ token: string }> };

type UploadFileBody = {
  fileName?: string;
  mimeType?: string;
  base64?: string;
  checklistItemId?: string;
  checklistLabel?: string;
};

type UploadBody = UploadFileBody & { files?: UploadFileBody[] };

const MAX_BASE64_LENGTH = 36_000_000;
const MAX_FILES_PER_BATCH = 10;
const ALLOWED_EXTENSIONS = new Set(["pdf", "jpg", "jpeg", "png", "heic", "heif"]);

function extensionOf(fileName: string) {
  return fileName.toLowerCase().split(".").pop() || "";
}

function signatureMatches(file: UploadFileBody) {
  if (!file.fileName || !file.base64) return false;
  const extension = extensionOf(file.fileName);
  if (!ALLOWED_EXTENSIONS.has(extension)) return false;

  const header = Buffer.from(file.base64.slice(0, 96), "base64");
  if (extension === "pdf") return header.subarray(0, 5).toString("ascii") === "%PDF-";
  if (extension === "jpg" || extension === "jpeg") return header[0] === 0xff && header[1] === 0xd8 && header[2] === 0xff;
  if (extension === "png") return header.subarray(0, 8).equals(Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]));
  if (extension === "heic" || extension === "heif") {
    const brand = header.subarray(4, 32).toString("ascii").toLowerCase();
    return brand.includes("ftyp") && /heic|heix|hevc|hevx|mif1|msf1/.test(brand);
  }
  return false;
}

export async function POST(request: Request, context: RouteContext) {
  try {
    const { token } = await context.params;
    if (!/^[a-f0-9]{40,64}$/i.test(token)) {
      return NextResponse.json({ ok: false, error: "Lien de dossier invalide." }, { status: 404 });
    }

    if (!hasValidClientSession(request, token)) {
      return NextResponse.json(verificationRequiredResponse(), {
        status: 401,
        headers: { "cache-control": "no-store" },
      });
    }

    const rate = checkRateLimit(`client-upload:${clientAddress(request)}:${token}`, 20, 10 * 60 * 1000);
    if (!rate.allowed) {
      return NextResponse.json(
        { ok: false, error: "Trop de dépôts rapprochés. Réessayez dans quelques instants." },
        { status: 429, headers: { "Retry-After": String(rate.retryAfter) } },
      );
    }

    const body = (await request.json()) as UploadBody;
    const files = body.files?.length ? body.files : [body];
    if (!files.length || files.length > MAX_FILES_PER_BATCH) {
      return NextResponse.json({ ok: false, error: "Un dépôt doit contenir entre 1 et 10 fichiers." }, { status: 400 });
    }
    if (files.some((file) => !file.fileName || !file.base64 || !file.checklistItemId || !file.checklistLabel)) {
      return NextResponse.json({ ok: false, error: "Dépôt incomplet." }, { status: 400 });
    }
    const totalBase64Length = files.reduce((total, file) => total + (file.base64?.length || 0), 0);
    if (totalBase64Length > MAX_BASE64_LENGTH) {
      return NextResponse.json({ ok: false, error: "Ce lot est trop volumineux. Déposez-le en plusieurs fois." }, { status: 413 });
    }
    if (files.some((file) => !signatureMatches(file))) {
      return NextResponse.json({ ok: false, error: "Un fichier n’est pas un PDF ou une image autorisée, ou son format réel ne correspond pas à son extension." }, { status: 415 });
    }

    const data = await callPortalBackend<unknown>({
      action: "upload_pieces",
      token,
      uploads: files,
    });
    return NextResponse.json({ ok: true, data });
  } catch (error) {
    const message = error instanceof Error ? error.message : "Dépôt impossible.";
    return NextResponse.json({ ok: false, error: message }, { status: 502 });
  }
}
