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

import com.arrebol.taxiservicios.beans.Datatable;
import com.arrebol.taxiservicios.beans.TaxiGenericBean;
import com.arrebol.taxiservicios.controller.admin.DriverController;
import com.arrebol.taxiservicios.controller.util.DateWrapper;
import com.arrebol.taxiservicios.model.catalog.Holiday;
import com.arrebol.taxiservicios.model.core.Person;
import com.arrebol.taxiservicios.model.core.User;
import com.arrebol.taxiservicios.model.dashboard.ToCollect;
import com.arrebol.taxiservicios.model.enums.PersonType;
import com.arrebol.taxiservicios.utils.ToCollectUtility;
import com.arrebol.taxiservicios.wrapper.PersonWrapper;
import java.io.Serializable;
import java.util.ArrayList;
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;
import org.primefaces.PrimeFaces;
import org.primefaces.event.ReorderEvent;
import org.primefaces.event.RowEditEvent;

/**
 *
 * @author Picasso
 */
@Named("driverListBean")
@ViewScoped
public class DriverListBean extends TaxiGenericBean implements Serializable, Datatable {

    /**
     *
     * @param outcome
     * @return
     */
    public String editDriver(String outcome) {
        return outcome;
    }

    private static final long serialVersionUID = 6166262474494793034L;

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

    private DriverController controller;
    private List<PersonWrapper> drivers;
    private List<PersonWrapper> driversPool;
    private List<Person> driversBlackList;
    private PersonWrapper selectedDriver;
    private Person selectedDriverBlackList;
    private String blackListDescription;

    @PostConstruct
    public void init() {
        logger.info("init");
        try {
            loadBundlePropertyFile();

            setController(new DriverController());
            setDrivers(wraperPerson(getController().getAllPersonsByPersonTye(PersonType.DRIVER)));
            setDriversPool(wraperPerson(getController().getAllPersonsPoolByPersonTye(PersonType.DRIVER)));
            setDriversBlackList(getController().getAllPersonsBlackListByPersonTye(PersonType.DRIVER));

            logger.info("Taxi drivers loaded");
        } catch (Exception e) {
            logger.error("init", e);
        }
    }

    @Override
    public void editRow(RowEditEvent event) {
        Person person = (Person) event.getObject();
        if (person != null) {
            getController().addPerson(person, getLoggedUser().getUserName(), false);
            getDriversBlackList().clear();
            setDriversBlackList(getController().getAllPersonsBlackListByPersonTye(PersonType.DRIVER));
            showMessage(FacesMessage.SEVERITY_INFO, "Registro Editado", "Se hizo el cambio correctamente.");
        }
    }

    @Override
    public void onRowCancel(RowEditEvent event) {
        showMessage(FacesMessage.SEVERITY_INFO, "Edición Cancelada", ((Person) event.getObject()).getFirstName());
    }

