/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.arrebol.taxiservicios.controller.mutual;

import com.arrebol.taxiservicios.controller.connection.ConnectionManager;
import com.arrebol.taxiservicios.controller.util.HibernateUtil;
import com.arrebol.taxiservicios.model.admin.Taxi;
import com.arrebol.taxiservicios.model.catalog.Color;
import com.arrebol.taxiservicios.model.catalog.Location;
import com.arrebol.taxiservicios.model.catalog.Vehicle;
import com.arrebol.taxiservicios.model.core.Person;
import com.arrebol.taxiservicios.model.core.User;
import com.arrebol.taxiservicios.model.enums.PersonType;
import com.arrebol.taxiservicios.model.mutual.MutualOut;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaDelete;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
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 oscarvargas
 */
public class MutualOutController extends ConnectionManager implements Serializable{
    
    public List<Taxi> fillTaxisComboBox() {

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

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

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

            Path<String> id = root.get("id");
            Path<String> placa = root.get("placa");
            Path<String> year = root.get("year");
            Path<Vehicle> vehicle = root.get("vehicle");
            Path<Color> color = root.get("color");

            criteria.select(
                    builder.construct(Taxi.class, id,
                            placa, year, vehicle, color
                    ));

            criteria.where(builder.equal(root.get("active"), Boolean.TRUE));

            criteria.orderBy(
                    builder.asc(root.get("placa"))
            );
            criteria.orderBy(
                    builder.asc(root.get("year"))
            );

            result = session.createQuery(criteria).getResultList();
            transaction.commit();
            logger.info("Total of taxis found for ComboBox: " + (null == result ? -1 : result.size()));
        } catch (HibernateException e) {
            logger.error("Can not load list of taxis for ComboBox ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method fillTaxisComboBox of Sale", e);
            rollback(transaction);
        }

        return result;
    }
    
    public List<MutualOut> fillDataTableBetweenDates(Date starDate, Date endDate, Location location) {
        logger.info("fillDataTableBetweenDates");

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

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

            results = session.createQuery("SELECT exp FROM MutualOut exp "
                    + "WHERE exp.active = 1 AND "
                    + "(DATE(exp.createdOn) BETWEEN DATE(:starDate) AND DATE(:endDate)) AND "
                    + "exp.location.id = :location ORDER BY exp.createdOn DESC")
                    .setParameter("starDate", starDate)
                    .setParameter("endDate", endDate)
                    .setParameter("location", location.getId())
                    .getResultList();

            transaction.commit();
            logger.info("Total of MutualOut founds in auto complete search " + results.size());
        } catch (HibernateException e) {
            rollback(transaction);
            logger.error("Can not load auto complete list of MutualOut", e);
        } catch (Exception e) {
            rollback(transaction);
            logger.error("Method fillDataTableBetweenDates", e);
        }

        return results;
    }

    public List<Person> fillDriversComboBox() {

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

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

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

            Path<String> idPath = root.get("id");
            Path<String> firstNamePath = root.get("firstName");
            Path<String> secondNamePath = root.get("secondName");
            Path<String> lastNamePath = root.get("lastName");
            Path<String> middleNamePath = root.get("middleName");

            criteria.select(
                    builder.construct(Person.class, idPath, firstNamePath, secondNamePath, lastNamePath, middleNamePath
                    ));

            criteria.where(builder.equal(root.get("personType"), PersonType.DRIVER));
            
            criteria.orderBy(
                    builder.asc(root.get("firstName")),
                    builder.asc(root.get("secondName")),
                    builder.asc(root.get("lastName")),
                    builder.asc(root.get("middleName"))
            );

            result = session.createQuery(criteria).getResultList();
            transaction.commit();
            logger.info("Total of drivers found for datatable: " + (null == result ? -1 : result.size()));
        } catch (HibernateException e) {
            logger.error("Can not load list of drivers for datatable ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method fillDriversComboBox of Sanction", e);
            rollback(transaction);
        }

        return result;
    }
    
    public boolean addMutualOut(MutualOut mutual, String userName, String driverId, String taxiId) {
        logger.info("addMutualAdd");
        boolean success = false;

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

            mutual.setCreatedBy(new User(userName, ""));
            if(driverId != null && !driverId.isEmpty())
                mutual.setDriver(new Person(driverId));
            else
                mutual.setDriver(null);
            
            if(taxiId != null && !taxiId.isEmpty())
                mutual.setTaxi(new Taxi(taxiId));
            else
                mutual.setTaxi(null);
            
            mutual.setActive(true);
            session.save(mutual);
            logger.info("MutualOut saved " + mutual.getId());

            transaction.commit();

            success = true;
        } catch (HibernateException e) {
            logger.error("MutualOut can not be added ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method addMutualOut() ", e);
            rollback(transaction);
        }
        return success;
    }
    
   
    public MutualOut getMutualOutById(String mutualOutId) {
        logger.info("getMutualOutById");

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

            mutualOut = session.get(MutualOut.class, mutualOutId);

            transaction.commit();
            logger.info("MutualOut " + mutualOut);
        } catch (HibernateException e) {
            logger.error("MutualOut cannot be loaded " + mutualOutId, e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method getMutualOutById(" + mutualOutId + ") ", e);
            rollback(transaction);
        }
        return mutualOut;
    }
    
    public boolean deleteById(String mutualOutId) {
        logger.info("deleteById");

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

            CriteriaBuilder builder = session.getCriteriaBuilder();

            builder = session.getCriteriaBuilder();
            CriteriaDelete<MutualOut> delete = builder.createCriteriaDelete(MutualOut.class);
            Root<MutualOut> root = delete.from(MutualOut.class);

                delete.where(builder.equal(root.get("id"), mutualOutId));

                int total = session.createQuery(delete).executeUpdate();

            if (1 == total) {
                transaction.commit();
                success = true;
                logger.info("MutualOut " + mutualOutId + " deleted");
            } else {
                transaction.rollback();
                logger.error("Error MutualOut deleted total: " + total);
            }
        } catch (HibernateException e) {
            logger.error("MutualOut can not be deleted ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method deleteById() ", e);
            rollback(transaction);
        }
        return success;
    }
    
    private static final long serialVersionUID = 1020525241432403643L;
    
    final Logger logger = LogManager.getLogger(MutualOutController.class);

    public MutualOutController() {
    }
    
}
