
import orderService from "@/services/resources/OrderService";
import resumeOrderService from "@/services/resources/ResumeOrderService";


export default {

    initOrderCreate: context => {
        var service = orderService.build();

        return new Promise((resolve, reject) => {

            service
                .get("/create?sales_consultant_id=" + context.state.salesConsultantId)
                .then(resp => {

                    context.commit("initState", resp);
                    context.dispatch('searchLatestOrders');
                   
                    if (resp.order) {
                        context.commit('setOrderId', resp.order.id);
                        context.dispatch('setPaymentMethod', {payment_method: resp.order.payment_method})
                        .catch( err => {
                            reject(err);
                        });

                        resp.order.itens.forEach(item => {

                            if (parseFloat(item.pivot.unitary_value) > 0) {

                                context.dispatch('updateOrder', {
                                    product_per_campaign: item,
                                    quantity: item.pivot.quantity
                                });
                            }
                        });

                    }

                    resolve(resp);
                })
                .catch(err => {
                    console.log("err");

                    reject(err);
                })

        });



    },
    searchLatestOrders: context => {
        
        return new Promise((resolve, reject) => {
            
        var service = resumeOrderService.build();
        let filters = {
          campaigns_code: "1020,1120,0920,0820",//Está fixo para atender campanha 12
          order_by: "DESC"
        };
  
        if (context.state.salesConsultantId > 0) {
          filters.sales_consultant_id = context.state.salesConsultantId;
        }
        service
          .search(filters)
          .then(resp => {
            if (resp.length == 0) {
              context.commit("setResumeLastOrderValue", 0);
            } else {
                context.commit("setResumeLastOrderValue", resp[0].amount_catalog);
            }
            resolve(resp);
          })
          .catch(err => {
            reject(err);
          });
        });
      },
    resetOrderCreate: context => {
        context.commit('resetState');
    },
    setSettings: (state, payload) => {
        state.settings = payload;
    },
    setPaymentMethod: (context, payload) => {

        return new Promise( (resolve, reject) => {

            if(payload.payment_method == 'CREDIT_CARD' && 
                !context.rootGetters.isSalesConsultant ){
                    reject({msg: "O perfil não pode fazer pagamento com cartão de crédito."});
                    return;
            }
      
            if(context.rootGetters.isPromoter && context.rootGetters.isPromotherInOtherOrder){
                reject({msg: "O perfil não pode fazer pagamento com cartão de crédito para esse pedido."});
                return;
            }
          
      
            if(payload.payment_method == 'CREDIT_CARD'){
              context.commit( 'setStatus' ,"TYPED");
            }
            context.commit('setPaymentMethod', payload);
            resolve({msg: "Tipo de pagamento alterado"});
        } );

    },
    setSalesConsultantIdOrderCreate(context, payload) {

        if (context.rootGetters.isManagerSalesConsultant || context.rootGetters.isPromoter
           || context.rootGetters.isSAC || context.rootGetters.isManagerComercial) {
            context.commit('setSalesConsultant', payload.id);
            context.commit('setSalesConsultantObject', payload);
        } else {
            context.commit('setSalesConsultant', context.rootState.user.user.sales_consultant.id);
            context.commit('setSalesConsultantObject', context.rootState.user.user.sales_consultant);
        }

    },
    updateOrder: (context, payload) => {

        

        let findedProduct = context.getters.getOrderById(payload.product_per_campaign.id);

        if (!findedProduct) {
            context.commit('addProduct', payload);
            context.dispatch('applyPromotions');
        } else {
            let productWithNewQty = {
                product_per_campaign: payload.product_per_campaign,
                quantity: findedProduct.quantity + payload.quantity
            }

            context.commit('updateProductQuantity', productWithNewQty);
        }
      //  context.dispatch('normalizeFreeProducts');
      //  console.log("******************** Promoções aplicadas *******************");

    },
    updateProductQuantity(context, payload) {
       // context.dispatch('removeFreeProducts');
        context.commit('updateProductQuantity', payload);
        context.dispatch('applyPromotions');
        //context.dispatch('normalizeFreeProducts');
    },
    /**
     * 
     * 
     */
    removeProduct(context, index) {
       // context.dispatch('removeFreeProducts');
        context.commit('removeProduct', index);
        context.dispatch('applyPromotions');
        //context.dispatch('normalizeFreeProducts');
    },
    //Limpar todos produtos gratuitos
    removeFreeProducts(context){
        console.log("***********  Remover free *****************");
        var itens = context.getters.getOrdeWithCatalogPrice();
        itens.forEach(item => {
            if(item.total == 0){
                
            let findedProduct = context.getters.getOrderById( item.product_per_campaign_id);
            context.commit('updateProductQuantity', {
                product_per_campaign: { id: item.product_per_campaign_id},
                quantity: findedProduct.quantity - item.quantity
            });

        }
       
        
    });

    },
    //Remover produtos que ficaram com a quatida zerada após promoções
    removeProducsWithZeroItens(context){

        context.state.order_products.forEach( (item,index) =>{
            if(item.quantity == 0){
                context.commit('removeProduct', index);
            }
        });

    },

    normalizeFreeProducts(context){
        console.log("***********  Normalizar free *****************");
        console.log(context.getters.getOrdeWithCatalogPrice());
        /*
        var order  = context.getters.getOrder();
        var itensWithCatalogPrices = context.getters.getOrdeWithCatalogPrice();
        order.forEach( (item,index) => {

            if(item.product_per_campaign.digitable){
                return;
            }

          let findedProduct = itensWithCatalogPrices.find( itemWithCatalog => 
                itemWithCatalog.total == 0 && itemWithCatalog.product_per_campaign_id == item.product_per_campaign.id);

                if(findedProduct){
                    context.commit('updateProductQuantity', {
                        product_per_campaign: { id: findedProduct.product_per_campaign_id},
                        quantity: findedProduct.quantity
                    });
                }

        });

        */

       var itens = context.getters.getOrdeWithCatalogPrice();
        itens.forEach(item => {
            
            let findedProduct = context.getters.getOrderById( item.product_per_campaign_id);
            
            if(!findedProduct.product_per_campaign.digitable && item.total > 0){
            
              
           
                context.dispatch('updateProductQuantity', {
                    product_per_campaign: { id: item.product_per_campaign_id},
                    quantity: findedProduct.quantity - item.quantity
                });
                
         

        }
       
        
    });

    context.dispatch('removeProducsWithZeroItens');

    },

    /**
     * 
     * 
     */


    // Aplicar Promoções
    applyPromotions(context) {
      //  context.dispatch('removeFreeProducts');
     // console.log("Adicionar Promoções");
        let promotions = context.state.promotions;

        promotions.forEach(promotion => {


            let quantity = promotionEnabled(context, promotion);

            if (quantity > 0) {
//console.log("Promoção ativa " + quantity);
//console.log(promotion);
                applyPromotions(context, promotion, quantity)
            }


        });

        context.dispatch('applyPromotionsProgressive');

    },
    //Aplicar Promoções com desconto progressivo
    applyPromotionsProgressive(context) {

        let promotions = context.state.promotions_progressive;

        promotions.forEach(promotion => {

            let products = context.state.order_products.filter( productOrder => {
                return promotion.products_per_campaigns.find( productPerCampaign =>
                     productOrder.product_per_campaign.id == productPerCampaign.id  );
            } );

            if (products.length == 0) {
                return;
            }

           // console.log("##### Promoções Progressivas ####");

           let totalQuantity = products.reduce((total, current) => total + (current.quantity || 0), 0);

            let productFinded = context.getters.getOrderById(promotion.product_per_campaign_id);


            let range = promotionProgressiveRange(promotion, totalQuantity);

            if (range != null) {
                applyPromotionsProgressive(context, products, range)
            }

        });

        context.dispatch('addFreeProducts');
    },

    /*
    *Adicionar produtos gratuitos
    */

    addFreeProducts(context) {

        context.dispatch('normalizeFreeProducts');
        let promotions = context.state.promotions;

        promotions.forEach(promotion => {


            let quantity = promotionEnabled(context, promotion);

            if (quantity == 0) {
                return;
            }

            let takeProducts = promotion.promotion_has_take_product_per_campaign;

            takeProducts.forEach(product => {

                let productFinded = context.getters.getOrderById(product.product_per_campaign_id);
                let takeProductIsFree = takeFreeProduct(promotion, product);
                if (productFinded && takeProductIsFree) {
                    if (productFinded.quantity < quantity) {

                        context.dispatch('updateProductQuantity', { product_per_campaign: product.product_per_campaign, quantity: quantity });

                    }
                } else if (!productFinded && takeProductIsFree) {
                    context.dispatch('updateOrder', {
                        product_per_campaign: product.product_per_campaign,
                        quantity: quantity
                    });
                }

            });




        });

        
        context.dispatch('removeProducsWithZeroItens');
        context.dispatch('updateOrderPrices');
    },
    
    updateOrderPrices({ commit, getters }) {
        commit('updateOrderPrices', { getters });
        commit('updateComputedOrder');

    },
    async saveOrder(context) {

        if (context.getters.getOrdeWithCatalogPrice().length == 0 || context.state.calendar == null) {

            return new Promise((resolve, reject) => {
                resolve({ msg: "Não há produtos para salvar" });
            });

            return;
        }

        if(context.state.status == 'TYPED'){
            return new Promise((resolve, reject) => {
                resolve({ msg: "Não salvar status TYPED" });
            });

        }

        var itens = context.getters.getOrdeWithCatalogPrice();

        var data = {
            sales_consultant_id: context.state.salesConsultantId,
            status: context.state.status,
            itens: itens,
            payment_method: context.state.payment_method,
            campaign_id: context.state.calendar.campaign_id,
            amount_total: context.getters.getTotalToPay,
            shipping_cost: 0,
            incentives: context.getters.getConqueredIncentives.map(incentive => incentive.id),
            campaign_benchmarking_range_id: null,
            service:  context.state.service
        };

        if (typeof (context.getters.getBenchmarkingRange) != 'undefined') {
            data.shipping_cost = parseFloat(context.getters.getBenchmarkingRange.shipping_value);
            data.campaign_benchmarking_range_id = context.getters.getBenchmarkingRange.id;
        }

        if (context.state.orderId === 0) {
            return await createOrder(context, data);
        } else {
            return await updateOrder(context.state.orderId, data);
        }



    }

}//fim das actions


