/*
 * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
 * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
 */
package com.arrebol.taxiservicios.controller.predio;

import com.arrebol.taxiservicios.controller.admin.GenericPersonController;
import com.arrebol.taxiservicios.controller.util.HibernateUtil;
import com.arrebol.taxiservicios.model.core.User;
import com.arrebol.taxiservicios.model.enums.GenericEnumType;
import com.arrebol.taxiservicios.model.predio.DetalleLoteUrbanizacion;
import com.arrebol.taxiservicios.model.predio.Lote;
import com.arrebol.taxiservicios.model.predio.Predio;
import com.arrebol.taxiservicios.model.predio.Urbanizacion;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 *
 * @author Usuario
 */
public class UrbanizacionController extends GenericPersonController implements Serializable {

    private static final long serialVersionUID = -6265444716269535946L;

    final Logger logger = LogManager.getLogger(UrbanizacionController.class);

    public boolean disabledUrbanizacion(Urbanizacion urbanizacion, User user) {
        logger.info("disabledUrbanizacion");
        boolean success = false;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            urbanizacion.setLastUpdatedBy(user);
            urbanizacion.setLastUpdatedOn(new Date());
            session.update(urbanizacion);
            transaction.commit();
            logger.info("Urbanizacion updated " + urbanizacion.getId());
        } catch (HibernateException e) {
            logger.error("Urbanizacion can not be added ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method addUrbanizacion() ", e);
            rollback(transaction);
        }
        return success;
    }

    public boolean addUrbanizacion(Urbanizacion urbanizacion, User user) {
        logger.info("addUrbanizacion");

        boolean success = false;

        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            if (urbanizacion.getId() == null) {
                urbanizacion.setId(UUID.randomUUID().toString());
                urbanizacion.setCreatedBy(user);
                urbanizacion.setCreatedOn(new Date());
                session.save(urbanizacion);
                transaction.commit();
                logger.info("Urbanizacion saved " + urbanizacion.getId());
            } else {
                urbanizacion.setLastUpdatedBy(user);
                session.update(urbanizacion);
                transaction.commit();
                logger.info("Urbanizacion updated " + urbanizacion.getId());
            }

            success = true;
        } catch (HibernateException e) {
            logger.error("Urbanizacion can not be added ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method addUrbanizacion() ", e);
            rollback(transaction);
        }
        return success;
    }

    public List<Urbanizacion> fillAllUrbanizacionesByPredio(Predio predio) {
        logger.info("Searching all urbanizaciones..");

        List<Urbanizacion> result = null;
        Transaction transaction = null;

        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

            CriteriaQuery<Urbanizacion> criteria = builder.createQuery(Urbanizacion.class);
            Root<Urbanizacion> root = criteria.from(Urbanizacion.class);

            Predicate criteriaPredio = builder.equal(root.get("predio"), predio);
            Predicate criteriaActivo = builder.equal(root.get("activo"), GenericEnumType.ENABLED);
            criteria.where(builder.and(criteriaActivo, criteriaPredio));

            criteria.orderBy(builder.desc(root.get("createdOn")));
            result = session.createQuery(criteria).getResultList();

            logger.info("Total of urbanizaciones found: " + (null == result ? -1 : result.size()));
            transaction.commit();
        } catch (HibernateException e) {
            rollback(transaction);
            logger.error("Unable to load urbanizaciones list ", e);
        } catch (Exception e) {
            rollback(transaction);
            logger.error("Method fillAllUrbanizacionesByPredio", e);
        }

        return result;
    }

    public boolean checkIfUrbanizacionExistsByPredio(String  idPredio) {
        logger.info("Checking if any urbanizacion exists...");

        boolean exists = false;
        Transaction transaction = null;

        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

            CriteriaQuery<Long> criteria = builder.createQuery(Long.class);
            Root<Urbanizacion> root = criteria.from(Urbanizacion.class);

            criteria.select(builder.count(root));
            Predicate criteriaPredio = builder.equal(root.get("predio").get("id"), idPredio);
            Predicate criteriaActivo = builder.equal(root.get("activo"), GenericEnumType.ENABLED);
            criteria.where(builder.and(criteriaActivo, criteriaPredio));

            Long count = session.createQuery(criteria).getSingleResult();
            exists = count > 0;

            logger.info("Urbanizacion exists: " + exists);
            transaction.commit();
        } catch (HibernateException e) {
            rollback(transaction);
            logger.error("Unable to check if urbanizacion exists", e);
        } catch (Exception e) {
            rollback(transaction);
            logger.error("Method checkIfUrbanizacionExistsByPredio", e);
        }

        return exists;
    }
    
        public List<DetalleLoteUrbanizacion> fillAllDetalleLoteUrbanizacionByLote(Lote lote) {
        logger.info("Searching all detalles urbanizaciones..");

        List<DetalleLoteUrbanizacion> result = null;
        Transaction transaction = null;

        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

            CriteriaQuery<DetalleLoteUrbanizacion> criteria = builder.createQuery(DetalleLoteUrbanizacion.class);
            Root<DetalleLoteUrbanizacion> root = criteria.from(DetalleLoteUrbanizacion.class);

            Predicate criteriaLote = builder.equal(root.get("lote"), lote);
            criteria.where(builder.and(criteriaLote));

            criteria.orderBy(builder.desc(root.get("createdOn")));
            result = session.createQuery(criteria).getResultList();

            logger.info("Total of detalles urbanizaciones found: " + (null == result ? -1 : result.size()));
            transaction.commit();
        } catch (HibernateException e) {
            rollback(transaction);
            logger.error("Unable to load detalles urbanizaciones list ", e);
        } catch (Exception e) {
            rollback(transaction);
            logger.error("Method fillAllDetalleLoteUrbanizacionByLote", e);
        }

        return result;
    }

}
