package cn.superdesk.uniorder.service.order.base;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.superdesk.uniorder.common.enums.common.*;
import cn.superdesk.uniorder.common.lamda.AnLamdaUtils;
import cn.superdesk.uniorder.dao.entity.base.UnifiedOrder;
import cn.superdesk.uniorder.dao.entity.base.UnifiedOrderGoods;
import cn.superdesk.uniorder.dao.entity.base.UnifiedOrderReturn;
import cn.superdesk.uniorder.dao.entity.base.UnifiedOrderReturnCredit;
import cn.superdesk.uniorder.dto.param.setting.UnifiedServicePartGoodsTransportParam;
import cn.superdesk.uniorder.service.setting.UnifiedServiceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @Description: 运费处理节点
 * 所谓的 商户承担运费 问题
 * @Author: linjinyu
 * @CreateDate: 2020/12/15 下午4:22
 * @UpdateUser: linjinyu
 * @UpdateDate: 2020/12/15 下午4:22
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Service
public class CommonOrderTransportProcessService {

    @Autowired
    private UnifiedServiceService unifiedServiceService;

    /****************************************** 正单 positive start ******************************************/

    public void processTransport(UnifiedOrder unifiedOrderEntity, List<UnifiedOrderGoods> processUnifiedOrderGoodsList) {


//		UNKNOW(-1, "UNKNOW", "未知类型"),
//		SUPER(0, "SUPER", "服务之窗"),
//		QYNG(1, "QYNG", "企业采购"),
//		DKXD(2, "QYNG", "企业采购"),//TODO TMD 20200601 要求 "DKXD" 变成 "QYNG"  TODO TMD 20200601 要求 "代客下单" 变成 "企业采购"
//		FLSC(3, "FLSC", "企业福利"),
//		FLSC_QCH(31, "FLSC_QCH", "企业福利_侨城汇"),
//		LNSS(4, "LNSS", "楼内闪送"),

        switch (CommonServiceNoEnum.getByServiceNo(unifiedOrderEntity.getServiceNo())) {
            case 服务之窗:
                break;
            case 企业采购:
            case 代客下单:
                normalProcess(unifiedOrderEntity, processUnifiedOrderGoodsList);
                break;
            case 企业福利:
                customerAasume(unifiedOrderEntity, processUnifiedOrderGoodsList);
                merchantAssume(unifiedOrderEntity, processUnifiedOrderGoodsList);
                break;
            case 企业福利_侨城汇:
//				normalProcess(unifiedOrderEntity, processUnifiedOrderGoodsList);

                // 20210419 修改为
                customerAasume(unifiedOrderEntity, processUnifiedOrderGoodsList);
                merchantAssume(unifiedOrderEntity, processUnifiedOrderGoodsList);
                break;
            case 楼闪送:
                normalProcess(unifiedOrderEntity, processUnifiedOrderGoodsList);
                break;
            default:
                break;

        }

    }