/**
 * 
 * Funções auxiliares
 */
function promotionEnabled(context, promotion) {
   
    var toApplay = 0;

    if(promotion.buy_type === "OR"){
        //console.log("Promocão OR");
        toApplay =  promotionEnabledToTypeOr(context,promotion);
        //console.log(toApplay);

    }else if(promotion.buy_type === "AND"){
       // console.log("Promocão end");
        toApplay = promotionEnabledToTypeAnd(context,promotion);
       // console.log(toApplay);
    }

    
    

    return toApplay;
}

function promotionEnabledToTypeOr(context, promotion){
    let buyProducts = promotion.promotion_has_buy_product_per_campaign;
    var toApplay = 0;
    buyProducts.forEach(product => {

        let productFinded = context.getters.getOrderById(product.product_per_campaign_id);
        if (productFinded && productFinded.quantity >= product.quantity) {
          
                //console.log(product);
                //console.log("encomtrado");
               // console.log(productFinded);
                toApplay += Math.floor(productFinded.quantity / product.quantity);

    

        } else {
           // console.log("Produto não encontrado");
        }
    });

    return toApplay;
}

function promotionEnabledToTypeAnd(context, promotion){

    var buyProducts = promotion.promotion_has_buy_product_per_campaign;
    var toApplay = 0;

    for(let index = 0 ; index < buyProducts.length; index++){
        let product = buyProducts[index];
        let productFinded = context.getters.getOrderById(product.product_per_campaign_id);

        //Product not found
        if(!productFinded){
           // console.log("End, produto não encontrado");
            toApplay = 0;
            break;
        }

        if(productFinded.quantity >= product.quantity){

            let productToApplay = Math.floor(productFinded.quantity / product.quantity);

            if(productToApplay < toApplay || toApplay == 0){
                toApplay = productToApplay;
            }


        }else{//no quanity min to applay promotion
            //console.log("End, Quantidade insuficiente");
            toApplay = 0;
            break;
        }



    }//endfor


    return toApplay;

}

