package com.hzs.sale.pub.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.hzs.common.core.constant.EnumsPrefixConstants;
import com.hzs.common.core.enums.EApprovalBusiness;
import com.hzs.common.core.enums.EApproveStatus;
import com.hzs.common.core.enums.EDealerYesNo;
import com.hzs.common.core.exception.ServiceException;
import com.hzs.common.core.utils.StringUtils;
import com.hzs.common.domain.sale.ext.SaOrderChargeLogExt;
import com.hzs.common.domain.sale.ext.SaOrderItemsExt;
import com.hzs.common.domain.sale.product.BdProduct;
import com.hzs.common.domain.system.config.BdAccount;
import com.hzs.common.service.ITransactionCommonService;
import com.hzs.sale.deliver.dto.OrderSelfDTO;
import com.hzs.sale.deliver.service.ISaDeliverBusinessService;
import com.hzs.sale.order.dto.OrderChangeAddressDTO;
import com.hzs.sale.order.dto.OrderChangeProductDTO;
import com.hzs.sale.order.dto.OrderChangeProductDetailDTO;
import com.hzs.sale.order.dto.OrderReturnDTO;
import com.hzs.sale.order.param.OrderCancelParam;
import com.hzs.sale.order.service.IOrderBusinessService;
import com.hzs.sale.order.service.ISaOrderChargeLogService;
import com.hzs.sale.order.service.ISaOrderItemsService;
import com.hzs.sale.product.service.IBdProductService;
import com.hzs.sale.pub.dto.*;
import com.hzs.sale.pub.service.ISaleApprovalBusiness;
import com.hzs.sale.util.OrderUtil;
import com.hzs.system.base.IAreaServiceApi;
import com.hzs.system.config.IAccountServiceApi;
import com.hzs.system.sys.dto.ApprovalBusinessResultDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 订单模块统一的审批结束回调入口
 */
@Service
@Slf4j
public class SaleApprovalBusiness implements ISaleApprovalBusiness {

    @Autowired
    private ISaOrderItemsService iSaOrderItemsService;
    @Autowired
    private ISaOrderChargeLogService iSaOrderChargeLogService;
    @Autowired
    private IOrderBusinessService iOrderBusinessService;
    @Autowired
    private ISaDeliverBusinessService iSaDeliverBusinessService;
    @Autowired
    private IBdProductService iBdProductService;
    @Autowired
    private ITransactionCommonService iTransactionCommonService;

    @DubboReference
    private IAreaServiceApi iAreaServiceApi;
    @DubboReference
    private IAccountServiceApi iAccountServiceApi;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void approvalCallback(ApprovalBusinessResultDTO approvalBusinessResultDTO) {
        // 返回内容
        String str = null;
        if (EApproveStatus.FINISH.getValue() == approvalBusinessResultDTO.getEApproveStatus().getValue()) {
            // 已完成处理
            switch (approvalBusinessResultDTO.getEApprovalBusiness()) {
                case ORDER_CANCEL:
                    // 撤销订单
                    str = iOrderBusinessService.cancelOrderApprovalAgree(approvalBusinessResultDTO, EApprovalBusiness.ORDER_CANCEL.getValue());
                    break;
                case ORDER_CANCEL_PRODUCT:
                    // 撤销产品订单
                    str = iOrderBusinessService.cancelOrderApprovalAgree(approvalBusinessResultDTO, EApprovalBusiness.ORDER_CANCEL_PRODUCT.getValue());
                    break;
                case ORDER_CHANGE_ADDRESS:
                    // 订单修改地址
                    str = iOrderBusinessService.changeAddressApprovalAgree(approvalBusinessResultDTO);
                    break;
                case ORDER_CHANGE_PRODUCT:
                    // 订单调换货物
                    str = iOrderBusinessService.changeProductApprovalAgree(approvalBusinessResultDTO);
                    break;
                case ORDER_RETURN:
                    // 订单退单
                    str = iOrderBusinessService.returnOrderApprovalAgree(approvalBusinessResultDTO);
                    break;
                case SELF_DELIVERY_MANAGE:
                    // 订单自提
                    str = iSaDeliverBusinessService.selfDeliverApprovalAgree(approvalBusinessResultDTO);
                    break;
                case SECOND_DELIVER:
                    // 二次发货
                    str = iSaDeliverBusinessService.secondDeliverApprovalAgree(approvalBusinessResultDTO);
                    break;
            }
        } else {
            // 已驳回处理
            switch (approvalBusinessResultDTO.getEApprovalBusiness()) {
                case ORDER_CANCEL:
                    // 撤销订单
                    str = iOrderBusinessService.cancelOrderApprovalReject(approvalBusinessResultDTO, EApprovalBusiness.ORDER_CANCEL.getValue());
                    break;
                case ORDER_CANCEL_PRODUCT:
                    // 撤销产品订单
                    str = iOrderBusinessService.cancelOrderApprovalReject(approvalBusinessResultDTO, EApprovalBusiness.ORDER_CANCEL_PRODUCT.getValue());
                    break;
                case ORDER_CHANGE_ADDRESS:
                    // 订单修改地址
                    str = iOrderBusinessService.changeAddressApprovalReject(approvalBusinessResultDTO);
                    break;
                case ORDER_CHANGE_PRODUCT:
                    // 订单调换货物
                    str = iOrderBusinessService.changeProductApprovalReject(approvalBusinessResultDTO);
                    break;
                case ORDER_RETURN:
                    // 订单退单
                    str = iOrderBusinessService.returnOrderApprovalReject(approvalBusinessResultDTO);
                    break;
                case SELF_DELIVERY_MANAGE:
                    // 订单自提
                    str = iSaDeliverBusinessService.selfDeliverApprovalReject(approvalBusinessResultDTO);
                    break;
                case SECOND_DELIVER:
                    // 二次发货
                    str = iSaDeliverBusinessService.secondDeliverApprovalReject(approvalBusinessResultDTO);
                    break;
            }
        }
        if (StringUtils.isNotEmpty(str)) {
            // 返回有信息，说明有问题，抛出异常
            throw new ServiceException(str);
        }
    }

