import { NextRequest } from "next/server";
import { KycStatus } from "@prisma/client";
import { z } from "zod";
import { prisma } from "@/server/db";
import { AppError } from "@/server/errors";
import { fail, ok } from "@/server/http";
import { kycDocumentTypes, persistKycUploads, prepareKycUploads } from "@/server/kyc/document-upload";
import { requireUser } from "@/server/security/auth";

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

const uploadSchema = z.object({
  documentType: z.enum(kycDocumentTypes)
});

export async function POST(request: NextRequest) {
  try {
    const { user } = await requireUser(request);
    const form = await request.formData();
    const input = uploadSchema.parse({
      documentType: String(form.get("documentType") ?? "")
    });
    const files = form.getAll("files").filter((item): item is File => item instanceof File);
    const fallbackFile = form.get("file");
    if (!files.length && fallbackFile instanceof File) {
      files.push(fallbackFile);
    }

    const pendingCase = await prisma.kycCase.findFirst({
      where: { userId: user.id, status: KycStatus.PENDING },
      orderBy: { openedAt: "desc" }
    });
    const isRequiredDocument = input.documentType !== "SUPPORTING_DOCUMENT";

    if (isRequiredDocument && !pendingCase) {
      throw new AppError("Aucune vérification n'est demandée sur votre compte.", 409, "KYC_NOT_REQUIRED");
    }

    const kycCase =
      pendingCase ??
      (await prisma.kycCase.create({
        data: {
          userId: user.id,
          status: KycStatus.NOT_STARTED,
          provider: "manual_support_upload",
          providerRef: `support-upload-${user.id}`
        }
      }));

    const prepared = await prepareKycUploads({
      files,
      userId: user.id,
      caseId: kycCase.id,
      documentType: input.documentType
    });
    await persistKycUploads(prepared);

    const documents = await prisma.$transaction(
      prepared.map((file) =>
        prisma.kycDocument.create({
          data: {
            caseId: kycCase.id,
            type: file.documentType,
            storageKey: file.storageKey,
            checksum: file.checksum,
            status: "uploaded",
            metadata: {
              originalName: file.originalName,
              mimeType: file.mimeType,
              size: file.size
            }
          }
        })
      )
    );

    return ok({
      case: {
        id: kycCase.id,
        status: kycCase.status
      },
      documents: documents.map((document) => ({
        id: document.id,
        type: document.type,
        status: document.status,
        uploadedAt: document.uploadedAt
      }))
    });
  } catch (error) {
    return fail(error);
  }
}
