import { CouponType, CouponRangeType, PromotionType } from "@/enums"
import { deepCopy } from "./common"

const BILLING_TYPE = {
    STEP: 1,
    FIXED: 2
}
const PRICE_TYPE = {
    NUM: 1,
    WEIGHT: 2,
    PRICE_FREE: 3,
    NUM_FREE: 4,
    FORBID: 5
}

function expressCalc_default(weight, num, template) {
    let { billingType, pricingType, baseNumber, baseAmount, addNumber, addCost, freightAmount } = template
    if (billingType == BILLING_TYPE.FIXED) {
        return freightAmount
    }
    return expressCalc_step(weight, num, pricingType, baseNumber, baseAmount, addNumber, addCost)
}

function expressCalc_item(price, weight, num, template, defaultPrice) {
    let { pricingType, baseNumber, baseAmount, addNumber, addCost, freeShippingAmount } = template
    if (pricingType == PRICE_TYPE.FORBID) {
        return 0
    } else if (pricingType == PRICE_TYPE.PRICE_FREE) {
        if (price >= freeShippingAmount) {
            return 0
        }
        return defaultPrice
    } else if (pricingType == PRICE_TYPE.NUM_FREE) {
        if (num >= freeShippingAmount) {
            return 0
        }
        return defaultPrice
    } else {
        return expressCalc_step(weight, num, pricingType, baseNumber, baseAmount, addNumber, addCost)
    }
}

function expressCalc_step(weight, num, pricingType, baseNumber, baseAmount, addNumber, addCost) {
    let conVal = pricingType == PRICE_TYPE.NUM ? num : weight
    if (conVal <= baseNumber) {
        return baseAmount
    } else {
        let addVal = parseInt((conVal - baseNumber) / addNumber)
        if ((conVal - baseNumber) % addNumber > 0) {
            addVal++;
        }
        return baseAmount + addVal * addCost;
    }
}

// 计算两数组的交集
function arrIntersection(arr1 = [], arr2 = []) {
    let arr2Map = {}
    arr2.forEach(a => {
        arr2Map[a] = true
    })
    return arr1.filter(a => arr2Map[a])
}

// 计算两数组的差集
function arrDiff(arr1 = [], arr2 = []) {
    let arr2Map = {}
    arr2.forEach(a => {
        arr2Map[a] = true
    })
    return arr1.filter(a => !arr2Map[a])
}


// 快递费计算
export function expressCalc(price, weight, num, template) {
    if (!template) {
        return 0
    }
    let { distributionTemplate, distributionTemplateItem } = template
    let defaultPrice = expressCalc_default(weight, num, distributionTemplate)
    if (distributionTemplateItem == null) {
        return defaultPrice
    }
    return expressCalc_item(price, weight, num, distributionTemplateItem, defaultPrice)
}


// 核查优惠券是否能使用
export function couponInitCheck(goodsMap, couponList, forbiddenCb) {
    let arr = []
    couponList.forEach(l => {
        let { skuIds, conditionVal, couponVal } = l
        let t = skuIds.reduce((prev, curr) => {
            let { originalPrice = 0, num = 0 } = goodsMap[curr]
            return prev + originalPrice * num
        }, 0)
        if (t < conditionVal) {
            forbiddenCb(l, true)
            arr.push(l)
        }
    })

    return arr
}

// 优惠券
export function couponItemCheck(goodsMap, couponList, item, disabledCb) {
    let allSkuIds = Object.keys(goodsMap)
    let { select, conditionVal, couponVal, skuIds: itemSkuIds, useSkuIds: itemUseSkuIds, couponId } = item

    let leftSkuIds = []
    couponList.map(c => c.useSkuIds).forEach(c => {
        if (c && c.length != 0) {
            c.forEach(s => {
                leftSkuIds.push(s)
            })
        }
    })
    leftSkuIds = arrDiff(allSkuIds, leftSkuIds)

    if (select) {
        let useSkuIds = arrIntersection(leftSkuIds, itemSkuIds)
        leftSkuIds = arrDiff(leftSkuIds, useSkuIds)
        item.useSkuIds = useSkuIds

        couponList.forEach(c => {
            if (c.forbidden) {
                return
            }
            if (c.disabled) {
                return
            }
            if (c.couponId == couponId) {
                return
            }
            if (c.select) {
                return
            }
            if (leftSkuIds.length == 0) {
                disabledCb(c, true)
                return
            }
            let arr = arrIntersection(leftSkuIds, c.skuIds)
            if (!arr || arr.length == 0) {
                disabledCb(c, true)
                return
            }
            let total = arr.reduce((prev, curr) => {
                let { originalPrice, num } = goodsMap[curr]
                return prev + originalPrice * num
            }, 0)
            if (total < c.conditionVal) {
                disabledCb(c, true)
                return
            }
        })
    } else {
        leftSkuIds = leftSkuIds.concat(itemUseSkuIds)
        item.useSkuIds = []

        couponList.forEach(c => {
            if (c.forbidden) {
                return
            }
            if (!c.disabled) {
                return
            }
            if (c.couponId == couponId) {
                return
            }
            if (c.select) {
                return
            }
            let arr = arrIntersection(c.skuIds, leftSkuIds)
            if (arr && arr.length !== 0) {
                disabledCb(c, false)
                return
            }
            let total = arr.reduce((prev, curr) => {
                let { originalPrice, num } = goodsMap[curr]
                return prev + originalPrice * num
            }, 0)
            if (total >= c.conditionVal) {
                disabledCb(c, false)
                return
            }
        })
    }
}


// 促销计算
export function promotionCalc(goodsMap, promotionList) {
    return promotionList.reduce((prev, curr) => {
        let total = 0
        let { type, marketingPromotionRules: ruleList, skuIds } = curr
        let totalPrice = skuIds.reduce((sPrev, sCurr) => {
            let { originalPrice, num } = goodsMap[sCurr]
            return sPrev + originalPrice * num
        }, 0)
        if (type == PromotionType.FULL_DIRECTION) {
            let rule = ruleList.reverse().find(r => totalPrice > r.conditionVal)
            if (rule) {
                total = rule.promotionVal
            }
        } else if (type == PromotionType.FULL_DISCOUNT) {
            let rule = ruleList.reverse().find(r => totalPrice > r.conditionVal)
            if (rule) {
                total = (1 - rule.promotionVal) * totalPrice
            }
        } else if (type == PromotionType.DIRECT_REDUCTION) {
            total = ruleList[0].promotionVal
            if(ruleList[0].promotionVal > totalPrice){
                total = totalPrice
            }

        } else if (type == PromotionType.DISCOUNT) {
            total = (1 - ruleList[0].promotionVal) * totalPrice
        } else if (type == PromotionType.EVERY_REDUCTION) {
            let { conditionVal, promotionVal } = ruleList[0]
            total = parseInt(totalPrice / conditionVal) * promotionVal
        }

        return prev + total
    }, 0)
}
