package es.pulsoft.controlador;

import java.util.List;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import es.pulsoft.controlador.dto.DirectorBusqueda;
import es.pulsoft.controlador.entity.Director;
import es.pulsoft.dao.DirectorDao;

/**
 * Controlador encargado de gestionar las operaciones relacionadas con los directores.
 * Incluye funcionalidades para agregar, actualizar, eliminar, listar y buscar directores.
 */
@Controller
@RequestMapping("/Director")
public class DirectorControlador {

    @Autowired
    private DirectorDao directorDao;

    /**
     * Muestra la página de inicio.
     * 
     * @return nombre de la vista de inicio.
     */
    @GetMapping("/")
    public String paginaInicio() {
        return "index";
    }

    /**
     * Muestra el formulario para agregar un nuevo director.
     * 
     * @param modelo modelo de la vista.
     * @param modo modo de operación (normal o actualización).
     * @return nombre de la vista del formulario.
     */
    @GetMapping("/agregarDirector")
    public String mostrarFormulario(Model modelo, String modo) {
        modelo.addAttribute("director", new Director());
        modelo.addAttribute("modo", modo);
        return "director/agregarDirector";
    }

    /**
     * Guarda o actualiza un director en la base de datos.
     * 
     * @param director objeto Director a guardar o actualizar.
     * @param result resultado de la validación.
     * @param modo modo de operación.
     * @param session sesión actual del usuario.
     * @param modelo modelo de la vista.
     * @return redirección a la página correspondiente según el resultado.
     */
    @PostMapping("/agregarDirector")
    public String guardarDirector(@Valid @ModelAttribute("director") Director director,
                                  BindingResult result,
                                  @RequestParam String modo,
                                  HttpSession session,
                                  Model modelo) {
        modelo.addAttribute("modo", modo);
        try {
            if (result.hasErrors()) {
                return "director/agregarDirector";
            } else {
                directorDao.addDirector(director);
                if (modo.contentEquals("normal")) {
                    session.setAttribute("mensaje", "Director guardado correctamente");
                    return "redirect:/";
                } else {
                    session.setAttribute("mensaje", "Director actualizado correctamente");
                    return "redirect:/";
                }
            }
        } catch (Exception e) {
            if (modo.contentEquals("normal")) {
                session.setAttribute("error", "Error al guardar el director");
            } else {
                session.setAttribute("error", "Error al actualizar el director");
            }
            return "redirect:/";
        }
    }

    /**
     * Muestra la lista de todos los directores existentes.
     * 
     * @param modelo modelo de la vista.
     * @param modo modo de operación (ej: búsqueda, eliminación).
     * @return nombre de la vista para mostrar los directores.
     */
    @GetMapping("/mostrarDirector")
    public String mostrarDirector(Model modelo, String modo) {
        List<Director> listaDirectores = directorDao.listaDirectores();
        modelo.addAttribute("listaDirectores", listaDirectores);
        modelo.addAttribute("modo", modo);
        DirectorBusqueda directorBusqueda = new DirectorBusqueda();
        modelo.addAttribute("directorBusqueda", directorBusqueda);
        return "director/mostrarDirector";
    }

    /**
     * Carga los datos de un director específico para su actualización.
     * 
     * @param id identificador del director.
     * @param modelo modelo de la vista.
     * @param modo modo de operación.
     * @return nombre de la vista del formulario.
     */
    @GetMapping("/actualizar")
    public String actualizarDirector(@RequestParam("id") int id, Model modelo, String modo) {
        try {
            Director director = directorDao.getDirector(id);
            modelo.addAttribute("director", director);
            modelo.addAttribute("modo", modo);
            return "director/agregarDirector";
        } catch (Exception e) {
            return "index";
        }
    }

    /**
     * Elimina un director por su ID.
     * 
     * @param id identificador del director.
     * @param modelo modelo de la vista.
     * @return redirección a la vista de mostrar directores.
     */
    @RequestMapping(value = "/borrar", method = {RequestMethod.GET, RequestMethod.POST})
    public String borrarDirector(@RequestParam("id") int id, Model modelo) {
        try {
            Director director = directorDao.getDirector(id);
            directorDao.borrarDirector(director);
            modelo.addAttribute("mensaje", "Director borrado correctamente");
        } catch (Exception e) {
            modelo.addAttribute("error", "Error al borrar al director");
        }
        return "redirect:/Director/mostrarDirector?modo=borrar";
    }

    /**
     * Realiza una búsqueda de directores en función del tipo y valor de búsqueda.
     * 
     * @param directorBusqueda objeto con los criterios de búsqueda.
     * @param modo modo de operación.
     * @param modelo modelo de la vista.
     * @return nombre de la vista para mostrar los resultados de la búsqueda.
     */
    @GetMapping("/buscar")
    public String buscarDirector(@ModelAttribute("directorBusqueda") DirectorBusqueda directorBusqueda,
                                 @RequestParam("modo") String modo,
                                 Model modelo) {

        try {
            String valor = directorBusqueda.getValor();
            String campo = directorBusqueda.getTipoBusqueda();

            // Validación de término de búsqueda
            if (valor == null || valor.trim().isEmpty()) {
                modelo.addAttribute("error", "Debe ingresar un término de búsqueda");
                return "director/mostrarDirector";
            }

            System.out.println(campo);
            System.out.println(valor);
            List<Director> listaDirectores = directorDao.busquedaDirector(campo, valor);

            modelo.addAttribute("listaDirectores", listaDirectores);
            modelo.addAttribute("modo", modo);
            modelo.addAttribute("directorBusqueda", directorBusqueda);

            if (listaDirectores != null) {
                modelo.addAttribute("mensaje", "Un total de " + listaDirectores.size() + " encajan con la búsqueda");
            } else {
                modelo.addAttribute("mensaje", "No hay directores que encajen con la búsqueda");
            }
        } catch (Exception e) {
            modelo.addAttribute("error", "Fallo en la búsqueda");
        }

        return "director/mostrarDirector";
    }
}
