/*
 * 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.beans.stocktaking.service.order;

import com.arrebol.taxiservicios.beans.TaxiGenericBean;
import com.arrebol.taxiservicios.controller.admin.GenericValidationController;
import com.arrebol.taxiservicios.controller.catalog.BankCardController;
import com.arrebol.taxiservicios.controller.catalog.BankCardKardexController;
import com.arrebol.taxiservicios.controller.catalog.LocationController;
import com.arrebol.taxiservicios.controller.stocktaking.ServiceOrderController;
import com.arrebol.taxiservicios.controller.stocktaking.ServiceOrderSingletonController;
import com.arrebol.taxiservicios.model.catalog.BankCard;
import com.arrebol.taxiservicios.model.catalog.BankCardKardex;
import com.arrebol.taxiservicios.model.catalog.Location;
import com.arrebol.taxiservicios.model.core.Person;
import com.arrebol.taxiservicios.model.core.User;
import com.arrebol.taxiservicios.model.enums.BankCardKardexType;
import com.arrebol.taxiservicios.model.enums.BasicType;
import com.arrebol.taxiservicios.model.enums.ServiceOrderType;
import com.arrebol.taxiservicios.model.stocktaking.ServiceOrder;
import com.arrebol.taxiservicios.model.stocktaking.ServiceOrderHasProduct;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 *
 * @author oscarvargas
 */
@Named
@ViewScoped
public class GarageListBean extends TaxiGenericBean implements Serializable {

    /**
     *
     */
    public void searchServiceOrder() {
        logger.info("searchServiceOrder");
        try {
            Calendar start = Calendar.getInstance();
            Calendar end = Calendar.getInstance();

            start.setTime(getStartDate());
            start.set(Calendar.HOUR_OF_DAY, 0);
            start.set(Calendar.MINUTE, 0);
            start.set(Calendar.SECOND, 0);

            end.setTime(null == getEndDate() ? getToday() : getEndDate());
            end.set(Calendar.HOUR_OF_DAY, 23);
            end.set(Calendar.MINUTE, 59);
            end.set(Calendar.SECOND, 59);

            setServiceOrders(getController().getAllServiceOrderActiveAndStatusIn(Arrays.asList(getSelectedTypes()), 
                    start.getTime(), end.getTime(),new Location(getLocationId())));
        } catch (Exception e) {
            logger.error("searchServiceOrder", e);
            showMessage(FacesMessage.SEVERITY_ERROR,
                    getBundlePropertyFile().getString("manager.search.title"),
                    getBundlePropertyFile().getString("manager.search.exception.desc"));
        }
    }