    @Override
    public Object approvalData(EApprovalBusiness eApprovalBusiness, String businessCode, String toLanguageTag) {
        // 订单修改日志
        List<SaOrderChargeLogExt> saOrderChargeLogList = iSaOrderChargeLogService.queryDataByTypeAndCode(eApprovalBusiness.getValue(), businessCode, null);

        switch (eApprovalBusiness) {
            case ORDER_CHANGE_ADDRESS:
                // 订单修改地址
                List<ChangeAddressDTO> changeAddressList = new ArrayList<>(saOrderChargeLogList.size());

                for (SaOrderChargeLogExt saOrderChargeLog : saOrderChargeLogList) {
                    OrderChangeAddressDTO oldChangeAddress = JSONUtil.toBean(saOrderChargeLog.getBeforeData(), OrderChangeAddressDTO.class);
                    OrderChangeAddressDTO newChangeAddress = JSONUtil.toBean(saOrderChargeLog.getAfterData(), OrderChangeAddressDTO.class);

                    // 地址列表
                    Map<Integer, String> areaMap = iAreaServiceApi.getAreaMap(saOrderChargeLog.getPkCountry()).getData();

                    // 处理旧地址
                    StringBuilder oldAddress = new StringBuilder();
                    String oldProvince = areaMap.get(oldChangeAddress.getRecProvince());
                    if (StringUtils.isNotEmpty(oldProvince)) {
                        oldAddress.append(oldProvince);
                    }
                    String oldCity = areaMap.get(oldChangeAddress.getRecCity());
                    if (StringUtils.isNotEmpty(oldCity)) {
                        oldAddress.append(oldCity);
                    }
                    String oldCounty = areaMap.get(oldChangeAddress.getRecCounty());
                    if (StringUtils.isNotEmpty(oldCounty)) {
                        oldAddress.append(oldCounty);
                    }
                    oldAddress.append(oldChangeAddress.getRecAddress());

                    // 处理新地址
                    StringBuilder newAddress = new StringBuilder();
                    String newProvince = areaMap.get(newChangeAddress.getRecProvince());
                    if (StringUtils.isNotEmpty(newProvince)) {
                        newAddress.append(newProvince);
                    }
                    String newCity = areaMap.get(newChangeAddress.getRecCity());
                    if (StringUtils.isNotEmpty(newCity)) {
                        newAddress.append(newCity);
                    }
                    String newCounty = areaMap.get(newChangeAddress.getRecCounty());
                    if (StringUtils.isNotEmpty(newCounty)) {
                        newAddress.append(newCounty);
                    }
                    newAddress.append(newChangeAddress.getRecAddress());

                    changeAddressList.add(ChangeAddressDTO.builder()
                            .orderCode(saOrderChargeLog.getOrderCode())
                            .memberCode(saOrderChargeLog.getMemberCode())
                            .memberName(saOrderChargeLog.getMemberName())
                            .oldItem(ChangeAddressDetailDTO.builder()
                                    .recName(oldChangeAddress.getRecName())
                                    .recPhone(oldChangeAddress.getRecPhone())
                                    .recAddress(oldAddress.toString())
                                    .build())
                            .newItem(ChangeAddressDetailDTO.builder()
                                    .recName(newChangeAddress.getRecName())
                                    .recPhone(newChangeAddress.getRecPhone())
                                    .recAddress(newAddress.toString())
                                    .build())
                            .build());
                }
                return changeAddressList;
            case ORDER_CHANGE_PRODUCT:
                // 订单调换货物
                SaOrderChargeLogExt changeProductChargeLog = saOrderChargeLogList.get(0);

                OrderChangeProductDTO oldChangeProduct = JSONUtil.toBean(changeProductChargeLog.getBeforeData(), OrderChangeProductDTO.class);
                OrderChangeProductDTO newChangeProduct = JSONUtil.toBean(changeProductChargeLog.getAfterData(), OrderChangeProductDTO.class);

                // 查询翻译数据
                Map<String, String> changeProductMap = iTransactionCommonService.exportEnumTransactionToTag(toLanguageTag, EDealerYesNo.values());

                List<ChangeProductDetailDTO> oldItemList = new ArrayList<>(oldChangeProduct.getDetailList().size());
                // 旧明细数据处理
                for (OrderChangeProductDetailDTO orderChangeProductDetailDTO : oldChangeProduct.getDetailList()) {
                    ChangeProductDetailDTO tmpOldItems = BeanUtil.copyProperties(orderChangeProductDetailDTO, ChangeProductDetailDTO.class);
                    tmpOldItems.setIsGiftVal(changeProductMap.get(EnumsPrefixConstants.DEALER_YES_NO + tmpOldItems.getIsGift()));
                    oldItemList.add(tmpOldItems);
                }

                List<ChangeProductDetailDTO> newItemList = new ArrayList<>(newChangeProduct.getDetailList().size());
                // 新明细数据处理
                for (OrderChangeProductDetailDTO orderChangeProductDetailDTO : newChangeProduct.getDetailList()) {
                    ChangeProductDetailDTO tmpNewItems = BeanUtil.copyProperties(orderChangeProductDetailDTO, ChangeProductDetailDTO.class);
                    tmpNewItems.setIsGiftVal(changeProductMap.get(EnumsPrefixConstants.DEALER_YES_NO + tmpNewItems.getIsGift()));
                    newItemList.add(tmpNewItems);
                }

                List<ChangeProductDTO> changeProductList = new ArrayList<>();
                changeProductList.add(ChangeProductDTO.builder()
                        .orderCode(changeProductChargeLog.getOrderCode())
                        .memberCode(changeProductChargeLog.getMemberCode())
                        .memberName(changeProductChargeLog.getMemberName())
                        .oldPostage(oldChangeProduct.getPostage())
                        .newPostage(newChangeProduct.getPostage())
                        .oldItemList(oldItemList)
                        .newItemList(newItemList)
                        .build());
                return changeProductList;
            case ORDER_RETURN:
                // 订单退单
                List<ReturnDTO> returnList = new ArrayList<>(saOrderChargeLogList.size());
                for (SaOrderChargeLogExt returnChargeLog : saOrderChargeLogList) {
                    OrderReturnDTO newReturn = JSONUtil.toBean(returnChargeLog.getAfterData(), OrderReturnDTO.class);
                    returnList.add(ReturnDTO.builder()
                            .orderCode(returnChargeLog.getOrderCode())
                            .memberCode(returnChargeLog.getMemberCode())
                            .memberName(returnChargeLog.getMemberName())
                            .returnAmount(newReturn.getReturnAmount())
                            .returnRemark(newReturn.getReturnRemark())
                            .build());
                }
                return returnList;
            case ORDER_CANCEL: // 撤销订单、单点撤单、合并撤单
            case ORDER_CANCEL_PRODUCT: // 撤销产品
                List<CancelOrderDTO> cancelOrderDTOList = new ArrayList<>(saOrderChargeLogList.size());
                for (SaOrderChargeLogExt saOrderChargeLogExt : saOrderChargeLogList) {
                    OrderCancelParam orderCancelParam = JSONUtil.toBean(saOrderChargeLogExt.getAfterData(), OrderCancelParam.class);
                    CancelOrderDTO cancelOrderDTO = CancelOrderDTO.builder()
                            .orderCode(orderCancelParam.getOrderCode())
                            .memberCode(orderCancelParam.getMemberCode())
                            .memberName(orderCancelParam.getMemberName())
                            .cancelOrderCode(saOrderChargeLogExt.getBusinessCode())
                            .build();
                    if (orderCancelParam.getOrderCancelDetailParamList() != null && orderCancelParam.getOrderCancelDetailParamList().size() > 0) {
                        List<ChangeProductDetailDTO> changeProductDetailDTOList = new ArrayList<>();
                        orderCancelParam.getOrderCancelDetailParamList().forEach(orderCancelDetailParam -> {
                            changeProductDetailDTOList.add(ChangeProductDetailDTO.builder()
                                    .productName(orderCancelDetailParam.getProductName())
                                    .build());
                        });
                        cancelOrderDTO.setCancelItemsList(changeProductDetailDTOList);
                    }
                    cancelOrderDTOList.add(cancelOrderDTO);

                }
                return cancelOrderDTOList;
            case SELF_DELIVERY_MANAGE:
                // 订单自提
                // 订单明细ID
                List<Long> itemIdList = new ArrayList<>();

                for (SaOrderChargeLogExt saOrderChargeLogExt : saOrderChargeLogList) {
                    OrderSelfDTO orderSelfDTO = JSONUtil.toBean(saOrderChargeLogExt.getAfterData(), OrderSelfDTO.class);

                    itemIdList.addAll(orderSelfDTO.getItemIdList());
                }
                // 查询所有订单明细
                List<SaOrderItemsExt> saOrderItemsExtList = iSaOrderItemsService.queryListByItemId(itemIdList, null, null);
                return BeanUtil.copyToList(saOrderItemsExtList, SelfDTO.class);
            case SECOND_DELIVER:
                // 二次发货
                SaOrderChargeLogExt saOrderChargeLogExt = saOrderChargeLogList.get(0);

                // 修改后数据
                SecondDTO secondDTO = JSONUtil.toBean(saOrderChargeLogExt.getAfterData(), SecondDTO.class);
                secondDTO.setMemberCode(saOrderChargeLogExt.getMemberCode());
                secondDTO.setMemberName(saOrderChargeLogExt.getMemberName());

                // 地址列表
                Map<Integer, String> areaMap = iAreaServiceApi.getAreaMap(saOrderChargeLogExt.getPkCountry()).getData();
                // 省、市、县显示处理
                OrderUtil.handleOrderAddress(areaMap, secondDTO);

                // 产品处理
                List<SecondProductDTO> productList = secondDTO.getProductList();
                // 获取产品map
                Map<Integer, BdProduct> productMap = iBdProductService.queryProductMap(productList.stream().map(SecondProductDTO::getPkProduct).collect(Collectors.toList()), saOrderChargeLogExt.getPkCountry());
                for (SecondProductDTO productDTO : productList) {
                    BdProduct bdProduct = productMap.get(productDTO.getPkProduct());
                    if (null != bdProduct) {
                        productDTO.setProductCode(bdProduct.getProductCode());
                        productDTO.setProductName(bdProduct.getProductName());
                    }
                }

                // 账户翻译map
                Map<Integer, String> transactionMap = iTransactionCommonService.exportEnumTransactionByDB(EnumsPrefixConstants.KEY_ACC);
                // 扣款账户处理
                List<SecondAccountDTO> accountList = secondDTO.getAccountList();
                // 获取账户map
                Map<Integer, BdAccount> accountMap = iAccountServiceApi.getAccountMap(accountList.stream().map(SecondAccountDTO::getPkAccount).collect(Collectors.toList())).getData();
                for (SecondAccountDTO secondAccountDTO : accountList) {
                    BdAccount bdAccount = accountMap.get(secondAccountDTO.getPkAccount());
                    if (null != bdAccount) {
                        secondAccountDTO.setPkAccountVal(transactionMap.get(bdAccount.getPkTransactionKey()));
                    }
                }
                return secondDTO;
        }
        return null;
    }

}
