package es.pulsoft.controlador;

import java.time.LocalDate;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import es.pulsoft.controlador.dto.CursoEstudianteBusqueda;
import es.pulsoft.controlador.entity.Curso;
import es.pulsoft.controlador.entity.CursoEstudiante;
import es.pulsoft.controlador.entity.Estudiante;
import es.pulsoft.dao.CursoDao;
import es.pulsoft.dao.CursoEstudianteDao;
import es.pulsoft.dao.EstudianteDao;

/**
 * Controlador para gestionar las operaciones relacionadas con la inscripción de estudiantes en cursos.
 * Mapea todas las URLs bajo el path "/CursoEstudiante".
 */
@Controller
@RequestMapping("/CursoEstudiante")
public class CursoEstudianteControlador {

    @Autowired
    private CursoEstudianteDao cursoEstudianteDao;
    
    @Autowired
    private CursoDao cursoDao;
    
    @Autowired
    private EstudianteDao estudianteDao;
    
    /**
     * Muestra el formulario para agregar una nueva inscripción estudiante-curso.
     * 
     * @param cursoEstudiante Objeto que se bindea al formulario
     * @param modelo Modelo para pasar datos a la vista
     * @param modo Indica el modo de operación (ej: "agregar", "editar")
     * @return Vista "/cursoEstudiante/agregarCursoEstudiante"
     */
    @GetMapping("/agregarCursoEstudiante")
    public String agregarCursoEstudiante(
            @ModelAttribute("cursoEstudiante") CursoEstudiante cursoEstudiante,
            Model modelo,
            String modo) {

        List<Curso> listaCursos = cursoDao.ObtenerCursos();
        List<Estudiante> listaEstudiantes = estudianteDao.listarEstudiantes();
        modelo.addAttribute("listaCursos", listaCursos);
        modelo.addAttribute("listaEstudiantes", listaEstudiantes);
        modelo.addAttribute("cursoEstudiante", cursoEstudiante);
        modelo.addAttribute("modo", modo);
        return "/cursoEstudiante/agregarCursoEstudiante";
    }
    
    /**
     * Procesa el formulario para insertar o actualizar una inscripción.
     * 
     * @param cursoEstudiante Objeto con los datos del formulario
     * @param session Sesión HTTP para mensajes flash
     * @param modo Indica si es una operación normal (inserción) o de actualización
     * @return Redirección a la página principal
     */
    @PostMapping("/agregarCursoEstudiante")
    public String insertarCursoEstudiante(
            @ModelAttribute("cursoEstudiante") CursoEstudiante cursoEstudiante,
            HttpSession session,
            String modo) {
        
        LocalDate hoy = LocalDate.now();
        cursoEstudiante.setFechaInscripcion(hoy);
        
        if(modo.equals("normal")) {
            try {
                cursoEstudianteDao.inscipcion(cursoEstudiante);
                session.setAttribute("mensaje","Estudiante agregado al curso con exito");
            } catch (DataIntegrityViolationException ex) {
                session.setAttribute("error","Este estudiante ya está inscrito en el curso.");
            } catch(Exception e) {
                session.setAttribute("error","Operacion de insertar curso-estudiante fallida");
            }
        } else {
            try {                
                cursoEstudianteDao.inscipcion(cursoEstudiante);
                session.setAttribute("mensaje","Estudiante actualizado al curso con exito");
            } catch (DataIntegrityViolationException ex) {
                session.setAttribute("error","Este estudiante ya está inscrito en el curso.");
            } catch(Exception e) {
                session.setAttribute("error","Operacion al actualziar curso-estudiante fallida");
            }
        }
        return "redirect:/";
    }
    
