/*
 * Arrebol Consultancy copyright.
 * 
 * This code belongs to Arrebol Consultancy
 * its use, redistribution or modification are prohibited 
 * without written authorization from Arrebol Consultancy.
 */
package com.arrebol.taxiservicios.controller.admin;

import com.arrebol.taxiservicios.controller.connection.ConnectionManager;
import com.arrebol.taxiservicios.controller.util.HibernateUtil;
import com.arrebol.taxiservicios.model.catalog.Location;
import com.arrebol.taxiservicios.model.enums.FeeType;
import com.arrebol.taxiservicios.model.enums.PersonType;
import com.arrebol.taxiservicios.model.view.PersonListView;
import com.arrebol.taxiservicios.model.view.admin.FeeByDriverAdminView;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import javax.persistence.Query;
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 Lopez <janitzio.zavala@arrebol.com.mx>
 */
public class FeeByDriverAdminViewController extends ConnectionManager implements Serializable {

    /**
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public List<FeeByDriverAdminView> findFeesBetweenDates(Date startDate, Date endDate) {
        List<FeeByDriverAdminView> results = null;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            StringBuilder hql = new StringBuilder("From FeeByDriverAdminView WHERE ");

            hql.append("DATE(feeDate) BETWEEN DATE(:startDate) AND DATE(:endDate) ");
            hql.append("ORDER BY feeDate");

            results = session.createQuery(hql.toString(), FeeByDriverAdminView.class)
                    .setParameter("startDate", startDate)
                    .setParameter("endDate", endDate)
                    .getResultList();

            transaction.commit();
        } catch (HibernateException e) {
            logger.error("List can not be loaded findFeesBetweenDates", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findFeesBetweenDates() ", e);
            rollback(transaction);
        }
        return results;
    }

    /**
     *
     * @param driverId
     * @param startDate
     * @param endDate
     * @param listStatus
     * @return
     */
    public List<FeeByDriverAdminView> searchFees(String driverId, Date startDate, Date endDate, List<FeeType> listStatus, Location location) {
        List<FeeByDriverAdminView> results = null;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            StringBuilder hql = new StringBuilder("From FeeByDriverAdminView WHERE ");

            hql.append("(DATE(feeDate) BETWEEN DATE(:startDate) AND DATE(:endDate)) AND location.id = :location ");

            if (null != driverId) {
                hql.append("AND driverId = :driverId ");
            }

            if (!listStatus.isEmpty()) {
                hql.append("AND status IN(:listStatus) ");
            }

            hql.append("ORDER BY feeDate");

            Query query = session.createQuery(hql.toString(), FeeByDriverAdminView.class);

            query.setParameter("startDate", startDate);
            query.setParameter("endDate", endDate);
            query.setParameter("location", location.getId());

            if (null != driverId) {
                query.setParameter("driverId", driverId);
            }

            if (!listStatus.isEmpty()) {
                query.setParameter("listStatus", listStatus);
            }

            results = query.getResultList();

            transaction.commit();
        } catch (HibernateException e) {
            logger.error("List can not be loaded findFeesBetweenDates", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findFeesBetweenDates() ", e);
            rollback(transaction);
        }
        return results;
    }

    /**
     *
     * @param driverId
     * @return
     */
    public List<FeeByDriverAdminView> findFeesByDriver(String driverId, Location location) {
        List<FeeByDriverAdminView> results = null;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            StringBuilder hql = new StringBuilder("From FeeByDriverAdminView WHERE ");

            hql.append("driverId = :driverId ");
            hql.append("AND location.id = :location ");
            hql.append("ORDER BY feeDate");

            results = session.createQuery(hql.toString(), FeeByDriverAdminView.class)
                    .setParameter("driverId", driverId)
                    .setParameter("location", location.getId())
                    .getResultList();

            transaction.commit();
        } catch (HibernateException e) {
            logger.error("List can not be loaded findFeesByDriver", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findFeesByDriver() ", e);
            rollback(transaction);
        }
        return results;
    }

    /**
     *
     * @param listStatus
     * @return
     */
    public List<FeeByDriverAdminView> findFeesInStatus(List<FeeType> listStatus, Location location) {
        List<FeeByDriverAdminView> results = null;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            StringBuilder hql = new StringBuilder("From FeeByDriverAdminView WHERE ");

            hql.append("status IN(:listStatus) ");
            hql.append("AND location.id = :location ");
            hql.append("ORDER BY feeDate");

            results = session.createQuery(hql.toString(), FeeByDriverAdminView.class)
                    .setParameter("listStatus", listStatus)
                    .setParameter("location", location.getId())
                    .getResultList();

            transaction.commit();
        } catch (HibernateException e) {
            logger.error("List can not be loaded findFeesInStatus", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findFeesInStatus() ", e);
            rollback(transaction);
        }
        return results;
    }

    /**
     *
     * @param searchFullName
     * @return
     */
    public List<PersonListView> likeDriverName(String searchFullName) {
        List<PersonListView> results = null;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            CriteriaBuilder builder = session.getCriteriaBuilder();
            CriteriaQuery<PersonListView> query = builder.createQuery(PersonListView.class);
            Root<PersonListView> root = query.from(PersonListView.class);

            Path<String> id = root.get("id");
            Path<String> fullName = root.get("fullName");

            Predicate likeFullName = builder.like(root.get("fullName"), searchFullName);
            Predicate equalToDriver = builder.equal(root.get("type"), PersonType.DRIVER);

            query.select(builder.construct(PersonListView.class, id, fullName));
            query.where(likeFullName, equalToDriver);
            query.orderBy(builder.asc(root.get("fullName")));

            results = session.createQuery(query).getResultList();

            transaction.commit();
        } catch (HibernateException e) {
            logger.error("List can not be loaded likeDriverName", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method likeDriverName() ", e);
            rollback(transaction);
        }
        return results;
    }

    private static final long serialVersionUID = -1L;

    final Logger logger = LogManager.getLogger(getClass());
}
