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

import com.arrebol.taxiservicios.beans.TaxiGenericBean;
import com.arrebol.taxiservicios.controller.admin.CustomerController;
import com.arrebol.taxiservicios.controller.admin.TaxiController;
import com.arrebol.taxiservicios.controller.catalog.LocationController;
import com.arrebol.taxiservicios.controller.catalog.RegimenFiscalController;
import com.arrebol.taxiservicios.model.admin.Service;
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.RegimenFiscal;
import com.arrebol.taxiservicios.model.catalog.Vehicle;
import com.arrebol.taxiservicios.model.core.Address;
import com.arrebol.taxiservicios.model.core.ContactNumber;
import com.arrebol.taxiservicios.model.core.Person;
import com.arrebol.taxiservicios.model.core.PersonCommercialInvoice;
import com.arrebol.taxiservicios.model.enums.AddressType;
import com.arrebol.taxiservicios.model.enums.BasicType;
import com.arrebol.taxiservicios.model.enums.PersonType;
import com.arrebol.taxiservicios.model.enums.PhoneType;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;
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.model.DualListModel;

/**
 *
 * @author Picasso
 */
@Named("customerAddBean")
@ViewScoped
public class CustomerAddBean extends TaxiGenericBean implements Serializable {

    /**
     * Save/Update an vehicle in the system.
     */
    public void addVehicle() {
        logger.info("addVehicle");

        getTaxiAdd().setId(UUID.randomUUID().toString());
        getTaxiAdd().setActive(true);
        getTaxiAdd().setCreatedOn(new Date());
        getTaxiAdd().setLocation(getLoggedUser().getLocation());
        getTaxiAdd().setCustomer(getCustomer());
        getTaxiAdd().setGps(BasicType.DISABLED);
        getTaxiAdd().setApc(BasicType.DISABLED);
        boolean success = getController().addTaxi(getTaxiAdd(), getLoggedUser().getId(), vehicleId, colorId);

        if (success) {
            getTaxi().add(taxiAdd);
            showMessage(FacesMessage.SEVERITY_INFO,
                    getBundlePropertyFile().getString("taxi.add.title"),
                    getBundlePropertyFile().getString("taxi.add.success.desc"));
        } else {
            logger.error("Taxi " + getTaxiAdd() + " was not saved");
            showMessage(FacesMessage.SEVERITY_ERROR,
                    getBundlePropertyFile().getString("taxi.add.title"),
                    getBundlePropertyFile().getString("taxi.add.fail.desc"));
        }

    }

