"""
Servicio de carga de Grupos dentro de una Carrera y Gestion ya seleccionadas
(el usuario primero navega Facultad -> Carrera y elige la Gestion activa).

El Excel ya NO incluye lista de estudiantes: solo la cantidad, para no tocar
ningun dato identificable de los alumnos.

Columnas esperadas (una sola hoja, sin nombre fijo obligatorio, se toma la
primera hoja del archivo):
    Asignatura | Grupo | Docente | DocenteEmail | Director | DirectorEmail | CantidadEstudiantes
"""
import pandas as pd
from django.db import transaction

from evaluacion.models import Asignatura, Persona, Grupo

COLUMNAS_REQUERIDAS = [
    "Asignatura", "Grupo", "Docente", "DocenteEmail",
    "Director", "DirectorEmail", "CantidadEstudiantes",
]


class ExcelValidationError(Exception):
    pass


@transaction.atomic
def cargar_excel_grupos(archivo, carrera, gestion):
    df = pd.read_excel(archivo, dtype=str).dropna(how="all")

    faltantes = [c for c in COLUMNAS_REQUERIDAS if c not in df.columns]
    if faltantes:
        raise ExcelValidationError(
            f"Faltan columnas en el archivo: {faltantes}. Se esperaban: {COLUMNAS_REQUERIDAS}"
        )

    for col in df.columns:
        df[col] = df[col].astype(str).str.strip()

    duplicados = df[df.duplicated(subset=["Asignatura", "Grupo"], keep=False)]
    if not duplicados.empty:
        raise ExcelValidationError(
            "El archivo tiene filas duplicadas para la misma combinacion Asignatura + Grupo."
        )

    resumen = {
        "asignaturas_creadas": 0, "personas_creadas": 0,
        "grupos_creados": 0, "grupos_actualizados": 0, "filas_con_error": [],
    }

    for idx, fila in df.iterrows():
        try:
            cantidad = int(float(fila["CantidadEstudiantes"]))
            if cantidad < 1:
                raise ValueError("La cantidad de estudiantes debe ser al menos 1.")
        except ValueError:
            resumen["filas_con_error"].append(
                f"Fila {idx + 2}: 'CantidadEstudiantes' invalido ('{fila['CantidadEstudiantes']}')."
            )
            continue

        asignatura, creada = Asignatura.objects.get_or_create(nombre=fila["Asignatura"], carrera=carrera)
        resumen["asignaturas_creadas"] += int(creada)

        docente, creada = Persona.objects.get_or_create(
            email=fila["DocenteEmail"], rol=Persona.ROL_DOCENTE,
            defaults={"nombre": fila["Docente"]},
        )
        resumen["personas_creadas"] += int(creada)

        director, creada = Persona.objects.get_or_create(
            email=fila["DirectorEmail"], rol=Persona.ROL_DIRECTOR,
            defaults={"nombre": fila["Director"]},
        )
        resumen["personas_creadas"] += int(creada)

        grupo, creado = Grupo.objects.update_or_create(
            asignatura=asignatura, gestion=gestion, codigo=fila["Grupo"],
            defaults={"docente": docente, "director": director, "cantidad_estudiantes": cantidad},
        )
        if creado:
            resumen["grupos_creados"] += 1
        else:
            resumen["grupos_actualizados"] += 1

    return resumen