function promotionProgressiveRange(promotion, qtyInOrder) {

    var rangeToApplay = null;




    promotion.range.forEach(range => {

        if (qtyInOrder >= range.quantity) {
            rangeToApplay = range;
        }

    });

    return rangeToApplay;
}


function applyPromotions(context, promotion, quantity) {

    let takeProducts = promotion.promotion_has_take_product_per_campaign;
    var applayed = 0;
   console.log("Aplicar Promoção:" + quantity);


   for(let i =0 ; i < takeProducts.length ; i++){
        
    let product = takeProducts[i];

        if (promotion.take_type === "AND") {
            applayed = 0;
        } else if (applayed == quantity) {
           break;
        }
   
   /* takeProducts.forEach(product => {

        if (promotion.take_type === "AND") {
            applayed = 0;
        } else if (applayed == quantity) {
            return;
        }
*/

        let productFinded = context.getters.getOrderById(product.product_per_campaign_id);
        if (productFinded) {


            let qtyToApplay = 0;

            if(promotion.take_type == 'AND'){
                qtyToApplay =  (productFinded.quantity >= quantity) ? quantity : productFinded.quantity;
            }else{
                let enabled = quantity - applayed;

                qtyToApplay =  (productFinded.quantity >= enabled) ? enabled : productFinded.quantity;
            }

            let discountValue = getValueDiscount(productFinded.product_per_campaign.catalog_value,
                promotion.discount_type,
                product.discount);
            let totalDiscount = (discountValue * qtyToApplay);

            //console.log("Aplicar:" + qtyToApplay);
            //console.log("Valor: " + discountValue);
            //console.log("Valor aplicado: " + totalDiscount);

            let payload = { product_per_campaign: productFinded.product_per_campaign, discountPromotion: totalDiscount, promotion: { promotionId: promotion.id, quantity: qtyToApplay } };

            context.commit('updateProductPromotionDiscount', payload);


            applayed += qtyToApplay;


        }

    // });
    }

}


