import { NextResponse } from "next/server";
import { db } from "@/lib/db";
import { inscripcion, reportepago, curso, notificacion } from "@/db/schema";
import { eq } from "drizzle-orm";
import { getServerSession } from "next-auth/next";
import { authOptions } from "@/lib/auth";
import fs from 'fs/promises';
import path from 'path';
import crypto from "crypto";

export async function POST(req: Request) {
  try {
    const session = await getServerSession(authOptions);
    if (!session?.user?.id) {
      return NextResponse.json({ error: "No autorizado" }, { status: 401 });
    }

    const formData = await req.formData();
    const inscripcionId = formData.get('inscripcionId') as string;
    const referencia = formData.get('referencia') as string;
    const montoStr = formData.get('monto') as string;
    const monto = parseFloat(montoStr || "0");
    const fechaPago = formData.get('fechaPago') as string;
    const concepto = formData.get('concepto') as string;
    const file = formData.get('comprobante') as File | null;

    if (!inscripcionId || !file || !referencia || !fechaPago) {
      return NextResponse.json({ error: "Faltan campos obligatorios" }, { status: 400 });
    }

    // Guardar archivo
    const bytes = await file.arrayBuffer();
    const buffer = Buffer.from(bytes);
    
    // Crear el nombre y la ruta del archivo
    const uniqueName = `${Date.now()}-${file.name.replace(/\s+/g, '_')}`;
    const publicDir = path.join(process.cwd(), 'public', 'uploads');
    const filePath = path.join(publicDir, uniqueName);
    
    // Asegurarse de que el directorio exista
    try {
      await fs.access(publicDir);
    } catch {
      await fs.mkdir(publicDir, { recursive: true });
    }
    
    await fs.writeFile(filePath, buffer);
    const comprobanteUrl = `/uploads/${uniqueName}`;

    // Verificar que la inscripción pertenezca al usuario usando join
    const inscripcionResult = await db
      .select({
        inscripcion: inscripcion,
        curso: curso
      })
      .from(inscripcion)
      .innerJoin(curso, eq(inscripcion.cursoId, curso.id))
      .where(eq(inscripcion.id, inscripcionId))
      .limit(1);

    if (inscripcionResult.length === 0 || inscripcionResult[0].inscripcion.userId !== session.user.id) {
      return NextResponse.json({ error: "Inscripción no válida" }, { status: 403 });
    }

    const inscripcionData = inscripcionResult[0];
    const cursoData = inscripcionData.curso;

    // Crear el Reporte de Pago
    const reporteId = crypto.randomUUID();
    await db.insert(reportepago).values({
      id: reporteId,
      inscripcionId,
      monto,
      referencia,
      fechaPago,
      comprobanteUrl,
      concepto,
      estado: "PENDIENTE",
      updatedAt: new Date(),
    });

    // Actualizar el estado de pago de la inscripción a PENDIENTE de revisión
    // Y el estadoFlujo a REGISTRADO_PAGO
    await db.update(inscripcion).set({
      estadoPago: "PENDIENTE",
      estadoFlujo: "REGISTRADO_PAGO"
    }).where(eq(inscripcion.id, inscripcionId));

    // Crear notificación para el administrador
    await db.insert(notificacion).values({
      id: crypto.randomUUID(),
      titulo: `Nuevo Pago Reportado: ${concepto}`,
      mensaje: `El estudiante ha reportado un pago de ${monto} con referencia ${referencia} para el curso ${cursoData.titulo}.`,
      colegioId: cursoData.colegioId,
      cursoId: cursoData.id,
      userId: session.user.id
    });

    return NextResponse.json({ success: true, reporte: { id: reporteId } });
  } catch (error) {
    console.error("Error al reportar pago:", error);
    return NextResponse.json({ error: "Error interno del servidor" }, { status: 500 });
  }
}
