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

import com.arrebol.taxiservicios.beans.Datatable;
import com.arrebol.taxiservicios.beans.TaxiGenericBean;
import com.arrebol.taxiservicios.controller.catalog.ClaveProductoServicioController;
import com.arrebol.taxiservicios.controller.catalog.ClaveUnidadController;
import com.arrebol.taxiservicios.controller.catalog.ProductBrandController;
import com.arrebol.taxiservicios.controller.catalog.ProductController;
import com.arrebol.taxiservicios.model.catalog.Brand;
import com.arrebol.taxiservicios.model.catalog.ClaveProductoServicio;
import com.arrebol.taxiservicios.model.catalog.ClaveUnidad;
import com.arrebol.taxiservicios.model.catalog.Product;
import com.arrebol.taxiservicios.model.enums.BasicType;
import com.arrebol.taxiservicios.services.catalog.ProductService;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedProperty;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.primefaces.event.ReorderEvent;
import org.primefaces.event.RowEditEvent;
import org.primefaces.event.SelectEvent;

/**
 *
 * @author oscarvargas
 */
@Named("productManager")
@ViewScoped
public class ProductManager extends TaxiGenericBean implements Serializable, Datatable {

    /**
     *
     */
    public void onBrandChange() {
        try {
            if (getSelectedBrandId().equals("N/A")) {
                setProduct(new ArrayList<>());
            } else {
                setProduct(searchProductByBrand(getSelectedBrandId()));
            }
        } catch (Exception e) {
            logger.error("onBrandChange", e);
            
            setProduct(new ArrayList<>());
            showMessage(FacesMessage.SEVERITY_ERROR, "Producto", "Error al realizar la búsqueda del producto por marca");
        }
    }
    
