package com.storlead.sales.util;

import com.storlead.sales.util.sku.constants.SsdSkuConstants;
import com.storlead.sales.pojo.vo.sku.MakeOrderSkuDetailVO;
import com.storlead.sales.config.SsdSkuConfigProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;

/**
 * @Author: Timo
 * @Date: 2019/1/10 11:36
 * @Description: 类用途：计算sku单价
 * 这里计算的是某个sku区间内的单价
 * 因为没有不同的区间价格不一样。
 */
public class SsdSkuPriceUtil {

    public static final BigDecimal ZERO = BigDecimal.ZERO;
    public static final BigDecimal ONE = BigDecimal.ONE;
    public static final BigDecimal ONE_HUNDRED = BigDecimal.valueOf(100);
    /**
     * 定金金额的百分比
     */
    public static final BigDecimal EARNEST_AMOUNT_PERCENTAGE = BigDecimal.valueOf(0.3);

    private static Logger log = LoggerFactory.getLogger(SsdSkuPriceUtil.class);
    private BigDecimal unitPrice;
    private Integer dayCount;


    /**
     * 计算该区间内sku的单价并且是不包含国家规定的税率
     * 需要注意的是： 这里的计算如果某一项功能需要强制开通的时候不管用户是否需要开通这里都会将开发费用计算进去
     * 公式：(工人费用成本 + 物料费用成本 + 主控成本 + Flash 成本 + 可选功能成本 ) / (1 - 毛利率)
     *
     * @param skuDetail           sku详情信息
     * @param openPhysicalDestroy 用户是否需要开通 物理销毁 true 开通/ false 不开通
     * @param openLogicDestroy    用户是否需要开通 逻辑销毁 true 开通/ false 不开通
     * @param openAesEncrypt      用户是否需要开通 ASE加密 true 开通/ false 不开通
     * @param openRapidBackup     用户是否需要开通 快速备份 true 开通/ false 不开通
     * @return
     */
    public static BigDecimal getSsdSkuUnitPrice(MakeOrderSkuDetailVO skuDetail, boolean openPhysicalDestroy, boolean openLogicDestroy, boolean openAesEncrypt, boolean openRapidBackup) {
        // sku 单价初始价格
        BigDecimal skuUnitPrice = ZERO;
        skuUnitPrice = skuUnitPrice
                .add(getProcessingPricing(skuDetail))
                .add(getMaterialPricing(skuDetail))
                .add(getCoreChipPrice(skuDetail))
                .add(getFlashChipPrice(skuDetail))
                .add(getPhysicalDestroyPrice(skuDetail, openPhysicalDestroy))
                .add(getLogicDestroyPrice(skuDetail, openLogicDestroy))
                .add(getAesEncryptPrice(skuDetail, openAesEncrypt))
                .add(getRapidBackupPrice(skuDetail, openRapidBackup))
        ;

        BigDecimal rate = ONE.subtract(skuDetail.getRate().divide(ONE_HUNDRED));
        rate = (rate.compareTo(ZERO) == 0) ? ONE : rate;

        return skuUnitPrice.divide(rate, 2, BigDecimal.ROUND_HALF_EVEN);
    }

    /**
     * 计算该区间内sku的单价并且是不包含国家规定的税率
     * 需要注意的是： 这里的计算如果某一项功能需要强制开通的时候不管用户是否需要开通这里都会将开发费用计算进去
     * 公式：(工人费用成本 + 物料费用成本 + 主控成本 + Flash 成本 + 可选功能成本 ) / (1 - 毛利率)
     *
     * @param skuDetail           sku详情信息
     * @param openPhysicalDestroy 用户是否需要开通 物理销毁 1 开通/ 非1 不开通
     * @param openLogicDestroy    用户是否需要开通 逻辑销毁 1 开通/ 非1 不开通
     * @param openAesEncrypt      用户是否需要开通 ASE加密 1 开通/ 非1 不开通
     * @param openRapidBackup     用户是否需要开通 快速备份 1 开通/ 非1 不开通
     * @return
     */
    public static BigDecimal getSsdSkuUnitPrice(MakeOrderSkuDetailVO skuDetail, Integer openPhysicalDestroy, Integer openLogicDestroy, Integer openAesEncrypt, Integer openRapidBackup) {

        return getSsdSkuUnitPrice(skuDetail,
                openPhysicalDestroy.equals(SsdSkuConstants.OPEN_PHYSICALDESTROY),
                openLogicDestroy.equals(SsdSkuConstants.OPEN_LOGICDESTROY),
                openAesEncrypt.equals(SsdSkuConstants.OPEN_AESENCRYPT),
                openRapidBackup.equals(SsdSkuConstants.OPEN_RAPIDBACKUP)
        );
    }