    /**
     * 供应商/客户 承担运费
     *
     * @param unifiedOrderEntity
     * @param processUnifiedOrderGoodsList
     */
    private void normalProcess(UnifiedOrder unifiedOrderEntity, List<UnifiedOrderGoods> processUnifiedOrderGoodsList) {

        UnifiedServicePartGoodsTransportParam defaultGoodsTransport = unifiedServiceService.getUnifiedServicePartGoodsTransport(unifiedOrderEntity.getServiceNo());

        // 将运费转换为商品 同 (一般订单 add 20190925)
        if (null != unifiedOrderEntity.getTransportAmount() && unifiedOrderEntity.getTransportAmount().compareTo(BigDecimal.ZERO) > 0) {

            UnifiedOrderGoods unifiedOrderGoods = new UnifiedOrderGoods();

            unifiedOrderGoods.setOrderSn(unifiedOrderEntity.getOrderSn());

            unifiedOrderGoods.setGoodsLockingCustomer(CommonAccountingLockingEnum.正常.getKey());
            unifiedOrderGoods.setGoodsLockingSupplier(CommonAccountingLockingEnum.正常.getKey());

            unifiedOrderGoods.setAccountingStateCustomer(CommonAccountingStateEnum.未对账.getKey());
            unifiedOrderGoods.setAccountingStateSupplier(CommonAccountingStateEnum.未对账.getKey());

            unifiedOrderGoods.setGoodsType(CommonOrderGoodsTypeEnum.运费.getKey());
            unifiedOrderGoods.setDirection(CommonDirectionEnum.正向.getKey());

            unifiedOrderGoods.setGoodsId(CommonOrderGoodsIdEnum.运费.getKey());
            unifiedOrderGoods.setGoodsName(CommonOrderGoodsIdEnum.运费.getDesc());
            unifiedOrderGoods.setUnit(CommonOrderGoodsUnitEnum.项.getDesc());

            unifiedOrderGoods.setQuantity(1);
            unifiedOrderGoods.setPrice(unifiedOrderEntity.getTransportAmount());
            unifiedOrderGoods.setCostPrice(unifiedOrderEntity.getTransportAmount());

//			defaultGoodsTransport
            unifiedOrderGoods.setFiscalCode(defaultGoodsTransport.getGoodsTransportFiscalCode());
            unifiedOrderGoods.setTaxCode(defaultGoodsTransport.getGoodsTransportTaxCode());
            unifiedOrderGoods.setTaxRate(defaultGoodsTransport.getGoodsTransportTaxRate());

            // 商户税率
            unifiedOrderGoods.setMerchTaxId(0L);
            unifiedOrderGoods.setMerchTaxCode(defaultGoodsTransport.getGoodsTransportTaxCode());
            unifiedOrderGoods.setMerchTaxRate(defaultGoodsTransport.getGoodsTransportTaxRate());

            // 平台税率
            unifiedOrderGoods.setOperationTaxId(0L);
            unifiedOrderGoods.setOperationTaxCode(defaultGoodsTransport.getGoodsTransportTaxCode());
            unifiedOrderGoods.setOperationTaxRate(defaultGoodsTransport.getGoodsTransportTaxRate());

            unifiedOrderGoods.setCreateTime(DateUtil.date());
            unifiedOrderGoods.setCreateUserId(1L);
            unifiedOrderGoods.setUpdateTime(DateUtil.date());
            unifiedOrderGoods.setUpdateUserId(1L);

            processUnifiedOrderGoodsList.add(unifiedOrderGoods);

        } else {
            unifiedOrderEntity.setTransportAmount(BigDecimal.ZERO);
        }
    }


    /**
     * 客户承担
     * 这个逻辑 202103101516 三人 张雪 家豪
     *
     * @param unifiedOrderEntity
     * @param processUnifiedOrderGoodsList
     */
    private void customerAasume(UnifiedOrder unifiedOrderEntity, List<UnifiedOrderGoods> processUnifiedOrderGoodsList) {

        UnifiedServicePartGoodsTransportParam defaultGoodsTransport = unifiedServiceService.getUnifiedServicePartGoodsTransport(unifiedOrderEntity.getServiceNo());

        // 将运费转换为商品
        if (null != unifiedOrderEntity.getTransportAmount() && unifiedOrderEntity.getTransportAmount().compareTo(BigDecimal.ZERO) > 0) {

            UnifiedOrderGoods unifiedOrderGoods = new UnifiedOrderGoods();

            unifiedOrderGoods.setOrderSn(unifiedOrderEntity.getOrderSn());

            unifiedOrderGoods.setGoodsLockingCustomer(CommonAccountingLockingEnum.正常.getKey());
            unifiedOrderGoods.setGoodsLockingSupplier(CommonAccountingLockingEnum.正常.getKey());


            unifiedOrderGoods.setAccountingStateCustomer(CommonAccountingStateEnum.未对账.getKey());
            unifiedOrderGoods.setAccountingStateSupplier(CommonAccountingStateEnum.不对账.getKey());

            unifiedOrderGoods.setGoodsType(CommonOrderGoodsTypeEnum.运费.getKey());
            unifiedOrderGoods.setDirection(CommonDirectionEnum.正向.getKey());

            unifiedOrderGoods.setGoodsId(CommonOrderGoodsIdEnum.运费.getKey());
            unifiedOrderGoods.setGoodsName(CommonOrderGoodsIdEnum.运费.getDesc());
            unifiedOrderGoods.setUnit(CommonOrderGoodsUnitEnum.项.getDesc());

            unifiedOrderGoods.setQuantity(1);
            unifiedOrderGoods.setPrice(unifiedOrderEntity.getTransportAmount());
            unifiedOrderGoods.setCostPrice(unifiedOrderEntity.getTransportAmount());

            // defaultGoodsTransport
            unifiedOrderGoods.setFiscalCode(defaultGoodsTransport.getGoodsTransportFiscalCode());
            unifiedOrderGoods.setTaxCode(defaultGoodsTransport.getGoodsTransportTaxCode());
            unifiedOrderGoods.setTaxRate(defaultGoodsTransport.getGoodsTransportTaxRate());

            // 商户税率
            unifiedOrderGoods.setMerchTaxId(0L);
            unifiedOrderGoods.setMerchTaxCode(defaultGoodsTransport.getGoodsTransportTaxCode());
            unifiedOrderGoods.setMerchTaxRate(defaultGoodsTransport.getGoodsTransportTaxRate());

            // 平台税率
            unifiedOrderGoods.setOperationTaxId(0L);
            unifiedOrderGoods.setOperationTaxCode(defaultGoodsTransport.getGoodsTransportTaxCode());
            unifiedOrderGoods.setOperationTaxRate(defaultGoodsTransport.getGoodsTransportTaxRate());

            unifiedOrderGoods.setCreateTime(DateUtil.date());
            unifiedOrderGoods.setCreateUserId(1L);
            unifiedOrderGoods.setUpdateTime(DateUtil.date());
            unifiedOrderGoods.setUpdateUserId(1L);

            processUnifiedOrderGoodsList.add(unifiedOrderGoods);

        } else {
            unifiedOrderEntity.setTransportAmount(BigDecimal.ZERO);
        }

    }

