import { NextRequest, NextResponse } from "next/server";
import { writeFile } from "fs/promises";
import { join } from "path";
import { prisma } from "@/infrastructure/db/prisma";
import { processOCR } from "@/lib/ocr/processor";

export async function POST(request: NextRequest) {
  try {
    const formData = await request.formData();
    const file = formData.get("file") as File;
    const appointmentId = formData.get("appointmentId") as string;

    if (!file) {
      return NextResponse.json(
        { success: false, message: "No se proporcionó ningún archivo" },
        { status: 400 }
      );
    }

    if (!appointmentId) {
      return NextResponse.json(
        { success: false, message: "No se proporcionó el ID de la cita" },
        { status: 400 }
      );
    }

    const allowedTypes = ["application/pdf", "image/jpeg", "image/png"];
    const maxSize = 5 * 1024 * 1024; // 5MB

    if (!allowedTypes.includes(file.type)) {
      return NextResponse.json(
        { success: false, message: "Tipo de archivo no permitido. Solo se aceptan PDF, JPG y PNG" },
        { status: 400 }
      );
    }

    if (file.size > maxSize) {
      return NextResponse.json(
        { success: false, message: "El archivo excede el tamaño máximo de 5MB" },
        { status: 400 }
      );
    }

    const timestamp = Date.now();
    const extension = file.name.split(".").pop();
    const filename = `payment_${appointmentId}_${timestamp}.${extension}`;
    const uploadDir = join(process.cwd(), "public", "uploads", "payments");
    const filepath = join(uploadDir, filename);

    const bytes = await file.arrayBuffer();
    const buffer = Buffer.from(bytes);

    await writeFile(filepath, buffer);

    const { extractedData, confidence } = await processOCR(buffer, file.type);

    const fileUrl = `/uploads/payments/${filename}`;

    let payment = await prisma.payment.findUnique({
      where: { appointmentId: parseInt(appointmentId) },
    });

    if (payment) {
      payment = await prisma.payment.update({
        where: { id: payment.id },
        data: {
          proofUrl: fileUrl,
          extractedDate: extractedData.date,
          extractedAmount: extractedData.amount,
          extractedReference: extractedData.reference,
          extractedSenderName: extractedData.senderName,
          extractedSenderBank: extractedData.senderBank,
          confidence: confidence / 100,
        },
      });
    } else {
      payment = await prisma.payment.create({
        data: {
          appointmentId: parseInt(appointmentId),
          amount: extractedData.amount || 0,
          proofUrl: fileUrl,
          extractedDate: extractedData.date,
          extractedAmount: extractedData.amount,
          extractedReference: extractedData.reference,
          extractedSenderName: extractedData.senderName,
          extractedSenderBank: extractedData.senderBank,
          confidence: confidence / 100,
        },
      });
    }

    return NextResponse.json({
      success: true,
      message: "Comprobante subido y procesado exitosamente",
      fileUrl,
      extractedData,
      confidence: confidence.toFixed(2),
      payment,
    });
  } catch (error) {
    console.error("[Upload Proof] Error:", error);
    return NextResponse.json(
      { success: false, message: "Error al procesar el comprobante" },
      { status: 500 }
    );
  }
}
