"use server";
import { db } from '@/lib/db';
import { curso, inscripcion, cursoinstructor } from '@/db/schema';
import { eq, count } from 'drizzle-orm';
import { revalidatePath } from "next/cache";
import { authOptions } from "@/lib/auth";
import { getServerSession } from "next-auth";
import crypto from "crypto";

async function checkCourseOwnership(cursoId: string) {
  const session = await getServerSession(authOptions);
  if (!session || (session.user.role !== "SUPERADMIN" && session.user.role !== "ADMIN_COLEGIO")) {
    throw new Error("No autorizado");
  }
  
  if (session.user.role === "SUPERADMIN") return session;

  const foundCurso = await db.query.curso.findFirst({
    where: eq(curso.id, cursoId),
    columns: { colegioId: true }
  });

  if (!foundCurso || foundCurso.colegioId !== session.user.colegioId) {
    throw new Error("No autorizado para este colegio");
  }

  return session;
}

export async function deleteCurso(id: string) {
  try {
    await checkCourseOwnership(id);

    const foundCurso = await db.query.curso.findFirst({
      where: eq(curso.id, id)
    });

    if (!foundCurso) return { success: false, error: "Curso no encontrado" };

    const [inscCountRes] = await db.select({ value: count() }).from(inscripcion).where(eq(inscripcion.cursoId, id));
    const inscripcionesCount = inscCountRes.value;

    if (inscripcionesCount > 0 || foundCurso.inscritosCount > 0) {
      return { success: false, error: "Regla de Negocio: No se puede eliminar un curso que tiene alumnos inscritos." };
    }

    await db.update(curso)
      .set({ activo: false, updatedAt: new Date() })
      .where(eq(curso.id, id));

    revalidatePath("/dashboard/cursos");
    return { success: true };
  } catch (error: any) {
    return { success: false, error: error.message || "Ocurrió un error en el servidor." };
  }
}

export async function createCurso(formData: FormData) {
  const session = await getServerSession(authOptions);
  if (!session || (session.user.role !== "SUPERADMIN" && session.user.role !== "ADMIN_COLEGIO")) {
    return { success: false, error: "No autorizado" };
  }

  try {
    const requestedColegioId = formData.get("colegioId") as string;
    const titulo       = formData.get("titulo") as string;
    const categoria    = formData.get("categoria") as string;
    const precio       = parseFloat(formData.get("precio") as string) || 0;
    const fechaInicioStr = formData.get("fechaInicio") as string;
    const matriculaMax = parseInt(formData.get("matriculaMax") as string) || null;
    const detallesGraduacion = formData.get("detallesGraduacion") as string;
    const descripcion  = formData.get("descripcion") as string;
    const requisitos   = formData.get("requisitos") as string;
    const duracionSemanas = parseInt(formData.get("duracionSemanas") as string) || null;
    const tipoCobro    = (formData.get("tipoCobro") as "GRATIS" | "PAGO" | "COLABORACION") || "PAGO";
    const horaEntrada  = (formData.get("horaEntrada") as string) || null;
    const horaSalida   = (formData.get("horaSalida") as string) || null;
    const mostrarPrecio = formData.get("mostrarPrecio") === "on";
    const instructorIds = formData.getAll("instructorId") as string[];
    const estudianteIds = formData.getAll("estudianteId") as string[];

    // Force colegioId for ADMIN_COLEGIO
    let colegioId = requestedColegioId;
    if (session.user.role === "ADMIN_COLEGIO") {
      colegioId = session.user.colegioId as string;
    }

    if (!colegioId) throw new Error("La sede gestora es requerida.");
    if (!titulo) throw new Error("El título del curso es requerido.");
    if (!categoria) throw new Error("La categoría es requerida.");
    if (!fechaInicioStr) throw new Error("La fecha de inicio es requerida.");

    const fechaInicio = new Date(fechaInicioStr);
    if (isNaN(fechaInicio.getTime())) {
      throw new Error("La fecha de inicio no es válida.");
    }

    const newCursoId = crypto.randomUUID();
    await db.insert(curso).values({
      id: newCursoId,
      colegioId,
      titulo,
      categoria,
      precio,
      fechaInicio,
      matriculaMax,
      detallesGraduacion,
      descripcion,
      requisitos,
      duracionSemanas,
      horaEntrada,
      horaSalida,
      mostrarPrecio,
      tipoCobro,
      updatedAt: new Date()
    });

    if (instructorIds.length > 0) {
      await db.insert(cursoinstructor).ignore().values(
        instructorIds.map(iid => ({ cursoId: newCursoId, instructorId: iid }))
      );
    }

    if (estudianteIds.length > 0) {
      await db.insert(inscripcion).ignore().values(
        estudianteIds.map(eid => ({
          id: crypto.randomUUID(),
          cursoId: newCursoId,
          userId: eid,
          estadoFlujo: "INSCRITO" as const,
          updatedAt: new Date(),
          estadoPago: "APROBADO" as const,
        }))
      );
    }

    revalidatePath("/dashboard/cursos");
    return { success: true };
  } catch (error: any) {
    console.error("Error en createCurso:", error);
    return { success: false, error: error.message || "Error inesperado al crear el curso." };
  }
}