    /**
     * 商户承担 / 这个是中间商 的亏损？
     *
     * @param unifiedOrderEntity
     * @param processUnifiedOrderGoodsList
     */
    private void merchantAssume(UnifiedOrder unifiedOrderEntity, List<UnifiedOrderGoods> processUnifiedOrderGoodsList) {

        UnifiedServicePartGoodsTransportParam defaultGoodsTransport = unifiedServiceService.getUnifiedServicePartGoodsTransport(unifiedOrderEntity.getServiceNo());

        // 将运费转换为商品
        if (null != unifiedOrderEntity.getTransportMerchantAssumeAmount() && unifiedOrderEntity.getTransportMerchantAssumeAmount().compareTo(BigDecimal.ZERO) > 0) {

            UnifiedOrderGoods unifiedOrderGoods = new UnifiedOrderGoods();

            unifiedOrderGoods.setOrderSn(unifiedOrderEntity.getOrderSn());

            unifiedOrderGoods.setGoodsLockingCustomer(CommonAccountingLockingEnum.正常.getKey());
            unifiedOrderGoods.setGoodsLockingSupplier(CommonAccountingLockingEnum.正常.getKey());

            unifiedOrderGoods.setAccountingStateCustomer(CommonAccountingStateEnum.不对账.getKey());
            unifiedOrderGoods.setAccountingStateSupplier(CommonAccountingStateEnum.未对账.getKey());

            unifiedOrderGoods.setGoodsType(CommonOrderGoodsTypeEnum.运费.getKey());
            unifiedOrderGoods.setDirection(CommonDirectionEnum.正向.getKey());

            unifiedOrderGoods.setGoodsId(CommonOrderGoodsIdEnum.商户承担运费.getKey());
            unifiedOrderGoods.setGoodsName(CommonOrderGoodsIdEnum.商户承担运费.getDesc());
            unifiedOrderGoods.setUnit(CommonOrderGoodsUnitEnum.项.getDesc());

            unifiedOrderGoods.setQuantity(1);
            unifiedOrderGoods.setPrice(unifiedOrderEntity.getTransportMerchantAssumeAmount());
            unifiedOrderGoods.setCostPrice(unifiedOrderEntity.getTransportMerchantAssumeAmount());

//			defaultGoodsTransport
            unifiedOrderGoods.setFiscalCode(defaultGoodsTransport.getGoodsTransportFiscalCode());
            unifiedOrderGoods.setTaxCode(defaultGoodsTransport.getGoodsTransportTaxCode());
            unifiedOrderGoods.setTaxRate(defaultGoodsTransport.getGoodsTransportTaxRate());

            // 商户税率
            unifiedOrderGoods.setMerchTaxId(0L);
            unifiedOrderGoods.setMerchTaxCode(defaultGoodsTransport.getGoodsTransportTaxCode());
            unifiedOrderGoods.setMerchTaxRate(defaultGoodsTransport.getGoodsTransportTaxRate());

            // 平台税率
            unifiedOrderGoods.setOperationTaxId(0L);
            unifiedOrderGoods.setOperationTaxCode(defaultGoodsTransport.getGoodsTransportTaxCode());
            unifiedOrderGoods.setOperationTaxRate(defaultGoodsTransport.getGoodsTransportTaxRate());

            unifiedOrderGoods.setCreateTime(DateUtil.date());
            unifiedOrderGoods.setCreateUserId(1L);
            unifiedOrderGoods.setUpdateTime(DateUtil.date());
            unifiedOrderGoods.setUpdateUserId(1L);

            processUnifiedOrderGoodsList.add(unifiedOrderGoods);

        } else {
            unifiedOrderEntity.setTransportMerchantAssumeAmount(BigDecimal.ZERO);
        }
    }