    public void inProgress() {
        logger.info("inProgress: ");
        try {
            if (getApproved().equals(getSelectedServiceOrder().getServiceOrderType())) {
                if (getSingletonController().workWithServiceOrder(4, getSelectedServiceOrder().getId(), null, null, getLoggedUser().getId(), null, null, null, getLoggedUser().getLocation())) {
                    //if (getController().updateStatus(getSelectedServiceOrder().getId(), ServiceOrderType.PROGRESS, getLoggedUser().getId())) {

                    /*
                    getServiceOrders().remove(getSelectedServiceOrder());
                    getSelectedServiceOrder().setServiceOrderType(ServiceOrderType.PROGRESS);
                    getServiceOrders().add(getSelectedServiceOrder());
                     */
                    loadServiceOrderList();

                    showMessage(FacesMessage.SEVERITY_INFO,
                            getBundlePropertyFile().getString("garage.title"),
                            getBundlePropertyFile().getString("garage.progress.desc"));
                } else {
                    logger.error(getBundlePropertyFile().getString("garage.progress.error"));
                    showMessage(FacesMessage.SEVERITY_ERROR,
                            getBundlePropertyFile().getString("garage.title"),
                            getBundlePropertyFile().getString("garage.progress.error"));
                }
            } else {
                logger.error("Status " + getSelectedServiceOrder().getServiceOrderType() + ", waiting for " + getApproved());
                showMessage(FacesMessage.SEVERITY_ERROR,
                        getBundlePropertyFile().getString("garage.title"),
                        getBundlePropertyFile().getString("garage.progress.error"));
            }

        } catch (Exception e) {
            logger.error("inProgress: " + e);
            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("garage.title"),
                    getBundlePropertyFile().getString("garage.progress.exception"));
        }
    }

    public void finishOrder() {
        logger.info("finishOrder: ");
        try {
            if (getProgress().equals(getSelectedServiceOrder().getServiceOrderType())) {
                if (getSingletonController().workWithServiceOrder(5, getSelectedServiceOrder().getId(), null, null, getLoggedUser().getId(), null, null, null, getLoggedUser().getLocation())) {
                    //if (getController().updateStatus(getSelectedServiceOrder().getId(), ServiceOrderType.FINISHED, getLoggedUser().getId())) {
                    showMessage(FacesMessage.SEVERITY_INFO,
                            getBundlePropertyFile().getString("garage.title"),
                            getBundlePropertyFile().getString("garage.finish.desc"));

                    // getServiceOrders().remove(getSelectedServiceOrder());
                    loadServiceOrderList();
                } else {
                    logger.error(getBundlePropertyFile().getString("garage.finish.error"));
                    showMessage(FacesMessage.SEVERITY_ERROR,
                            getBundlePropertyFile().getString("garage.title"),
                            getBundlePropertyFile().getString("garage.finish.error"));
                }
            } else {
                logger.error("Status " + getSelectedServiceOrder().getServiceOrderType() + ", waiting for " + getProgress());
                showMessage(FacesMessage.SEVERITY_ERROR,
                        getBundlePropertyFile().getString("garage.title"),
                        getBundlePropertyFile().getString("garage.finish.error"));
            }

        } catch (Exception e) {
            logger.error("finishOrder: " + e);
            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("garage.title"),
                    getBundlePropertyFile().getString("garage.finish.exception"));
        }
    }

    private void loadServiceOrderList() {
        try {
            setServiceOrders(getController().getAllServiceOrderNotIn(new Location(getLocationId())));
        } catch (Exception e) {
            logger.error("loadServiceOrderList", e);

            setServiceOrders(new ArrayList<>());
            showMessage(FacesMessage.SEVERITY_WARN,
                    getBundlePropertyFile().getString("garage.title"),
                    getBundlePropertyFile().getString("generic.loading.service.orders.list.warning.desc"));
        }
    }
    
    
    public void authorizeDeposit() {
        logger.info("autorizadeDeposit");
        User by = new User(getLoggedUser().getId(), "");
        try {
            if (getGenericController().existClosingDayByCreatedOn(new Date(), getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN, "Error","No se puede hacer ninguna acción si existe un corte del día");
                return;
            }
            if (getController().autorizarDeposito(selectedServiceOrder.getId(), by)) {
                
                BankCardKardex bankCardKardexObj = new BankCardKardex();
                

                bankCardKardexObj.setBankCard(getSelectedServiceOrder().getBankCard());
                bankCardKardexObj.setAmount(getSelectedServiceOrder().getTotal().doubleValue());
                bankCardKardexObj.setAmountBefore(getSelectedServiceOrder().getBankCard().getBalance());
                bankCardKardexObj.setAmountAfter(bankCardKardexObj.getAmountBefore()+bankCardKardexObj.getAmount());
                bankCardKardexObj.setKardexType(BankCardKardexType.INCOME);
                bankCardKardexObj.setDescription("Orden de servicio");
                bankCardKardexObj.setLocation(getSelectedServiceOrder().getLocation());
                
                BankCardKardexController bankCardKardexCtrl = new BankCardKardexController(); 
                bankCardKardexCtrl.save(bankCardKardexObj, getLoggedUser().getId());

                BankCard bankCard = getSelectedServiceOrder().getBankCard();
                
                bankCard.setBalance(bankCardKardexObj.getAmountAfter());
                
                BankCardController bankCardCtrl = new BankCardController();
                
                bankCardCtrl.save(bankCard, getLoggedUser().getId());
                
                setSelectedServiceOrder(null);
                showMessage(FacesMessage.SEVERITY_INFO, "Mensaje","Orden de servicio autorizada");
                setServiceOrdersPending(getController().fillDataTableDepositPending(getLoggedUser().getLocation().getId()));
            } else {
                logger.error("Invoice " + getSelectedServiceOrder()+ "can not be updated");
                showMessage(FacesMessage.SEVERITY_WARN, "Error","No se pudo autorizar la compra");
            }

        } catch (Exception e) {
            logger.error("editRow: " + e);
            
        }
    }

    private static final long serialVersionUID = -4979441656702485158L;
    final Logger logger = LogManager.getLogger(GarageListBean.class);

    private ServiceOrderController controller;
    private ServiceOrderSingletonController singletonController;
    private List<ServiceOrder> serviceOrders;
    private List<ServiceOrder> serviceOrdersPending;
    private ServiceOrder selectedServiceOrder;
    private List<ServiceOrderHasProduct> details;
    private final ServiceOrderType approved = ServiceOrderType.APPROVED;
    private final ServiceOrderType progress = ServiceOrderType.PROGRESS;
    private final ServiceOrderType paseTaller = ServiceOrderType.PASE_TALLER;
    private Date startDate;
    private Date endDate;
    private ServiceOrderType[] selectedTypes;
    private List<ServiceOrderType> types;
    private String driverId;
    List<Person> drivers;
    private BasicType valor;
    private LocationController locationController;
    private GenericValidationController genericController;
    private List<Location> locations;
    private String locationId;



    @PostConstruct
    public void init() {
        logger.info("init");
        try {
            valor = BasicType.ENEBLED;
            loadBundlePropertyFile();
            setController(new ServiceOrderController());
            setSingletonController(ServiceOrderSingletonController.getInstance());
            setLocationController(new LocationController());
            setServiceOrders(getController().getAllServiceOrderNotIn(getLoggedUser().getLocation()));
            setGenericController(new GenericValidationController());
            setServiceOrdersPending(getController().fillDataTableDepositPending(getLoggedUser().getLocation().getId()));
            setLocations(getLocationController().fillLocationDatatable());
            setLocationId(getLoggedUser().getLocation().getId());
            logger.info("Service orders loaded");
        } catch (Exception e) {
            logger.error("init", e);
        }
    }
    public BasicType getValor() {
        return valor;
    }

    public void setValor(BasicType valor) {
        this.valor = valor;
    }
    
    public ServiceOrderController getController() {
        return controller;
    }

    public void setController(ServiceOrderController controller) {
        this.controller = controller;
    }

    public ServiceOrderSingletonController getSingletonController() {
        return singletonController;
    }

    public void setSingletonController(ServiceOrderSingletonController singletonController) {
        this.singletonController = singletonController;
    }

    public List<ServiceOrder> getServiceOrders() {
        return serviceOrders;
    }

    public void setServiceOrders(List<ServiceOrder> serviceOrders) {
        this.serviceOrders = serviceOrders;
    }

    public ServiceOrder getSelectedServiceOrder() {
        return selectedServiceOrder;
    }

    public void setSelectedServiceOrder(ServiceOrder selectedServiceOrder) {
        this.selectedServiceOrder = selectedServiceOrder;
    }

    /**
     *
     *
     * @param id
     * @return
     */
    public List<ServiceOrderHasProduct> getDetails(String id) {
        logger.info("getDetails");
        try {
            setDetails(getController().findAllProductByOrderId(id));

            logger.info("details loaded size " + details.size());
        } catch (Exception e) {
            logger.error("getDetails", e);
        }
        return null == details ? new ArrayList<>() : details;
    }

    public void setDetails(List<ServiceOrderHasProduct> details) {
        this.details = details;
    }

    public ServiceOrderType getApproved() {
        return approved;
    }

    public ServiceOrderType getProgress() {
        return progress;
    }

    public Date getStartDate() {
        return startDate;
    }

    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }

    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    public ServiceOrderType[] getSelectedTypes() {
        return selectedTypes;
    }

    public void setSelectedTypes(ServiceOrderType[] selectedTypes) {
        this.selectedTypes = selectedTypes;
    }

    public List<ServiceOrderType> getTypes() {
        if (null == types) {
            types = Arrays.asList(ServiceOrderType.values());
        }
        return types;
    }

    public void setTypes(List<ServiceOrderType> types) {
        this.types = types;
    }

    public String getDriverId() {
        return driverId;
    }

    public void setDriverId(String driverId) {
        this.driverId = driverId;
    }

    public List<Person> getDrivers() {
        return drivers;
    }

    public void setDrivers(List<Person> drivers) {
        this.drivers = drivers;
    }

    public LocationController getLocationController() {
        return locationController;
    }

    public void setLocationController(LocationController locationController) {
        this.locationController = locationController;
    }

    public List<Location> getLocations() {
        return locations;
    }

    public void setLocations(List<Location> locations) {
        this.locations = locations;
    }

    public String getLocationId() {
        return locationId;
    }

    public void setLocationId(String locationId) {
        this.locationId = locationId;
    }

    public List<ServiceOrder> getServiceOrdersPending() {
        return serviceOrdersPending;
    }

    public void setServiceOrdersPending(List<ServiceOrder> serviceOrdersPending) {
        this.serviceOrdersPending = serviceOrdersPending;
    }

    public GenericValidationController getGenericController() {
        return genericController;
    }

    public void setGenericController(GenericValidationController genericController) {
        this.genericController = genericController;
    }

    
}