export async function updateCurso(id: string, formData: FormData) {
  try {
    const session = await checkCourseOwnership(id);

    const titulo       = formData.get("titulo") as string;
    const categoria    = formData.get("categoria") as string;
    const precio       = parseFloat(formData.get("precio") as string) || 0;
    const matriculaMax = parseInt(formData.get("matriculaMax") as string) || null;
    const detallesGraduacion = formData.get("detallesGraduacion") as string;
    const descripcion  = formData.get("descripcion") as string;
    const requisitos   = formData.get("requisitos") as string;
    const duracionSemanas = parseInt(formData.get("duracionSemanas") as string) || null;
    const tipoCobro    = (formData.get("tipoCobro") as "GRATIS" | "PAGO" | "COLABORACION") || "PAGO";
    const horaEntrada  = (formData.get("horaEntrada") as string) || null;
    const horaSalida   = (formData.get("horaSalida") as string) || null;
    const mostrarPrecio = formData.get("mostrarPrecio") === "on";
    const instructorIds = formData.getAll("instructorId") as string[];
    const estudianteIds = formData.getAll("estudianteId") as string[];

    await db.update(curso)
      .set({
        titulo,
        categoria,
        precio,
        matriculaMax,
        detallesGraduacion,
        descripcion,
        requisitos,
        duracionSemanas,
        horaEntrada,
        horaSalida,
        mostrarPrecio,
        tipoCobro,
        updatedAt: new Date()
      })
      .where(eq(curso.id, id));

    // Reemplazar instructores
    await db.delete(cursoinstructor).where(eq(cursoinstructor.cursoId, id));
    if (instructorIds.length > 0) {
      await db.insert(cursoinstructor).ignore().values(
        instructorIds.map(iid => ({ cursoId: id, instructorId: iid }))
      );
    }

    // Reemplazar estudiantes inscritos
    await db.delete(inscripcion).where(eq(inscripcion.cursoId, id));
    if (estudianteIds.length > 0) {
      await db.insert(inscripcion).ignore().values(
        estudianteIds.map(eid => ({
          id: crypto.randomUUID(),
          cursoId: id,
          userId: eid,
          estadoFlujo: "INSCRITO" as const,
          estadoPago: "APROBADO" as const,
          updatedAt: new Date()
        }))
      );
    }

    revalidatePath("/dashboard/cursos");
    revalidatePath("/dashboard/instructores");
    return { success: true };
  } catch (error: any) {
    return { success: false, error: error.message || "Error al actualizar el curso." };
  }
}