    /****************************************** 正单 positive  end ******************************************/

    /****************************************** 负单 negative start ******************************************/

    /**
     * 退单 退运费 没有分客户/商户 承担
     *
     * @param unifiedOrderReturn
     * @param finalRefundOrderCreditList
     * @return
     */
    public UnifiedOrderGoods processRefundTransport(UnifiedOrderReturn unifiedOrderReturn, List<UnifiedOrderReturnCredit> finalRefundOrderCreditList) {

        UnifiedServicePartGoodsTransportParam defaultGoodsTransport = unifiedServiceService.getUnifiedServicePartGoodsTransport("FLSC_QCH");

        /****************************************** TODO 20210120 处理退单退运费验证 start ******************************************/
        UnifiedOrderGoods refundOrderGoods = null;

        if (null != unifiedOrderReturn.getTransportAmount()
                && unifiedOrderReturn.getTransportAmount().compareTo(BigDecimal.ZERO) > 0) {

//				List<UnifiedOrderReturnCredit> finalRefundOrderCreditListFilterTransportAmount = finalRefundOrderCreditList.stream().filter(o -> o.getGoodsId().compareTo(0L) == 0).collect(Collectors.toList());


            List<Predicate<UnifiedOrderReturnCredit>> predicatesByTransportCredit = new ArrayList<>();
            // 退单 上的字段 - dispatchprice > 0
            // 流水 上的字段
            // |---- goodsid : 2479969 如果订单有退运费 此id 0 = 0
            // |---- daily_account_type : 3 如果订单有退运费 也是 = 3(双向 企业 供应商)= 4 (单向 企业)= 5 (单向 供应商)
            // mark by linijnyu at 20210120 来源 林志鹏
            // 这个比较的 GoodsId 从 0 改成 -1 mark by linjinyu at 20210309
            predicatesByTransportCredit.add(
                    r -> r.getGoodsId() != null
                            && r.getGoodsId().compareTo(CommonOrderGoodsIdEnum.退单退运费.getKey()) == 0
//							&& r.getDailyAccountType().equals(3)
                            && (r.getDailyAccountType().equals(3) || r.getDailyAccountType().equals(4))
            );
            List<UnifiedOrderReturnCredit> finalRefundOrderCreditListFilterTransportAmount = AnLamdaUtils.filters(finalRefundOrderCreditList, predicatesByTransportCredit);

            if (CollUtil.isNotEmpty(finalRefundOrderCreditListFilterTransportAmount)) {

                // 在流水上记录的运费
                BigDecimal transporByCredit = finalRefundOrderCreditListFilterTransportAmount.stream()
                        .map(item -> item.getBalance() == null ? BigDecimal.ZERO : item.getBalance())
                        .reduce(BigDecimal.ZERO, BigDecimal::add);

                List<Integer> dailyAccountTypeByCredit = finalRefundOrderCreditListFilterTransportAmount.stream()
                        .filter(AnLamdaUtils.distinctByKey(o -> o.getDailyAccountType()))
                        .map(o -> o.getDailyAccountType())
                        .collect(Collectors.toList());

                Integer dailyAccountType = 0;

                // 如果为空,就是不存在退运费一说
                if (CollUtil.isNotEmpty(dailyAccountTypeByCredit)) {

                    // 只允许 存在一种情况 要不 = 3
                    if (dailyAccountTypeByCredit.size() > 1) {
                        // TODO 记录 Error
//					callback.setProcessResult(CommonProcessResultEnum.异常.getKey());
//					callback.setProcessReport("退单信息存退运费,但没有退运费流水");
//					return callback;
                        // TODO 抛出异常
                    } else {
                        dailyAccountType = dailyAccountTypeByCredit.get(0);
                    }
                }

                if (unifiedOrderReturn.getTransportAmount().compareTo(transporByCredit) != 0) {
                    // TODO 记录 Error
//					callback.setProcessResult(CommonProcessResultEnum.异常.getKey());
//					callback.setProcessReport("退单信息存退运费,但没有退运费流水");
//					return callback;
                    // TODO 抛出异常

                } else if (dailyAccountType.equals(0)) {
                    // TODO 记录 Error
//					callback.setProcessResult(CommonProcessResultEnum.异常.getKey());
//					callback.setProcessReport("退单信息存退运费,但没有退运费流水");
//					return callback;
                    // TODO 抛出异常
                } else {


                    refundOrderGoods = new UnifiedOrderGoods();

//					refundOrderGoods.setOrderSn(unifiedOrderReturn.getOrderSn());
                    refundOrderGoods.setOrderSn(unifiedOrderReturn.getReturnSn());

                    refundOrderGoods.setGoodsType(CommonOrderGoodsTypeEnum.运费.getKey());
                    refundOrderGoods.setDirection(CommonDirectionEnum.负向.getKey());

                    refundOrderGoods.setGoodsLockingCustomer(CommonAccountingLockingEnum.正常.getKey());
                    refundOrderGoods.setGoodsLockingSupplier(CommonAccountingLockingEnum.正常.getKey());

                    // 双向 企业 供应商 魔法数字代表什么,请找林智鹏 mark by linjinyu at 20211116
                    if (dailyAccountType.equals(3)) {
                        refundOrderGoods.setAccountingStateCustomer(CommonAccountingStateEnum.未对账.getKey());
                        refundOrderGoods.setAccountingStateSupplier(CommonAccountingStateEnum.未对账.getKey());
                    }
                    // 单向 企业
                    else if (dailyAccountType.equals(4)) {
                        refundOrderGoods.setAccountingStateCustomer(CommonAccountingStateEnum.未对账.getKey());
                        refundOrderGoods.setAccountingStateSupplier(CommonAccountingStateEnum.不对账.getKey());
                    }

                    // add by linjinyu 20200723 已经确认过 运费goods_id 必定为 0 如果 goods_id 中 0 为能唯一代表运费,哪么,SQL就会有问题,但这个问题不明显
                    refundOrderGoods.setGoodsId(CommonOrderGoodsIdEnum.退单退运费.getKey());
                    refundOrderGoods.setGoodsName(CommonOrderGoodsIdEnum.退单退运费.getDesc());
                    refundOrderGoods.setQuantity(-1);
                    refundOrderGoods.setUnit(CommonOrderGoodsUnitEnum.项.getDesc());
                    refundOrderGoods.setPrice(unifiedOrderReturn.getTransportAmount());
                    refundOrderGoods.setCostPrice(unifiedOrderReturn.getTransportAmount());

                    // defaultGoodsTransport
                    refundOrderGoods.setFiscalCode(defaultGoodsTransport.getGoodsTransportFiscalCode());
                    refundOrderGoods.setTaxCode(defaultGoodsTransport.getGoodsTransportTaxCode());
                    refundOrderGoods.setTaxRate(defaultGoodsTransport.getGoodsTransportTaxRate());

                    // 商户税率
                    refundOrderGoods.setMerchTaxId(0L);
                    refundOrderGoods.setMerchTaxCode(defaultGoodsTransport.getGoodsTransportTaxCode());
                    refundOrderGoods.setMerchTaxRate(defaultGoodsTransport.getGoodsTransportTaxRate());

                    // 平台税率
                    refundOrderGoods.setOperationTaxId(0L);
                    refundOrderGoods.setOperationTaxCode(defaultGoodsTransport.getGoodsTransportTaxCode());
                    refundOrderGoods.setOperationTaxRate(defaultGoodsTransport.getGoodsTransportTaxRate());

                    refundOrderGoods.setCreateTime(DateUtil.date());
                    refundOrderGoods.setCreateUserId(1L);
                    refundOrderGoods.setUpdateTime(DateUtil.date());
                    refundOrderGoods.setUpdateUserId(1L);
                }
            }
        }
        /****************************************** TODO 20210120 处理退单退运费验证   end ******************************************/

        return refundOrderGoods;

    }

    /****************************************** 负单 negative  end ******************************************/
}