function applyPromotionsProgressive(context, productsInOrder, rangeDiscount) {

    productsInOrder.forEach( productInOrder => {
   
        let valueDiscount = getValueDiscount(productInOrder.product_per_campaign.catalog_value,
            rangeDiscount.discount_type,
            rangeDiscount.discount
        );
    
        let totalDiscount = valueDiscount * productInOrder.quantity;
    
        let payload = { product_per_campaign: productInOrder.product_per_campaign, discountPromotion: totalDiscount, promotionProgressive: rangeDiscount };
        context.commit('updateProductPromotionDiscount', payload);

    } );

}

function getValueDiscount(productCatalogPrice, typeDiscount, valueDiscount) {

    if (typeDiscount === "PERCENT") {

        return parseFloat(valueDiscount) * parseFloat(productCatalogPrice) / 100;

    } else {

        return valueDiscount;

    }


}

function takeFreeProduct(promotion, productTake) {

    if (promotion.discount_type === "PERCENT" & productTake.discount == 100) {
        return true;
    }

    return false;
}


function createOrder(context, data) {
    var service = orderService.build();
    return new Promise((resolve, reject) => {

        service
            .create(data)
            .then(resp => {
                context.commit('setOrderId', resp.data.id)
                resolve(resp);
            })
            .catch(err => {
                console.log("err");

                reject(err);
            })

    })


}

function updateOrder(id, data) {

    data._method = "PUT";
    data.id = id;
    var service = orderService.build();
    return new Promise((resolve, reject) => {

        service
            .update(data)
            .then(resp => {

                resolve(resp);
            })
            .catch(err => {
                console.log("err");

                reject(err);
            })

    });

}

