package es.pulsoft.dao;

import java.util.List;

import javax.transaction.Transactional;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import es.pulsoft.controlador.entity.Director;

/**
 * Clase DAO para gestionar las operaciones relacionadas con la entidad Director.
 * Implementa la interfaz DirectorDao.
 * Las operaciones incluyen agregar, obtener, listar, eliminar y buscar directores.
 */
@Repository
public class DirectorDaoClase implements DirectorDao {

    @Autowired
    private SessionFactory sessionFactory;

    /**
     * Agrega o actualiza un director en la base de datos.
     * 
     * @param director el objeto Director que contiene la información del director a agregar o actualizar.
     */
    @Override
    @Transactional
    public void addDirector(Director director) {
        try {
            // Obtiene la sesión actual de Hibernate
            Session session = sessionFactory.getCurrentSession();
            // Guarda o actualiza el director
            session.saveOrUpdate(director);
            session.flush();
        } catch (Exception e) {
            // Imprime el error en caso de excepciones
            e.printStackTrace();
        }
    }

    /**
     * Obtiene una lista de todos los directores en la base de datos.
     * 
     * @return una lista de objetos Director.
     */
    @Override
    @Transactional
    public List<Director> listaDirectores() {
        try {
            // Obtiene la sesión actual de Hibernate
            Session session = sessionFactory.getCurrentSession();
            // Ejecuta la consulta HQL para obtener todos los directores
            List<Director> listaDirectores = session.createQuery("from Director", Director.class).getResultList();
            return listaDirectores;
        } catch (Exception e) {
            // Imprime el error en caso de excepciones
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Obtiene un director por su ID.
     * 
     * @param id el ID del director a obtener.
     * @return el objeto Director correspondiente al ID.
     */
    @Override
    @Transactional
    public Director getDirector(int id) {
        try {
            // Obtiene la sesión actual de Hibernate
            Session session = sessionFactory.getCurrentSession();
            // Obtiene el director por su ID
            Director director = session.get(Director.class, id);
            return director;
        } catch (Exception e) {
            // Imprime el error en caso de excepciones
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Elimina un director de la base de datos.
     * 
     * @param director el objeto Director que se va a eliminar.
     */
    @Override
    @Transactional
    public void borrarDirector(Director director) {
        try {
            // Obtiene la sesión actual de Hibernate
            Session session = sessionFactory.getCurrentSession();
            // Elimina el director
            session.delete(director);
        } catch (Exception e) {
            // Imprime el error en caso de excepciones
            e.printStackTrace();
        }
    }

    /**
     * Realiza una búsqueda de directores en la base de datos basándose en un campo y valor de búsqueda.
     * 
     * @param campo el campo en el que se realizará la búsqueda (por ejemplo, "nombre").
     * @param valor el valor que se busca en el campo especificado.
     * @return una lista de objetos Director que coinciden con los criterios de búsqueda.
     */
    @Override
    @Transactional
    public List<Director> busquedaDirector(String campo, String valor) {
        List<Director> listaDirectores = null;
        try {
            // Obtiene la sesión actual de Hibernate
            Session session = sessionFactory.getCurrentSession();
            // Ejecuta la consulta HQL con el campo y valor proporcionado, ignorando mayúsculas y minúsculas
            listaDirectores = session.createQuery("from Director where lower(" + campo + ") like lower(:valor)", Director.class)
                                     .setParameter("valor", valor + "%")
                                     .getResultList();
            return listaDirectores;
        } catch (Exception e) {
            // Devuelve null en caso de error
            return listaDirectores;
        }
    }
}