    /**
     * Muestra la lista de todas las inscripciones estudiante-curso.
     * 
     * @param modo Indica el modo de operación
     * @param modelo Modelo para pasar datos a la vista
     * @return Vista "/cursoEstudiante/mostrarCursoEstudiante"
     */
    @GetMapping("/mostrarCursoEstudiante")
    public String mostrarCursoEstudiante(
            String modo,
            Model modelo) {
        
        List<CursoEstudiante> listaInscripciones = cursoEstudianteDao.obtenerInscripciones();
        CursoEstudiante cursoEstudiante = new CursoEstudiante();
        modelo.addAttribute("listaInscripciones", listaInscripciones);
        modelo.addAttribute("modo", modo);
        modelo.addAttribute("cursoEstudiante", cursoEstudiante);
        CursoEstudianteBusqueda cursoEstudianteBusqueda = new CursoEstudianteBusqueda();
        modelo.addAttribute("cursoEstudianteBusqueda", cursoEstudianteBusqueda);
        return "/cursoEstudiante/mostrarCursoEstudiante";
    }
    
    /**
     * Elimina una inscripción estudiante-curso.
     * 
     * @param id ID de la inscripción a borrar
     * @param session Sesión HTTP para mensajes flash
     * @return Redirección a la vista de listado de inscripciones
     */
    @GetMapping("/borrar")
    public String borrarCurso(
            @RequestParam("id") int id,
            HttpSession session) {
        
        try {
            CursoEstudiante cursoEstudiante = cursoEstudianteDao.obtenerCursoEstudiante(id);
            cursoEstudianteDao.borrar(cursoEstudiante);
            session.setAttribute("mensaje", "Inscripcion borrada con exito");
        } catch(Exception e) {
            session.setAttribute("error", "Fallo al borrar la inscripcion");
        }
        
        return "redirect:/CursoEstudiante/mostrarCursoEstudiante?modo=borrar";
    }
    
    /**
     * Prepara el formulario para actualizar una inscripción existente.
     * 
     * @param modelo Modelo para pasar datos a la vista
     * @param id ID de la inscripción a actualizar
     * @param modo Modo de operación (debería ser "actualizar")
     * @return Vista "cursoEstudiante/agregarCursoEstudiante" (reutiliza el formulario de agregar)
     */
    @GetMapping("/actualizar")
    public String actualizoInscripcion(
            Model modelo,
            @RequestParam("id") int id,
            String modo) {
        
        CursoEstudiante cursoEstudiante = cursoEstudianteDao.obtenerCursoEstudiante(id);
        modelo.addAttribute("cursoEstudiante", cursoEstudiante);
        modelo.addAttribute("modo", modo);
        List<Curso> listaCursos = cursoDao.ObtenerCursos();
        List<Estudiante> listaEstudiantes = estudianteDao.listarEstudiantes();
        modelo.addAttribute("listaEstudiantes", listaEstudiantes);
        modelo.addAttribute("listaCursos", listaCursos);
        
        return "cursoEstudiante/agregarCursoEstudiante";
    }
    
    /**
     * Busca inscripciones según los criterios especificados.
     * 
     * @param cursoEstudianteBusqueda DTO con los parámetros de búsqueda
     * @param session Sesión HTTP
     * @param modelo Modelo para pasar datos a la vista
     * @param modo Modo de operación
     * @return Vista "cursoEstudiante/mostrarCursoEstudiante" con los resultados
     */
    @GetMapping("/buscar")
    public String buscarEstudiante(
            @ModelAttribute("cursoEstudianteBusqueda") CursoEstudianteBusqueda cursoEstudianteBusqueda,
            HttpSession session,
            Model modelo,
            String modo) {
        
        String tipo = cursoEstudianteBusqueda.getTipoBusqueda();
        List<CursoEstudiante> listaInscripciones = null;
        String valor = cursoEstudianteBusqueda.getValor();
        
        
        switch(tipo) {
            case "estudiante":
                listaInscripciones = cursoEstudianteDao.buscar(valor,"estudiante");
                break;
            case "curso":
                listaInscripciones = cursoEstudianteDao.buscar(valor,"curso");
                break;
        }
        
        modelo.addAttribute("modo", modo);
        modelo.addAttribute("listaInscripciones", listaInscripciones);
        
        return "cursoEstudiante/mostrarCursoEstudiante";
    }
}