package com.arrebol.taxiservicios.controller.stocktaking;

import com.arrebol.taxiservicios.controller.connection.ConnectionManager;
import com.arrebol.taxiservicios.controller.util.HibernateUtil;
import com.arrebol.taxiservicios.model.catalog.Brand;
import com.arrebol.taxiservicios.model.enums.BrandType;
import com.arrebol.taxiservicios.model.stocktaking.view.KardexOutStocktakingView;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
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 Carlos Janitzio Zavala López.
 */
public class KardexOutStocktakingController extends ConnectionManager implements Serializable {


    /**
     *
     * @param starDate
     * @param endDate
     * @return
     */
    public List<KardexOutStocktakingView> fillDatatable(Date starDate, Date endDate) {
        LOG.info("Searching all kardex Out..");

        List<KardexOutStocktakingView> result = null;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            String query = "SELECT exp FROM KardexOutStocktakingView exp "
                    + "WHERE DATE(exp.fecha) BETWEEN DATE(:starDate) AND DATE(:endDate) "
                    + "ORDER BY DATE(exp.fecha), exp.ordenServicio DESC";

            result = session.createQuery(query)
                    .setParameter("starDate", starDate)
                    .setParameter("endDate", endDate)
                    .getResultList();

            transaction.commit();
            LOG.info("Total of kardex out found for datatable: " + (null == result ? -1 : result.size()));
        } catch (HibernateException e) {
            LOG.error("Can not load list of kardex out for datstable ", e);
            rollback(transaction);
        } catch (Exception e) {
            LOG.error("Method fillDatatable of kardex in", e);
            rollback(transaction);
        }

        return result;
    }
    
    
    public List<KardexOutStocktakingView> fillKardexOutDataTableBetweenDates(Date starDate, Date endDate, String location) {
        LOG.info("fillExpenseDataTableBetweenDates");

        List<KardexOutStocktakingView> results = null;
        Transaction transaction = null;

        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();
            
            CriteriaQuery<KardexOutStocktakingView> query = builder.createQuery(KardexOutStocktakingView.class);
            Root<KardexOutStocktakingView> root = query.from(KardexOutStocktakingView.class);

            Predicate typePredicate = builder.equal(root.get("estatus"), "FINISHED");
            Predicate startDatePredicate = builder.greaterThanOrEqualTo(root.get("payDate"), starDate);
            Predicate endDatePredicate = builder.lessThanOrEqualTo(root.get("payDate"), endDate);
            Predicate locationPredicate = builder.equal(root.get("location"), location);
            
             query.where(builder.and(typePredicate,startDatePredicate, endDatePredicate, locationPredicate
            ));
            query.orderBy(builder.asc(root.get("payDate")));

            results = session.createQuery(query).getResultList();
            transaction.commit();
            LOG.info("Total of Expense founds in auto complete search " + results.size());
        } catch (HibernateException e) {
            rollback(transaction);
            LOG.error("Can not load auto complete list of Expense", e);
        } catch (Exception e) {
            rollback(transaction);
            LOG.error("Method fillExpenseDataTableBetweenDates", e);
        }

        return results;
    }
    
    public List<KardexOutStocktakingView> fillDatatable(Date starDate, Date endDate, String brandId) {
        LOG.info("Searching all kardex Out..");

        List<KardexOutStocktakingView> result = null;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            String query = "SELECT exp FROM KardexOutStocktakingView exp "
                    + "WHERE DATE(exp.fecha) BETWEEN DATE(:starDate) AND DATE(:endDate) AND exp.brandId = :brandId "
                    + "ORDER BY DATE(exp.fecha), exp.ordenServicio DESC";

            result = session.createQuery(query)
                    .setParameter("starDate", starDate)
                    .setParameter("endDate", endDate)
                    .setParameter("brandId", brandId)
                    .getResultList();

            transaction.commit();
            LOG.info("Total of kardex out found for datatable: " + (null == result ? -1 : result.size()));
        } catch (HibernateException e) {
            LOG.error("Can not load list of kardex out for datstable ", e);
            rollback(transaction);
        } catch (Exception e) {
            LOG.error("Method fillDatatable of kardex in", e);
            rollback(transaction);
        }

        return result;
    }
    
    public List<Brand> fillProductBrandComboBox() {

        Transaction transaction = null;
        List<Brand> result = new ArrayList<>();

        try {
            LOG.info("Searching all products brands to select..");
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

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

            Path<String> idPath = root.get("id");
            Path<String> namePath = root.get("name");

            criteria.select(
                    builder.construct(Brand.class, idPath, namePath
                    ));
            criteria.where(builder.equal(root.get("brandType"), BrandType.OTHER));
            criteria.orderBy(builder.asc(root.get("name")));

            result = session.createQuery(criteria).getResultList();

            LOG.info("Total of products brands found for ComboBox: " + (null == result ? -1 : result.size()));
            transaction.commit();
        } catch (HibernateException e) {
            LOG.error("Can not load list of products brands for ComboBox ", e);
            rollback(transaction);
        } catch (Exception e) {
            LOG.error("Method fillProductBrandComboBox of ProductBrand", e);
            rollback(transaction);
        }

        return result;
    }

    

    private static final long serialVersionUID = 3405798902357776578L;

    final Logger LOG = LogManager.getLogger(KardexOutStocktakingController.class);

    }