    /**
     * 计算该区间内sku的单价，包含国家规定的税率
     * 需要注意的是： 这里的计算如果某一项功能需要强制开通的时候不管用户是否需要开通这里都会将开发费用计算进去
     * 公式：(工人费用成本 + 物料费用成本 + 主控成本 + Flash 成本 + 可选功能成本 ) / (1 - 毛利率) X (1+增值税)
     *
     * @param skuDetail           sku详情信息
     * @param openPhysicalDestroy 用户是否需要开通 物理销毁 1 开通/ 非1 不开通
     * @param openLogicDestroy    用户是否需要开通 逻辑销毁 1 开通/ 非1 不开通
     * @param openAesEncrypt      用户是否需要开通 ASE加密 1 开通/ 非1 不开通
     * @param openRapidBackup     用户是否需要开通 快速备份 1 开通/ 非1 不开通
     * @param configProperties    sku 计算需要的参数
     *                            zhCNTaxPriceRate          中国含税利率
     *                            physicalDestroyDays       物理销毁需要的天数
     *                            logicDestroyDays          逻辑销毁需要的天数
     *                            aesEncryptDays            aes 加密需要天数
     *                            rapidBackupDays           rapidBackup需要天数
     * @return
     */
    public static BigDecimal getSsdSkuTaxUnitPrice(MakeOrderSkuDetailVO skuDetail, Integer openPhysicalDestroy, Integer openLogicDestroy, Integer openAesEncrypt, Integer openRapidBackup, SsdSkuConfigProperties configProperties) {
        BigDecimal unitPrice = new BigDecimal(0);
        int i = skuDetail.getAdditionalSurcharges().compareTo(BigDecimal.ZERO);
        if (skuDetail.getAdditionalSurcharges() == null || i == 0) {
            unitPrice = getSsdSkuUnitPrice(skuDetail, openPhysicalDestroy, openLogicDestroy, openAesEncrypt, openRapidBackup);
        } else {
            unitPrice = skuDetail.getSkuunitPrice();
        }
        return unitPrice.multiply(ONE.add(configProperties.getZhCNTaxPriceRate())).setScale(2, BigDecimal.ROUND_HALF_EVEN);
    }


    /**
     * 计算该区间内sku的单价，包含国家规定的税率
     * 需要注意的是： 这里的计算如果某一项功能需要强制开通的时候不管用户是否需要开通这里都会将开发费用计算进去
     * 公式：(工人费用成本 + 物料费用成本 + 主控成本 + Flash 成本 + 可选功能成本 ) / (1 - 毛利率) X (1+0.16)
     *
     * @param skuDetail           sku详情信息
     * @param openPhysicalDestroy 用户是否需要开通 物理销毁 true 开通/ false 不开通
     * @param openLogicDestroy    用户是否需要开通 逻辑销毁 true 开通/ false 不开通
     * @param openAesEncrypt      用户是否需要开通 ASE加密 true 开通/ false 不开通
     * @param openRapidBackup     用户是否需要开通 快速备份 true 开通/ false 不开通
     * @param configProperties    sku 计算需要的参数
     *                            zhCNTaxPriceRate          中国含税利率
     *                            physicalDestroyDays       物理销毁需要的天数
     *                            logicDestroyDays          逻辑销毁需要的天数
     *                            aesEncryptDays            aes 加密需要天数
     *                            rapidBackupDays           rapidBackup需要天数
     * @return
     */
    public static BigDecimal getSsdSkuTaxUnitPrice(MakeOrderSkuDetailVO skuDetail, boolean openPhysicalDestroy, boolean openLogicDestroy, boolean openAesEncrypt, boolean openRapidBackup, SsdSkuConfigProperties configProperties) {
        BigDecimal unitPrice = getSsdSkuUnitPrice(skuDetail, openPhysicalDestroy, openLogicDestroy, openAesEncrypt, openRapidBackup);
        return unitPrice.multiply(ONE.add(configProperties.getZhCNTaxPriceRate())).setScale(2, BigDecimal.ROUND_HALF_EVEN);
    }

