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

import com.arrebol.taxiservicios.controller.connection.ConnectionManager;
import com.arrebol.taxiservicios.controller.util.HibernateUtil;
import com.arrebol.taxiservicios.model.admin.Service;
import com.arrebol.taxiservicios.model.catalog.Location;
import com.arrebol.taxiservicios.model.core.User;
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.CriteriaDelete;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.CriteriaUpdate;
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 ServiceController extends ConnectionManager implements Serializable {

    /**
     *
     * Searching all services for list.
     *
     * @return
     */
    public List<Service> fillServiceDatatable() {

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

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

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

           /* Path<String> idPath = root.get("id");
            Path<String> namePath = root.get("name");
            Path<String> chargePath = root.get("charge");
            Path<String> discountPath = root.get("discountFix");

            criteria.select(
                    builder.construct(Service.class, idPath, namePath, chargePath, discountPath
                    ));*/

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

            logger.info("Total of services found : " + (null == result ? -1 : result.size()));
            transaction.commit();
        } catch (HibernateException e) {
            logger.error("Can not load list of services ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method fillServiceDatatable of Service", e);
            rollback(transaction);
        }

        return result;
    }
    
    public List<Service> fillServiceDatatableByLocation(String idLocation) {

        Transaction transaction = null;
        List<Service> result = null;
        
        logger.info("******************************** id location*******************+");
        logger.info(idLocation);

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

            CriteriaQuery<Service> criteria = builder.createQuery(Service.class);
            Root<Service> root = criteria.from(Service.class);
            /*
            Path<String> idPath = root.get("id");
            Path<String> namePath = root.get("name");
            Path<String> chargePath = root.get("charge");
            Path<String> discountPath = root.get("discountFix");

            criteria.select(
                    builder.construct(Service.class, idPath, namePath, chargePath, discountPath
                    ));*/
            
            criteria.where(builder.equal(root.get("location"), new Location(idLocation)));

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

            logger.info("Total of services found : " + (null == result ? -1 : result.size()));
            transaction.commit();
        } catch (HibernateException e) {
            logger.error("Can not load list of services ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method fillServiceDatatable of Service", e);
            rollback(transaction);
        }

        return result;
    }

    public void saveService(Service service, String userId) {
        Transaction transaction = null;

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

            if (service.getId() != null) {
                CriteriaUpdate<Service> update = builder.createCriteriaUpdate(Service.class);
                Root<Service> root = update.from(Service.class);

                update.set("name", service.getName());
                update.set("charge", service.getCharge());
                update.set("discountFix", service.getDiscountFix());
                update.set("lastUpdatedBy", new User(userId, ""));
                update.set("lastUpdatedOn", new Date());
                update.set("claveUnidad", service.getClaveUnidad());
                update.set("claveProductoServicio",service.getClaveProductoServicio());
                update.where(builder.equal(root.get("id"), service.getId()));

                session.createQuery(update).executeUpdate();

                logger.info("The service was edited - " + service);
            } else {

                service.setId(UUID.randomUUID().toString());
                service.setCreatedBy(new User(userId, ""));
                service.setCreatedOn(new Date());
                session.save(service);
                logger.info("The service was saved - " + service);
            }

            transaction.commit();
        } catch (HibernateException e) {
            logger.error("The service can not be saved - " + service, e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method saveService(" + service + ")", e);
            rollback(transaction);
        }
    }

    public void deleteService(Service service) {

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

            if (service.getId() != null) {
                CriteriaDelete<Service> delete = builder.createCriteriaDelete(Service.class);
                Root<Service> root = delete.from(Service.class);

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

                session.createQuery(delete).executeUpdate();

                logger.info("The service was deleted - " + service.getId());
            }
            transaction.commit();
        } catch (HibernateException e) {
            logger.error("The service can not be deleted - " + service, e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method  deleteService(" + service + ")", e);
            rollback(transaction);
        }
    }

    private static final long serialVersionUID = -559465932081273592L;

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

    public ServiceController() {
    }

}