    /**
     * Save/Update an customer in the system.
     */
    public void addCustomer() {
        logger.info("addCustomer");
        try {
            if (!isAddCustomerBtnOnclick()) {
                getCustomer().setId(UUID.randomUUID().toString());
                getCustomer().setActive(true);
                getCustomer().setRoot(false);
                getCustomer().setCreatedOn(new Date());
                getCustomer().setLocation(new Location(getLoggedUser().getLocation().getId()));
            } else {
                getCustomer().setLastUpdatedOn(new Date());
            }
            getCustomer().setAjustador(Boolean.FALSE);
            // correccion de fecha 
            if (getCustomer().getBirthdate() != null) {
                getCustomer().setBirthdate(correcciónDeDias(getCustomer().getBirthdate(), 1));
            }

            boolean success = getController().addPerson(getCustomer(), getLoggedUser().getUserName(), !isAddCustomerBtnOnclick());

            if (success) {
                setAddCustomerBtnOnclick(true);
                showMessage(FacesMessage.SEVERITY_INFO,
                        getBundlePropertyFile().getString("customer.add.title"),
                        getBundlePropertyFile().getString("customer.add.success.desc"));
            } else {
                logger.error("Employee " + getCustomer() + " was not " + (isAddCustomerBtnOnclick() ? "updated" : "saved"));
                showMessage(FacesMessage.SEVERITY_ERROR,
                        getBundlePropertyFile().getString("customer.add.title"),
                        getBundlePropertyFile().getString("customer.add.fail.desc"));
            }
        } catch (Exception e) {
            logger.error("addEmployee: " + e);
            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("customer.add.title"),
                    getBundlePropertyFile().getString("customer.add.exception.desc"));
        }
    }

    /**
     * Add RFC, Email, CURP, and Local/Mobile phones to customer.
     */
    public void addContactDetails() {
        logger.info("addContactDetails");
        try {
            if (!isAddContactBtnOnclick()) {
                getContactNumbers().stream().map((contactNumber) -> {
                    contactNumber.setId(UUID.randomUUID().toString());
                    return contactNumber;
                }).forEachOrdered((contactNumber) -> {
                    contactNumber.setPerson(getCustomer());
                    contactNumber.setCreatedOn(new Date());
                });
            } else {
                getContactNumbers().forEach((phone) -> {
                    phone.setLastUpdatedOn(new Date());
                });
            }
            getCustomer().setLastUpdatedOn(new Date());

            boolean success = getController().saveOrUpdateCustomerContactDetailsById(
                    getCustomer().getId(), getCustomer().getCurp(),
                    getCustomer().getRfc(), getCustomer().getMail(),
                    getContactNumbers(), getLoggedUser().getUserName(),
                    !isAddContactBtnOnclick(), !isAddContactBtnOnclick());
            if (success) {
                setAddContactBtnOnclick(true);
                logger.info("Contact detais saved.");
                showMessage(FacesMessage.SEVERITY_INFO,
                        getBundlePropertyFile().getString("person.add.contact.title"),
                        getBundlePropertyFile().getString("person.add.contact.success.desc"));
            } else {
                logger.error("Contact details can not be saved.");
                logger.error("Contact details: " + getCustomer());
                logger.error("Numbers details: " + getContactNumbers());
                showMessage(FacesMessage.SEVERITY_ERROR,
                        getBundlePropertyFile().getString("person.add.contact.title"),
                        getBundlePropertyFile().getString("person.add.contact.fail.desc"));
            }
        } catch (Exception e) {
            logger.error("addContactDetails: " + e);

            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("person.add.contact.title"),
                    getBundlePropertyFile().getString("person.add.contact.exception.desc"));
        }
    }

    public void addCommercialInvoice() {
        getCustomerCommercialInvoice().setIdPerson(getCustomer().getId());

        boolean success = getController().saveOrUpdatePersonCommercialInvoice(getCustomerCommercialInvoice(), getLoggedUser().getId(), getRegimenFiscalId());

        if (success) {

            logger.info("Address detais saved.");
            showMessage(FacesMessage.SEVERITY_INFO, "Alta de información para facturar", "Se agrego la informacion para facturar");
            setAddCustomerCommercialInvoiceBtnOnClick(true);
        } else {
            logger.error("Address details not saved " + getAddress());
            showMessage(FacesMessage.SEVERITY_ERROR, "Alta de información para facturar", "No se pudo agregar la informacion para facturar");
        }
    }

    /**
     * Save an address(HOME) person details details.
     */
    public void addAddress() {
        logger.info("addAddress");
        try {
            /*
            getAddress().setStreet(facesContext().getExternalContext().getRequestParameterMap().get("addAddressForm:streetHdn"));
            getAddress().setExtendedAddress(facesContext().getExternalContext().getRequestParameterMap().get("addAddressForm:colonyHdn"));
            getAddress().setLocality(facesContext().getExternalContext().getRequestParameterMap().get("addAddressForm:departmentHdn"));
            getAddress().setRegion(facesContext().getExternalContext().getRequestParameterMap().get("addAddressForm:stateHdn"));
            getAddress().setZipCode(facesContext().getExternalContext().getRequestParameterMap().get("addAddressForm:cpHdn"));
             */
            if (!isAddAddressBtnOnclick()) {
                getAddress().setId(UUID.randomUUID().toString());
                getAddress().setCreatedOn(new Date());
            } else {
                getAddress().setLastUpdatedOn(new Date());
            }

            boolean success = getController().saveOrUpdateAddress(getAddress(), !isAddAddressBtnOnclick(), getCustomer().getId(), getLoggedUser().getUserName());

            if (success) {
                setAddAddressBtnOnclick(true);
                logger.info("Address detais saved.");
                showMessage(FacesMessage.SEVERITY_INFO,
                        getBundlePropertyFile().getString("person.add.address.title"),
                        getBundlePropertyFile().getString("person.add.address.success.desc"));
            } else {
                logger.error("Address details not saved " + getAddress());
                showMessage(FacesMessage.SEVERITY_ERROR,
                        getBundlePropertyFile().getString("person.add.address.title"),
                        getBundlePropertyFile().getString("person.add.address.fail.desc"));
            }

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

            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("person.add.address.title"),
                    getBundlePropertyFile().getString("person.add.address.exception.desc"));
        }
    }

    /**
     * Save or update the services into a customer.
     */
    public void saveOrUpdatePersonHasServices() {
        logger.info("saveOrUpdateServices");
        try {
            boolean success = getController().saveOrUpdatePersonHasServices(
                    getCustomer().getId(), getServices().getTarget(), getServices().getSource());

            if (success) {
                logger.info("Services by Customer saved.");
                showMessage(FacesMessage.SEVERITY_INFO,
                        getBundlePropertyFile().getString("customer.service."
                                + (!isAddServiceBtnOnclick() ? "add" : "update")
                                + ".title"),
                        getBundlePropertyFile().getString("customer.service."
                                + (!isAddServiceBtnOnclick() ? "add" : "update")
                                + ".success.desc"));
                setAddServiceBtnOnclick(true);
            } else {
                logger.error("Services by customer didn't save.");
                showMessage(FacesMessage.SEVERITY_ERROR,
                        getBundlePropertyFile().getString("customer.service."
                                + (!isAddServiceBtnOnclick() ? "add" : "update")
                                + ".title"),
                        getBundlePropertyFile().getString("customer.service."
                                + (!isAddServiceBtnOnclick() ? "add" : "update")
                                + ".fail.desc"));
            }
        } catch (Exception e) {
            logger.error("saveOrUpdateServices: " + e);

            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("customer.service."
                            + (!isAddServiceBtnOnclick() ? "add" : "update")
                            + ".title"),
                    getBundlePropertyFile().getString("customer.service."
                            + (!isAddServiceBtnOnclick() ? "add" : "update")
                            + ".exception.desc"));
        }
    }

    private Date correcciónDeDias(Date fecha, int dias) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(fecha);
        calendar.add(Calendar.DAY_OF_YEAR, dias);
        return calendar.getTime();
    }

    private static final long serialVersionUID = -4594340936069728620L;

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

    private CustomerController controller;
    private Person customer;
    private List<ContactNumber> contactNumbers;
    private Address address;
    private PersonCommercialInvoice customerCommercialInvoice;

    private List<Taxi> taxi;
    TaxiController controllerTaxi;
    private Taxi selectedTaxi;
    private Taxi taxiAdd;
    private String vehicleId;
    private String colorId;

    private boolean addCustomerBtnOnclick;
    private boolean addContactBtnOnclick;
    private boolean addAddressBtnOnclick;
    private boolean addPaymentBtnOnclick;
    private boolean addServiceBtnOnclick;
    private boolean addCustomerCommercialInvoiceBtnOnClick;
    private Date sixteenYearsOld;
    private DualListModel<Service> services;

    private LocationController locationController;
    private RegimenFiscalController regimenFiscalController;
    private String regimenFiscalId;
    private List<Location> locations;
    private List<RegimenFiscal> regimenFiscal;

    @PostConstruct
    public void init() {
        logger.info("init");
        try {
            Calendar calendar = Calendar.getInstance();

            calendar.add(Calendar.YEAR, -15);
            setSixteenYearsOld(calendar.getTime());
            setTaxi(new ArrayList());

            loadBundlePropertyFile();
            setControllerTaxi(new TaxiController());
            setTaxiAdd(new Taxi());
            setController(new CustomerController());
            setLocationController(new LocationController());
            setRegimenFiscalController(new RegimenFiscalController());
            setLocations(getLocationController().fillLocationDatatable());
            setRegimenFiscal(getRegimenFiscalController().fillRegimenFiscalDatatable());
            setCustomer(new Person(PersonType.CUSTOMER));
            setCustomerCommercialInvoice(new PersonCommercialInvoice());
            setAddress(new Address(AddressType.HOME));
            setAddCustomerBtnOnclick(false);
            setAddContactBtnOnclick(false);
            setAddAddressBtnOnclick(false);
            setAddPaymentBtnOnclick(false);
            setAddServiceBtnOnclick(false);
            setAddCustomerCommercialInvoiceBtnOnClick(false);

            List<Service> servicesSource = getController().getAllServices(true);
            List<Service> servicesTarget = new ArrayList<>();

            setServices(new DualListModel<>(servicesSource, servicesTarget));

            getContactNumbers().add(new ContactNumber(PhoneType.HOME));
            getContactNumbers().add(new ContactNumber(PhoneType.MOBILE));
        } catch (Exception e) {
            logger.error("init", e);
        }
    }

    public String getColorId() {
        return colorId;
    }

    public void setColorId(String colorId) {
        this.colorId = colorId;
    }

    public String getVehicleId() {
        return vehicleId;
    }

    public void setVehicleId(String vehicleId) {
        this.vehicleId = vehicleId;
    }

    public List<Vehicle> getVehicles() {
        return getControllerTaxi().fillVehicleComboBox();
    }

    public List<Color> getColors() {
        return getControllerTaxi().fillColorsComboBox();
    }

    public Taxi getTaxiAdd() {
        return taxiAdd;
    }

    public void setTaxiAdd(Taxi taxiAdd) {
        this.taxiAdd = taxiAdd;
    }

    public Taxi getSelectedTaxi() {
        return selectedTaxi;
    }

    public void setSelectedTaxi(Taxi selectedTaxi) {
        this.selectedTaxi = selectedTaxi;
    }

    public TaxiController getControllerTaxi() {
        return controllerTaxi;
    }

    public void setControllerTaxi(TaxiController controllerTaxi) {
        this.controllerTaxi = controllerTaxi;
    }

    public List<Taxi> getTaxi() {
        return taxi;
    }

    public void setTaxi(List<Taxi> taxi) {
        this.taxi = taxi;
    }

    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 CustomerController getController() {
        return controller;
    }

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

    public Person getCustomer() {
        return customer;
    }

    public void setCustomer(Person customer) {
        this.customer = customer;
    }

    public List<ContactNumber> getContactNumbers() {
        if (null == contactNumbers) {
            contactNumbers = new ArrayList<>();
        }
        return contactNumbers;
    }

    public void setContactNumbers(List<ContactNumber> contactNumbers) {
        this.contactNumbers = contactNumbers;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public boolean isAddCustomerBtnOnclick() {
        return addCustomerBtnOnclick;
    }

    public void setAddCustomerBtnOnclick(boolean addCustomerBtnOnclick) {
        this.addCustomerBtnOnclick = addCustomerBtnOnclick;
    }

    public boolean isAddContactBtnOnclick() {
        return addContactBtnOnclick;
    }

    public void setAddContactBtnOnclick(boolean addContactBtnOnclick) {
        this.addContactBtnOnclick = addContactBtnOnclick;
    }

    public boolean isAddAddressBtnOnclick() {
        return addAddressBtnOnclick;
    }

    public void setAddAddressBtnOnclick(boolean addAddressBtnOnclick) {
        this.addAddressBtnOnclick = addAddressBtnOnclick;
    }

    public boolean isAddPaymentBtnOnclick() {
        return addPaymentBtnOnclick;
    }

    public void setAddPaymentBtnOnclick(boolean addPaymentBtnOnclick) {
        this.addPaymentBtnOnclick = addPaymentBtnOnclick;
    }

    public boolean isAddServiceBtnOnclick() {
        return addServiceBtnOnclick;
    }

    public void setAddServiceBtnOnclick(boolean addServiceBtnOnclick) {
        this.addServiceBtnOnclick = addServiceBtnOnclick;
    }

    public Date getSixteenYearsOld() {
        return sixteenYearsOld;
    }

    public void setSixteenYearsOld(Date sixteenYearsOld) {
        this.sixteenYearsOld = sixteenYearsOld;
    }

    public DualListModel<Service> getServices() {
        return services;
    }

    public void setServices(DualListModel<Service> services) {
        this.services = services;
    }

    public List<RegimenFiscal> getRegimenFiscal() {
        return regimenFiscal;
    }

    public void setRegimenFiscal(List<RegimenFiscal> regimenFiscal) {
        this.regimenFiscal = regimenFiscal;
    }

    public String getRegimenFiscalId() {
        return regimenFiscalId;
    }

    public void setRegimenFiscalId(String regimenFiscalId) {
        this.regimenFiscalId = regimenFiscalId;
    }

    public RegimenFiscalController getRegimenFiscalController() {
        return regimenFiscalController;
    }

    public void setRegimenFiscalController(RegimenFiscalController regimenFiscalController) {
        this.regimenFiscalController = regimenFiscalController;
    }

    public PersonCommercialInvoice getCustomerCommercialInvoice() {
        return customerCommercialInvoice;
    }

    public void setCustomerCommercialInvoice(PersonCommercialInvoice customerCommercialInvoice) {
        this.customerCommercialInvoice = customerCommercialInvoice;
    }

    public boolean isAddCustomerCommercialInvoiceBtnOnClick() {
        return addCustomerCommercialInvoiceBtnOnClick;
    }

    public void setAddCustomerCommercialInvoiceBtnOnClick(boolean addCustomerCommercialInvoiceBtnOnClick) {
        this.addCustomerCommercialInvoiceBtnOnClick = addCustomerCommercialInvoiceBtnOnClick;
    }

}