    /**
     * 获取开发这一款sku 需要的天数
     *
     * @param skuDetail           sku详情信息
     * @param openPhysicalDestroy 用户是否需要开通 物理销毁 true 开通/ false 不开通
     * @param openLogicDestroy    用户是否需要开通 逻辑销毁 true 开通/ false 不开通
     * @param openAesEncrypt      用户是否需要开通 ASE加密 true 开通/ false 不开通
     * @param openRapidBackup     用户是否需要开通 快速备份 true 开通/ false 不开通
     * @param configProperties    sku 计算需要的参数
     *                            zhCNTaxPriceRate          中国含税利率
     *                            physicalDestroyDays       物理销毁需要的天数
     *                            logicDestroyDays          逻辑销毁需要的天数
     *                            aesEncryptDays            aes 加密需要天数
     *                            rapidBackupDays           rapidBackup需要天数
     * @return
     */
    public static int getSsdSkuEstimateDay(MakeOrderSkuDetailVO skuDetail, boolean openPhysicalDestroy, boolean openLogicDestroy, boolean openAesEncrypt, boolean openRapidBackup, SsdSkuConfigProperties configProperties) {
        int dayCount = skuDetail.getEstimateDay();
        log.info("基本天数：{}", dayCount);
        // 支持开通物理销毁 并且开通了物理销毁
        // 强制开通物理销毁
        if (openPhysicalDestroy
                && skuDetail.getOpenPhysicalDestroy().intValue() == SsdSkuConstants.OPEN_PHYSICALDESTROY
                || skuDetail.getOpenPhysicalDestroy().intValue() == SsdSkuConstants.OPEN_PHYSICALDESTROY
                && skuDetail.getForceOpenPhysicalDestroy()) {
            log.info("开通物理销毁");
            dayCount = dayCount + configProperties.getPhysicalDestroyDays();
        }

        // 支持开通逻辑销毁 并且开通了逻辑销毁
        // 强制开通逻辑销毁
        if (openLogicDestroy
                && skuDetail.getOpenLogicDestroy().intValue() == SsdSkuConstants.OPEN_LOGICDESTROY
                || skuDetail.getOpenLogicDestroy().intValue() == SsdSkuConstants.OPEN_LOGICDESTROY
                && skuDetail.getForceOpenLogicDestroy()) {
            log.info("开通逻辑销毁");
            dayCount = dayCount + configProperties.getLogicDestroyDays();
        }

        // 支持开通AES加密 并且开通了AES加密
        // 强制开通AES加密
        if (openAesEncrypt
                && skuDetail.getOpenAesEncrypt().intValue() == SsdSkuConstants.OPEN_AESENCRYPT
                || skuDetail.getOpenAesEncrypt().intValue() == SsdSkuConstants.OPEN_AESENCRYPT
                && skuDetail.getForceOpenAesEncrypt()) {
            log.info("开通AES加密");
            dayCount = dayCount + configProperties.getAesEncryptDays();
        }

        // 支持开通RapidBackup 并且开通了RapidBackup
        // 强制开通RapidBackup
        if (openRapidBackup
                && skuDetail.getOpenRapidBackup() == SsdSkuConstants.OPEN_RAPIDBACKUP
                || skuDetail.getOpenRapidBackup() == SsdSkuConstants.OPEN_RAPIDBACKUP
                && skuDetail.getForceOpenRapidBackup()) {
            log.info("开通快速备份");
            dayCount = dayCount + configProperties.getRapidBackupDays();
        }
        return dayCount;
    }