    @Override
    public void onRowReorder(ReorderEvent event) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void addRow() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void deleteRow() {
        logger.info("deleteRow");
        try {
            if (null == getLoggedUser().getPerson()
                    || null == getLoggedUser().getPerson().getId()
                    || getLoggedUser().getPerson().getId().equals(getSelectedDriver().getId())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        getBundlePropertyFile().getString("driver.delete.title"),
                        getBundlePropertyFile().getString(
                                null == getLoggedUser().getPerson()
                                || null == getLoggedUser().getPerson().getId()
                                ? "driver.delete.cannot.empty"
                                : "driver.delete.cannot.delete"
                        ));
            } else {
                String tmpId = getSelectedDriver().getId();
                boolean success = getController().updateStatusDriverAndRemoveFromTaxi(
                        getSelectedDriver().getId(), getLoggedUser());

                if (success) {
                    getDrivers().remove(getSelectedDriver());
                    setSelectedDriver(null);

                    showMessage(FacesMessage.SEVERITY_INFO,
                            getBundlePropertyFile().getString("driver.released.title"),
                            getBundlePropertyFile().getString("driver.released.success.desc"));

                    if (!getController().deteleToCollectByDriverId(tmpId)) {
                        logger.error("To collect was not deleted");
                        showMessage(FacesMessage.SEVERITY_ERROR,
                                getBundlePropertyFile().getString("driver.delete.title"),
                                getBundlePropertyFile().getString("sale.delete.all.to.collect.fail.desc"));
                    }
                } else {
                    logger.error("Provider " + getSelectedDriver() + "was not deleted");
                    showMessage(FacesMessage.SEVERITY_ERROR,
                            getBundlePropertyFile().getString("driver.delete.title"),
                            getBundlePropertyFile().getString("driver.delete.fail.desc"));
                }
            }
        } catch (Exception e) {
            logger.error("deleteRow: " + e);

            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("driver.delete.title"),
                    getBundlePropertyFile().getString("driver.delete.exception.desc"));
        }
    }
    
    public void returnToPoolDriver() {
        logger.info("returnToPoolDriver");
        try {
            String tmpDriverId = getSelectedDriverBlackList().getId();
            boolean success = getController().returnToPoolBlackListDriver(tmpDriverId);

            if (success) {
                getDriversBlackList().remove(getSelectedDriverBlackList());
                setSelectedDriverBlackList(null);

                showMessage(FacesMessage.SEVERITY_INFO,
                        "Regreso a banca",
                        "Se regreso correctamente el chofer de lista negra a banca");

            } else {
                logger.error("Driver " + getSelectedDriver() + "was not deleted");
                showMessage(FacesMessage.SEVERITY_ERROR,
                        getBundlePropertyFile().getString("driver.active.title"),
                        getBundlePropertyFile().getString("driver.active.fail.desc"));
            }

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

            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("driver.active.title"),
                    getBundlePropertyFile().getString("driver.active.exception.desc"));
        }
    }

    public void activeDriver() {
        logger.info("activeDriver");
        try {
            String tmpDriverId = getSelectedDriver().getId();
            boolean success = getController().activeDriverById(tmpDriverId);

            if (success) {
                getDriversPool().remove(getSelectedDriver());
                setSelectedDriver(null);

                showMessage(FacesMessage.SEVERITY_INFO,
                        getBundlePropertyFile().getString("driver.active.title"),
                        getBundlePropertyFile().getString("driver.active.success.desc"));

                /*
                List<Person> persons = new ArrayList<>();
                Calendar startDate = Calendar.getInstance();

                persons.add(new Person(tmpDriverId));
                startDate.setTime(DateWrapper.today().addHours(-6).midnigthTime().asDate());

                
                List<ToCollect> collects = prepareToCollectForActiveDriver(persons, startDate);

                if (!getController().saveToCollect(collects)) {
                    showMessage(FacesMessage.SEVERITY_ERROR,
                            getBundlePropertyFile().getString("driver.active.title"),
                            getBundlePropertyFile().getString("driver.to.collect.fails.desc"));
                }
                 */
            } else {
                logger.error("Driver " + getSelectedDriver() + "was not deleted");
                showMessage(FacesMessage.SEVERITY_ERROR,
                        getBundlePropertyFile().getString("driver.active.title"),
                        getBundlePropertyFile().getString("driver.active.fail.desc"));
            }

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

            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("driver.active.title"),
                    getBundlePropertyFile().getString("driver.active.exception.desc"));
        }
    }

    /**
     * Add user to black list ().
     */
    public void addToBlackListDriver() {
        logger.info("addToBlackListDriver");
        try {
            String tmpDriverId = getSelectedDriver().getId();

            if (null == getBlackListDescription() || "".equals(getBlackListDescription().trim())) {
                showMessage(FacesMessage.SEVERITY_ERROR,
                        getBundlePropertyFile().getString("driver.black.list.title"),
                        getBundlePropertyFile().getString("validator.black.list.reason"));
            } else {
                if (getController().addToBlackListDriver(tmpDriverId, getBlackListDescription())) {
                    getDriversPool().remove(getSelectedDriver());
                    setSelectedDriver(null);
                    setBlackListDescription(null);

                    showMessage(FacesMessage.SEVERITY_INFO,
                            getBundlePropertyFile().getString("driver.black.list.title"),
                            getBundlePropertyFile().getString("driver.black.list.success.desc"));

                    PrimeFaces current = PrimeFaces.current();
                    current.executeScript("PF('blackListDialog').hide();");
                } else {
                    logger.error("Driver " + getSelectedDriver() + "was not added to black list");
                    showMessage(FacesMessage.SEVERITY_ERROR,
                            getBundlePropertyFile().getString("driver.black.list.title"),
                            getBundlePropertyFile().getString("driver.black.list.fail.desc"));
                }
            }
        } catch (Exception e) {
            logger.error("addToBlackListDriver: " + e);

            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("driver.black.list.title"),
                    getBundlePropertyFile().getString("driver.black.list.exception.desc"));
        }
    }

    private List<ToCollect> prepareToCollectForActiveDriver(List<Person> drivers, Calendar startDate) {
        logger.info("prepareToCollectForActiveDriver");

        List<ToCollect> collects = new ArrayList<>();

        try {
            //Calendar startDate = Calendar.getInstance();
            Calendar endDate = Calendar.getInstance();

            //startDate.setTime(DateWrapper.today().addHours(-6).firstDateForMonth().midnigthTime().asDate());
            endDate.setTime(DateWrapper.today().addHours(-6).lastDateForMonth().midnigthTime().asDate());

            List<Holiday> holidays = getController().findHolidaysByRangeOfDates(
                    startDate.getTime(), endDate.getTime());

            List<Date> dates = ToCollectUtility.daysToCollect(holidays,
                    startDate.get(Calendar.DAY_OF_MONTH), endDate.get(Calendar.DAY_OF_MONTH));

            collects = ToCollectUtility.fillToCollects(
                    dates, drivers, new User(getLoggedUser().getId(), ""));
        } catch (Exception e) {
            logger.error(e);
        }

        return collects;
    }

    public Person getSelectedDriverBlackList() {
        return selectedDriverBlackList;
    }

    public void setSelectedDriverBlackList(Person selectedDriverBlackList) {
        this.selectedDriverBlackList = selectedDriverBlackList;
    }

    public DriverController getController() {
        return controller;
    }

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

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

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

    public List<PersonWrapper> getDriversPool() {
        return driversPool;
    }

    public void setDriversPool(List<PersonWrapper> driversPool) {
        this.driversPool = driversPool;
    }

    public PersonWrapper getSelectedDriver() {
        return selectedDriver;
    }

    public void setSelectedDriver(PersonWrapper selectedDriver) {
        this.selectedDriver = selectedDriver;
    }

    public String getBlackListDescription() {
        return blackListDescription;
    }

    public void setBlackListDescription(String blackListDescription) {
        this.blackListDescription = blackListDescription;
    }

    public List<Person> getDriversBlackList() {
        return driversBlackList;
    }

    public void setDriversBlackList(List<Person> driversBlackList) {
        this.driversBlackList = driversBlackList;
    }

}