    public void onItemSelectClaveUnidad(SelectEvent event) {
        
        try {
            setClaveUnidad(claveUnidadController.getById(getIdClaveUnidad()));
        } catch (Exception e) {
            
            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("garage.title"),
                    getBundlePropertyFile().getString("garage.generic.exception"));
        }
    }
    
    public void onItemSelectClaveProductoServicio(SelectEvent event) {
        
        try {
            setClaveProductoServicio(claveProductoServicioController.getById(getIdClaveProductoServicio()));
        } catch (Exception e) {
            
            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("garage.title"),
                    getBundlePropertyFile().getString("garage.generic.exception"));
        }
    }
    
    public List<ClaveProductoServicio> searchClaveProductoServicios(String query) {
        
        List<ClaveProductoServicio> list = null;
        try {
            list = getClaveProductoServicioController().getClaveProductoServicioLike(query);
        } catch (Exception e) {
            
            showMessage(FacesMessage.SEVERITY_FATAL,
                    "No se pudo buscar la clave producto servicio",
                    "Error");
        }
        return list;
    }
    
    public List<ClaveUnidad> searchClaveUnidad(String query) {
        
        List<ClaveUnidad> list = null;
        try {
            list = getClaveUnidadController().getClaveUnidadLike(query);
        } catch (Exception e) {
            
            showMessage(FacesMessage.SEVERITY_FATAL,
                    "No se pudo buscar la clave producto servicio",
                    "Error");
        }
        return list;
    }
    
    public void updateInfo() {
        
        setName(getSelectedProduct().getName() != null ? getSelectedProduct().getName() : null);
        setCode(getSelectedProduct().getCode() != null ? getSelectedProduct().getCode() : null);
        setTipoUso(getSelectedProduct().getTipoUso() != null ? getSelectedProduct().getTipoUso() : null);
        setCompatibilidad(getSelectedProduct().getCompatibilidad() != null ? getSelectedProduct().getCompatibilidad() : null);
        setLife(getSelectedProduct().getLife());
        setBrandId(getSelectedProduct().getBrand().getId() != null ? getSelectedProduct().getBrand().getId() : null);
        
        if (getLoggedUser().getLocation().getId().equalsIgnoreCase("4d0859be-e31a-4acb-a690-2a5c2cb027a7")) {
            setQuantity(getSelectedProduct().getQuantity());
            setAmount(getSelectedProduct().getAmount());
            setUtility(getSelectedProduct().getUtility());
            
        } else {
            setQuantity(getSelectedProduct().getQuantity2());
            setAmount(getSelectedProduct().getAmount2());
            setUtility(getSelectedProduct().getUtility2());
        }
        
        if (getSelectedProduct().getService().equals(BasicType.DISABLED) && getSelectedProduct().getHerramienta().equals(BasicType.DISABLED)) {
            setServiceId("PRODUCTO");
        } else if (getSelectedProduct().getService().equals(BasicType.ENEBLED) && getSelectedProduct().getHerramienta().equals(BasicType.DISABLED)) {
            setServiceId("SERVICIO");
        } else if (getSelectedProduct().getService().equals(BasicType.DISABLED) && getSelectedProduct().getHerramienta().equals(BasicType.ENEBLED)) {
            setServiceId("HERRAMIENTA");
        }
        
        setClaveUnidad(getSelectedProduct().getClaveUnidad() != null ? getSelectedProduct().getClaveUnidad() : null);
        
        if (getClaveUnidad() != null) {
            setIdClaveUnidad(getClaveUnidad().toString());
        }
        
        setClaveProductoServicio(getSelectedProduct().getClaveProductoServicio() != null ? getSelectedProduct().getClaveProductoServicio() : null);
        
        if (getClaveProductoServicio() != null) {
            setIdClaveProductoServicio(getClaveProductoServicio().toString());
        }
        setShowQuantity(false);
        
    }

    /**
     *
     * @param productName
     * @return
     */
    public List<Product> searchByProductName(String productName) {
        try {
            return searchProductsLikeField(true, "%" + productName + "%");
        } catch (Exception e) {
            logger.error("searchByProductName", e);
            return new ArrayList<>();
        }
    }

    /**
     *
     * @param productCode
     * @return
     */
    public List<Product> searchByProductCode(String productCode) {
        try {
            return searchProductsLikeField(false, "%" + productCode + "%");
        } catch (Exception e) {
            logger.error("searchByProductCode", e);
            return new ArrayList<>();
        }
    }
    
    public void handleClose() {
        setClaveUnidad(null);
        setClaveProductoServicio(null);
        setIdClaveUnidad(null);
        setIdClaveProductoServicio(null);
        setName(null);
        setCode(null);
        setAmount(null);
        setQuantity(null);
        setUtility(null);
        setTipoUso(null);
        setCompatibilidad(null);
        setBrandId(null);
        setServiceId(null);
        setLife(null);
        setSelectedProduct(null);
        setShowQuantity(true);
    }

    /**
     *
     * @param event
     */
    public void onProductSelectedItem(SelectEvent event) {
        try {
            getProduct().clear();
            getProduct().add(findProductById(((Product) event.getObject()).getId()));
        } catch (Exception e) {
        }
    }
    
    @Override
    public void editRow(RowEditEvent event) {
        Product pro = (Product) event.getObject();
        if (pro != null) {
            productCtrl.saveProduct(pro, getLoggedUser().getId(), "");
            
            getProduct().clear();
            getProduct().add(findProductById(pro.getId()));
            
            showMessage(FacesMessage.SEVERITY_INFO, "Registro Editado", "Se hizo el cambio correctamente.");
        }
    }
    
    @Override
    public void onRowCancel(RowEditEvent event) {
        showMessage(FacesMessage.SEVERITY_INFO, "Edición Cancelada", ((Product) event.getObject()).getName());
    }
    
    @Override
    public void onRowReorder(ReorderEvent event) {
        showMessage(FacesMessage.SEVERITY_INFO, "Registro Movido", "De columna: " + (event.getFromIndex() + 1) + " a columna: " + (event.getToIndex() + 1));
    }
    
    @Override
    public void addRow() {
        Product productObj = new Product();
        try {            
            productObj.setId(getSelectedProduct().getId());
            
           if (getLoggedUser().getLocation().getId().equalsIgnoreCase("4d0859be-e31a-4acb-a690-2a5c2cb027a7")) {
            productObj.setQuantity(getSelectedProduct().getQuantity());
            productObj.setQuantity2(getSelectedProduct().getQuantity2());
            productObj.setAmount(amount);
            productObj.setAmount2(getSelectedProduct().getAmount2());
            productObj.setUtility(utility);
            productObj.setUtility2(getSelectedProduct().getUtility2());
        } else {
            productObj.setQuantity(getSelectedProduct().getQuantity());
            productObj.setQuantity2(getSelectedProduct().getQuantity2());
            productObj.setAmount(getSelectedProduct().getAmount());
            productObj.setAmount2(amount);
            productObj.setUtility(getSelectedProduct().getUtility());
            productObj.setUtility2(utility);
        }
            
            
        } catch (Exception e) {
           
            
            if (getLoggedUser().getLocation().getId().equalsIgnoreCase("4d0859be-e31a-4acb-a690-2a5c2cb027a7")) {
            productObj.setQuantity(quantity);
            productObj.setQuantity2(0);
            productObj.setAmount(amount);
            productObj.setAmount2(0D);
            productObj.setUtility(utility);
            productObj.setUtility2(0D);
        } else {
            productObj.setQuantity(0);
            productObj.setQuantity2(quantity);
            productObj.setAmount(0D);
            productObj.setAmount2(amount);
            productObj.setUtility(0D);
            productObj.setUtility2(utility);
        }
            
        }
        
        productObj.setName(name);
        
        productObj.setCode(code);
        productObj.setCompatibilidad(compatibilidad);
        productObj.setTipoUso(tipoUso);
        productObj.setService(BasicType.DISABLED);
        productObj.setHerramienta(BasicType.DISABLED);
        
        
        productObj.setLife(getLife());
        productObj.setActiveStatus(BasicType.ENEBLED);
        
        productObj.setClaveUnidad(getClaveUnidad());
        productObj.setClaveProductoServicio(getClaveProductoServicio());
        productCtrl.saveProduct(productObj, getLoggedUser().getId(), brandId);
        
        getProduct().clear();
        setClaveUnidad(null);
        setClaveProductoServicio(null);
        setIdClaveUnidad(null);
        setIdClaveProductoServicio(null);
        setName(null);
        setCode(null);
        setAmount(null);
        setQuantity(null);
        setUtility(null);
        setTipoUso(null);
        setCompatibilidad(null);
        setBrandId(null);
        setServiceId(null);
        setSelectedProduct(null);
        setShowQuantity(true);
        getProduct().add(findProductById(productObj.getId()));
        
        FacesMessage msg = new FacesMessage("Nuevo Producto", "Se agregó correctamente");
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }
    
    public void addRowCatalog() {
        Product productObj = new Product();
        
        try {            
            productObj.setId(getSelectedProduct().getId());
            
            if (getLoggedUser().getLocation().getId().equalsIgnoreCase("4d0859be-e31a-4acb-a690-2a5c2cb027a7")) {
                productObj.setAmount(amount);
                productObj.setAmount2(getSelectedProduct().getAmount2());
            } else {
                productObj.setAmount(getSelectedProduct().getAmount());
                productObj.setAmount2(amount);
            }
            
            productObj.setQuantity(getSelectedProduct().getQuantity());
            productObj.setQuantity2(getSelectedProduct().getQuantity2());
            productObj.setUtility(getSelectedProduct().getUtility());
            productObj.setUtility2(getSelectedProduct().getUtility2());
            productObj.setLife(getLife());
        } catch (Exception e) {
            productObj.setQuantity(0);
            productObj.setQuantity2(0);
            productObj.setUtility(0D);
            productObj.setUtility2(0D);
            productObj.setLife(0);
            
            if (getLoggedUser().getLocation().getId().equalsIgnoreCase("4d0859be-e31a-4acb-a690-2a5c2cb027a7")) {
                productObj.setAmount(amount);
                productObj.setAmount2(0D);
            } else {
                productObj.setAmount(0D);
                productObj.setAmount2(amount);
            }
            
        }
        
        if (serviceId.equalsIgnoreCase("PRODUCTO")) {
            productObj.setService(BasicType.DISABLED);
            productObj.setHerramienta(BasicType.DISABLED);
        }
        if (serviceId.equalsIgnoreCase("SERVICIO")) {
            productObj.setService(BasicType.ENEBLED);
            productObj.setHerramienta(BasicType.DISABLED);
        }
        if (serviceId.equalsIgnoreCase("HERRAMIENTA")) {
            productObj.setService(BasicType.DISABLED);
            productObj.setHerramienta(BasicType.ENEBLED);
        } else {
            productObj.setService(BasicType.DISABLED);
            productObj.setHerramienta(BasicType.DISABLED);
        }
        
        productObj.setCode(code);
        productObj.setName(name);
        productObj.setCompatibilidad(compatibilidad);
        productObj.setTipoUso(tipoUso);
        productObj.setActiveStatus(BasicType.ENEBLED);
        productObj.setClaveUnidad(getClaveUnidad());
        productObj.setClaveProductoServicio(getClaveProductoServicio());
        
        productCtrl.saveProduct(productObj, getLoggedUser().getId(), brandId);
        setClaveUnidad(null);
        setClaveProductoServicio(null);
        setIdClaveUnidad(null);
        setIdClaveProductoServicio(null);
        setName(null);
        setCode(null);
        setAmount(null);
        setQuantity(null);
        setUtility(null);
        setTipoUso(null);
        setCompatibilidad(null);
        setBrandId(null);
        setServiceId(null);
        setSelectedProduct(null);
        getProduct().clear();
        getProduct().add(findProductById(productObj.getId()));
        
        FacesMessage msg = new FacesMessage("Nuevo Producto", "Se agregó correctamente");
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }
    
    @Override
    public void deleteRow() {
        if ((getSelectedProduct().getQuantity() + getSelectedProduct().getQuantity2()) > 0) {
            showMessage(FacesMessage.SEVERITY_WARN, "Producto no eliminado", "No se pudo eliminar el producto porque aun tiene inventario disponible.");
            return;
        }
        productCtrl.deleteProduct(getSelectedProduct());
        getProduct().remove(getSelectedProduct());
        
        setSelectedProduct(null);
        showMessage(FacesMessage.SEVERITY_INFO, "Producto Eliminado", "Se eliminó correctamente.");
    }
    
    public List<Product> getProduct() {
        if (null == product) {
            product = new ArrayList<>();
        }
        return product;
    }
    
    public void setProduct(List<Product> product) {
        this.product = product;
    }
    
    public Product getSelectedProduct() {
        return selectedProduct;
    }
    
    public void setSelectedProduct(Product selectedProduct) {
        this.selectedProduct = selectedProduct;
    }
    
    public String getId() {
        return id;
    }
    
    public void setId(String id) {
        this.id = id;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getBrandId() {
        return brandId;
    }
    
    public void setBrandId(String brandId) {
        this.brandId = brandId;
    }
    
    public String getCode() {
        return code;
    }
    
    public void setCode(String code) {
        this.code = code;
    }
    
    public Double getAmount() {
        return amount;
    }
    
    public void setAmount(Double amount) {
        this.amount = amount;
    }
    
    public Double getUtility() {
        return utility;
    }
    
    public void setUtility(Double utility) {
        this.utility = utility;
    }
    
    public Integer getQuantity() {
        return quantity;
    }
    
    public void setQuantity(Integer quantity) {
        this.quantity = quantity;
    }
    
    public List<Brand> getBrandes() {
        return brandCtrl.fillProductBrandComboBox();
    }
    
    public Integer getLife() {
        return life;
    }
    
    public void setLife(Integer life) {
        this.life = life;
    }

    public boolean isShowQuantity() {
        return showQuantity;
    }

    public void setShowQuantity(boolean showQuantity) {
        this.showQuantity = showQuantity;
    }
    
    private static final long serialVersionUID = -4304755904973288208L;
    final Logger logger = LogManager.getLogger(ProductManager.class);
    
    private List<Product> product;
    private Product selectedProduct;
    
    private String id;
    private String name;
    private String brandId;
    private String serviceId;
    private String code;
    private String compatibilidad;
    private String tipoUso;
    private Double amount;
    private Double utility;
    private Integer quantity;
    private Integer life;
    private boolean showQuantity;
    
    private Product productByName;
    private Product productByCode;
    private String selectedBrandId;
    private String idClaveUnidad;
    private ClaveUnidad claveUnidad;
    private String idClaveProductoServicio;
    private ClaveProductoServicio claveProductoServicio;
    private ClaveUnidadController claveUnidadController;
    private ClaveProductoServicioController claveProductoServicioController;
    
    private ProductController productCtrl;
    private ProductBrandController brandCtrl;
    
    @PostConstruct
    public void init() {
        productCtrl = new ProductController();
        brandCtrl = new ProductBrandController();
        setClaveUnidadController(new ClaveUnidadController());
        setClaveProductoServicioController(new ClaveProductoServicioController());
        setShowQuantity(true);
    }
    
    public Product getProductByName() {
        return productByName;
    }
    
    public String getServiceId() {
        return serviceId;
    }
    
    public void setServiceId(String serviceId) {
        this.serviceId = serviceId;
    }
    
    public void setProductByName(Product productByName) {
        this.productByName = productByName;
    }
    
    public Product getProductByCode() {
        return productByCode;
    }
    
    public void setProductByCode(Product productByCode) {
        this.productByCode = productByCode;
    }
    
    public String getSelectedBrandId() {
        return selectedBrandId;
    }
    
    public void setSelectedBrandId(String selectedBrandId) {
        this.selectedBrandId = selectedBrandId;
    }
    
    public String getCompatibilidad() {
        return compatibilidad;
    }
    
    public void setCompatibilidad(String compatibilidad) {
        this.compatibilidad = compatibilidad;
    }
    
    public String getTipoUso() {
        return tipoUso;
    }
    
    public void setTipoUso(String tipoUso) {
        this.tipoUso = tipoUso;
    }
    
    public List<Product> fillDatatableProduct() {
        
        return productCtrl.fillProductDatatable();
    }
    
    public String getIdClaveUnidad() {
        return idClaveUnidad;
    }
    
    public void setIdClaveUnidad(String idClaveUnidad) {
        this.idClaveUnidad = idClaveUnidad;
    }
    
    public ClaveUnidad getClaveUnidad() {
        return claveUnidad;
    }
    
    public void setClaveUnidad(ClaveUnidad claveUnidad) {
        this.claveUnidad = claveUnidad;
    }
    
    public String getIdClaveProductoServicio() {
        return idClaveProductoServicio;
    }
    
    public void setIdClaveProductoServicio(String idClaveProductoServicio) {
        this.idClaveProductoServicio = idClaveProductoServicio;
    }
    
    public ClaveProductoServicio getClaveProductoServicio() {
        return claveProductoServicio;
    }
    
    public void setClaveProductoServicio(ClaveProductoServicio claveProductoServicio) {
        this.claveProductoServicio = claveProductoServicio;
    }
    
    public ClaveUnidadController getClaveUnidadController() {
        return claveUnidadController;
    }
    
    public void setClaveUnidadController(ClaveUnidadController claveUnidadController) {
        this.claveUnidadController = claveUnidadController;
    }
    
    public ClaveProductoServicioController getClaveProductoServicioController() {
        return claveProductoServicioController;
    }
    
    public void setClaveProductoServicioController(ClaveProductoServicioController claveProductoServicioController) {
        this.claveProductoServicioController = claveProductoServicioController;
    }

    /**
     *
     * @param isProductName
     * @param textToSearch
     * @return
     */
    public List<Product> searchProductsLikeField(boolean isProductName, String textToSearch) {
        try {
            return productCtrl.searchProductsLikeField(isProductName, textToSearch);
        } catch (Exception e) {
            return new ArrayList<>();
        }
    }

    /**
     *
     * @param brandId
     * @return
     */
    public List<Product> searchProductByBrand(String brandId) {
        try {
            if ("AllBrands".equals(brandId)) {
                return productCtrl.fillProductDatatable();
            } else if (brandId.length() == 36) {
                return productCtrl.searchProductByBrand(brandId);
            } else {
                return new ArrayList<>();
            }
        } catch (Exception e) {
            return new ArrayList<>();
        }
    }

    /**
     *
     * @param id
     * @return
     */
    public Product findProductById(String id) {
        try {
            return productCtrl.findProductById(id);
        } catch (Exception e) {
            return new Product();
        }
    }
    
    public boolean saveProductService(Product product, String brandId) {
        
        return productCtrl.saveProduct(product, getLoggedUser().getId(), brandId);
    }
    
    public void deleteProductService(Product product) {
        
        productCtrl.deleteProduct(product);
    }
    
    public List<Brand> getBrandesToProduct() {
        return brandCtrl.fillProductBrandComboBox();
    }
    
}