    /**
     * 获取开发这一款sku 需要的天数
     *
     * @param skuDetail           sku详情信息
     * @param openPhysicalDestroy 用户是否需要开通 物理销毁 1 开通/ 非1 不开通
     * @param openLogicDestroy    用户是否需要开通 逻辑销毁 1 开通/ 非1 不开通
     * @param openAesEncrypt      用户是否需要开通 ASE加密 1 开通/ 非1 不开通
     * @param openRapidBackup     用户是否需要开通 快速备份 1 开通/ 非1 不开通
     * @param configProperties    sku 计算需要的参数
     *                            zhCNTaxPriceRate          中国含税利率
     *                            physicalDestroyDays       物理销毁需要的天数
     *                            logicDestroyDays          逻辑销毁需要的天数
     *                            aesEncryptDays            aes 加密需要天数
     *                            rapidBackupDays           rapidBackup需要天数
     * @return
     */
    public static int getSsdSkuEstimateDay(MakeOrderSkuDetailVO skuDetail, Integer openPhysicalDestroy, Integer openLogicDestroy, Integer openAesEncrypt, Integer openRapidBackup, SsdSkuConfigProperties configProperties) {
        int dayCount = skuDetail.getEstimateDay();

        // 支持开通物理销毁 并且开通了物理销毁
        // 强制开通物理销毁
        if (openPhysicalDestroy.intValue() == SsdSkuConstants.OPEN_PHYSICALDESTROY
                && skuDetail.getOpenPhysicalDestroy().intValue() == SsdSkuConstants.OPEN_PHYSICALDESTROY
                || skuDetail.getOpenPhysicalDestroy().intValue() == SsdSkuConstants.OPEN_PHYSICALDESTROY
                && skuDetail.getForceOpenPhysicalDestroy()) {
            dayCount = dayCount + configProperties.getPhysicalDestroyDays();
        }

        // 支持开通逻辑销毁 并且开通了逻辑销毁
        // 强制开通逻辑销毁
        if (openLogicDestroy.intValue() == SsdSkuConstants.OPEN_LOGICDESTROY
                && skuDetail.getOpenLogicDestroy().intValue() == SsdSkuConstants.OPEN_LOGICDESTROY
                || skuDetail.getOpenLogicDestroy().intValue() == SsdSkuConstants.OPEN_LOGICDESTROY
                && skuDetail.getForceOpenLogicDestroy()) {
            dayCount = dayCount + configProperties.getLogicDestroyDays();
        }

        // 支持开通AES加密 并且开通了AES加密
        // 强制开通AES加密
        if (openAesEncrypt.intValue() == SsdSkuConstants.OPEN_AESENCRYPT
                && skuDetail.getOpenAesEncrypt().intValue() == SsdSkuConstants.OPEN_AESENCRYPT
                || skuDetail.getOpenAesEncrypt().intValue() == SsdSkuConstants.OPEN_AESENCRYPT
                && skuDetail.getForceOpenAesEncrypt()) {
            dayCount = dayCount + configProperties.getAesEncryptDays();
        }

        // 支持开通RapidBackup 并且开通了RapidBackup
        // 强制开通RapidBackup
        if (openRapidBackup.intValue() == SsdSkuConstants.OPEN_RAPIDBACKUP
                && skuDetail.getOpenRapidBackup() == SsdSkuConstants.OPEN_RAPIDBACKUP
                || skuDetail.getOpenRapidBackup() == SsdSkuConstants.OPEN_RAPIDBACKUP
                && skuDetail.getForceOpenRapidBackup()) {
            dayCount = dayCount + configProperties.getRapidBackupDays();
        }
        return dayCount;
    }

    /**
     * 获取 单片用工费用
     *
     * @param skuDetail
     * @return
     */
    private static BigDecimal getProcessingPricing(MakeOrderSkuDetailVO skuDetail) {
        return skuDetail.getProcessingPricing();
    }

    /**
     * // 单片物料成本
     *
     * @param skuDetail
     * @return
     */
    private static BigDecimal getMaterialPricing(MakeOrderSkuDetailVO skuDetail) {
        return skuDetail.getMaterialPricing();
    }

    private static BigDecimal getCoreChipPrice(MakeOrderSkuDetailVO skuDetail) {
        return skuDetail.getCoreChipPrice();
    }

