/*
 * 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.admin;

import com.arrebol.taxiservicios.controller.connection.ConnectionManager;
import com.arrebol.taxiservicios.controller.util.HibernateUtil;
import com.arrebol.taxiservicios.model.core.Person;
import com.arrebol.taxiservicios.model.dashboard.ToCollect;
import java.io.Serializable;
import java.util.ArrayList;
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 Picasso
 */
public class AdminSalesController extends ConnectionManager implements Serializable {

    /**
     * Get all drivers that has a taxi assigned.
     *
     * @return List of all Drivers
     */
    public List<Person> getAllDrivers() {
        logger.info("getAllDrivers");
        List<Person> persons = new ArrayList<>();

        Transaction transaction = null;

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

            String query = "SELECT P FROM Person P"
                    + " INNER JOIN Taxi TX on P.id = TX.driver"
                    + " WHERE P.active = true";

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

            transaction.commit();
            logger.info("Driver's list " + persons);
        } catch (HibernateException e) {
            logger.error("Can not load all drivers ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method getAllDrivers() ", e);
            rollback(transaction);
        }
        return persons;
    }

    public List<ToCollect> getAllToCollectsByDriver(Person driver) {
        logger.info("getAllToCollectsByDriver");
        List<ToCollect> toCollects = new ArrayList<>();

        Transaction transaction = null;

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

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

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

            criteria.select(builder.construct(ToCollect.class, id, collect));
            criteria.where(builder.equal(root.get("driver"), driver));
            criteria.orderBy(builder.asc(root.get("collect")));

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

            transaction.commit();
            logger.info("To Collect's list " + toCollects);
        } catch (HibernateException e) {
            logger.error("Can not load all to colelcts ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method getAllToCollectsByDriver() ", e);
            rollback(transaction);
        }
        return toCollects;
    }

    /**
     * Add a new register in table TO_COLLECT.
     *
     * First validate that register doesn't exist, if doesn't exist save
     * otherwise return false.
     *
     * @param collect New register to save in TO_COLLECT table.
     * @return True if add a new record otherwise false.
     */
    public boolean addToCollect(ToCollect collect) {
        logger.info("addToCollect");

        boolean success = false;
        Transaction transaction = null;

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

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

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

            criteria.select(builder.construct(ToCollect.class, id));
            criteria.where(
                    builder.and(
                            builder.equal(root.get("collect"), collect.getCollect()),
                            builder.equal(root.get("driver"), collect.getDriver())
                    )
            );

            ToCollect tc = session.createQuery(criteria).uniqueResult();

            if (null == tc) {
                session.save(collect);
                transaction.commit();

                logger.info("To collect saved " + collect);

                success = true;
            } else {
                transaction.rollback();
            }
        } catch (HibernateException e) {
            logger.error("Can not add the to collect " + collect, e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method addToCollect(" + collect + ") ", e);
            rollback(transaction);
        }
        return success;
    }

    /**
     * Delete to collect by ID.
     *
     * @param id Primary key of TO_COLLECT table.
     * @return True if ID was deleted otherwise false.
     */
    public boolean deleteToCollect(String id) {
        logger.info("deleteToCollect");

        boolean success = false;
        Transaction transaction = null;

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

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

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

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

            transaction.commit();
            logger.info("To collect deleted");

            success = true;
        } catch (HibernateException e) {
            logger.error("Can not delete the to collect id = " + id, e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method deleteToCollect(" + id + ") ", e);
            rollback(transaction);
        }
        return success;
    }

    private static final long serialVersionUID = -6524705452020500808L;

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

}