    /**
     * 获取 Flash 的价格
     *
     * @param skuDetail
     * @return
     */
    private static BigDecimal getFlashChipPrice(MakeOrderSkuDetailVO skuDetail) {
        return skuDetail.getFlashChipPrice().multiply(BigDecimal.valueOf(skuDetail.getFlashChipCount()));
    }

    /**
     * 获取物理销毁的价格
     * 需要判断一下 支不支持开通物理销毁
     * 需要判断一下 是否强制要求开通物理销毁
     *
     * @param skuDetail
     * @param openPhysicalDestroy
     * @return
     */
    private static BigDecimal getPhysicalDestroyPrice(MakeOrderSkuDetailVO skuDetail, boolean openPhysicalDestroy) {

        // 支持开通物理销毁 并且开通了物理销毁
        // 强制开通物理销毁
        if (openPhysicalDestroy
                && skuDetail.getOpenPhysicalDestroy().intValue() == SsdSkuConstants.OPEN_PHYSICALDESTROY
                || skuDetail.getOpenPhysicalDestroy().intValue() == SsdSkuConstants.OPEN_PHYSICALDESTROY
                && skuDetail.getForceOpenPhysicalDestroy()) {
            return skuDetail.getPhysicalDestroyPrice();
        }
        return ZERO;
    }

    /**
     * 获取逻辑销毁的价格
     *
     * @param skuDetail
     * @param openLogicDestroy
     * @return
     */
    private static BigDecimal getLogicDestroyPrice(MakeOrderSkuDetailVO skuDetail, boolean openLogicDestroy) {
        // 支持开通逻辑销毁 并且开通了逻辑销毁
        // 强制开通逻辑销毁
        if (openLogicDestroy
                && skuDetail.getOpenLogicDestroy().intValue() == SsdSkuConstants.OPEN_LOGICDESTROY
                || skuDetail.getOpenLogicDestroy().intValue() == SsdSkuConstants.OPEN_LOGICDESTROY
                && skuDetail.getForceOpenLogicDestroy()) {
            return skuDetail.getLogicDestroyPrice();
        }
        return openLogicDestroy == true ? skuDetail.getLogicDestroyPrice() : ZERO;
    }

    /**
     * 获取 aes 加密的价格
     *
     * @param skuDetail
     * @param openAesEncrypt
     * @return
     */
    private static BigDecimal getAesEncryptPrice(MakeOrderSkuDetailVO skuDetail, boolean openAesEncrypt) {
        // 支持开通AES加密 并且开通了AES加密
        // 强制开通AES加密
        if (openAesEncrypt
                && skuDetail.getOpenAesEncrypt().intValue() == SsdSkuConstants.OPEN_AESENCRYPT
                || skuDetail.getOpenAesEncrypt().intValue() == SsdSkuConstants.OPEN_AESENCRYPT
                && skuDetail.getForceOpenAesEncrypt()) {
            return skuDetail.getAesEncryptPrice();
        }
        return ZERO;
    }

    /**
     * 获取 RapidBackup 快速备份制作价格
     *
     * @param skuDetail
     * @param openRapidBackup
     * @return
     */
    private static BigDecimal getRapidBackupPrice(MakeOrderSkuDetailVO skuDetail, boolean openRapidBackup) {
        // 支持开通RapidBackup 并且开通了RapidBackup
        // 强制开通RapidBackup
        if (openRapidBackup
                && skuDetail.getOpenRapidBackup() == SsdSkuConstants.OPEN_RAPIDBACKUP
                || skuDetail.getOpenRapidBackup() == SsdSkuConstants.OPEN_RAPIDBACKUP
                && skuDetail.getForceOpenRapidBackup()) {
            return skuDetail.getRapidBackupPrice();
        }
        return ZERO;
    }

    /**
     * @param amount 订单总金额
     * @Author: timo
     * @Date: 2019/1/24 09:30
     * @Description: 根据订单总金额计算定金金额
     */
    public static BigDecimal getEarnestAmount(BigDecimal amount) {
        return amount.multiply(EARNEST_AMOUNT_PERCENTAGE).setScale(2, BigDecimal.ROUND_HALF_UP);
    }

}
