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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.hzs.common.core.constant.msg.CommonMsgConstants;
import com.hzs.common.core.constant.msg.DocumentMsgConstants;
import com.hzs.common.core.domain.R;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.exception.ServiceException;
import com.hzs.common.core.utils.CommonUtil;
import com.hzs.common.domain.sale.deliver.SaDeliver;
import com.hzs.common.domain.sale.deliver.SaDeliverBarCode;
import com.hzs.common.domain.sale.deliver.SaDeliverItems;
import com.hzs.common.domain.sale.ext.SaOrderExt;
import com.hzs.common.domain.sale.ext.SaOrderItemsExt;
import com.hzs.common.domain.sale.order.*;
import com.hzs.common.util.TransactionUtils;
import com.hzs.member.account.IMemberAccountServiceApi;
import com.hzs.sale.deliver.dto.OrderSelfBarCodeDTO;
import com.hzs.sale.deliver.dto.OrderSelfDTO;
import com.hzs.sale.deliver.param.SelfDeliverBarCodeParam;
import com.hzs.sale.deliver.param.SelfDeliverParam;
import com.hzs.sale.deliver.service.ISaDeliverBarCodeService;
import com.hzs.sale.deliver.service.ISaDeliverBusinessService;
import com.hzs.sale.deliver.service.ISaDeliverItemsService;
import com.hzs.sale.deliver.service.ISaDeliverService;
import com.hzs.sale.order.dto.OrderUseBarCodeDTO;
import com.hzs.sale.order.param.SelfPickUpParam;
import com.hzs.sale.order.service.*;
import com.hzs.system.base.IBarCodeServiceApi;
import com.hzs.system.base.dto.BarCodeUseDTO;
import com.hzs.system.sys.IApprovalServiceApi;
import com.hzs.system.sys.dto.ApprovalBusinessResultDTO;
import com.hzs.system.sys.dto.ApprovalSubmitDTO;
import com.hzs.system.sys.dto.LoginUser;
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.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 发货单业务服务
 */
@Slf4j
@Service
public class SaDeliverBusinessServiceImpl implements ISaDeliverBusinessService {

    @Autowired
    private ISaOrderService iSaOrderService;
    @Autowired
    private ISaOrderItemsService iSaOrderItemsService;
    @Autowired
    private ISaOrderChargeLogService iSaOrderChargeLogService;
    @Autowired
    private IOrderBusinessService iOrderBusinessService;
    @Autowired
    private ISaDeliverService iSaDeliverService;
    @Autowired
    private ISaDeliverItemsService iSaDeliverItemsService;
    @Autowired
    private ISaDeliverBarCodeService iSaDeliverBarCodeService;
    @Autowired
    private ISaOrderSelfLogService saOrderSelfLogService;

    @DubboReference
    IApprovalServiceApi iApprovalServiceApi;
    @DubboReference
    IBarCodeServiceApi iBarCodeServiceApi;
    @DubboReference
    IMemberAccountServiceApi iMemberAccountServiceApi;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public String selfDeliverSubmit(SelfDeliverParam param, List<SaOrderItemsExt> orderItemsList,
                                    List<SelfDeliverBarCodeParam> barCodeParamList, LoginUser loginUser) {
        // 当前时间
        Date nowDate = new Date();
        // 用户ID
        Long userId = loginUser.getUserId();
        // 所属国家
        Integer pkCountry = loginUser.getDataCountry();

        // 订单修改记录列表
        List<SaOrderChargeLog> saOrderChargeLogList = new ArrayList<>();
        // 涉及会员ID列表
        Set<Long> pkMemberList = new HashSet<>();

        // 本批订单修改记录编号
        String businessCode = CommonUtil.createSerialNumber(EOrderPrefix.ORDER_CODE);

        // 订单ID列表
        List<Long> orderIdList = orderItemsList.stream().map(SaOrderItemsExt::getPkOrder).distinct().collect(Collectors.toList());
        // 订单 + 明细列表
        List<SaOrderExt> saOrderExtList = iSaOrderService.queryOrderListByIdList(orderIdList, pkCountry);

        for (SaOrderExt saOrderExt : saOrderExtList) {
            // 记录涉及会员ID
            pkMemberList.add(saOrderExt.getPkCreator());

            // 订单明细ID列表
            List<Long> itemIdList = saOrderExt.getOrderItemsExtList().stream().map(SaOrderItemsExt::getPkId).collect(Collectors.toList());
            // 追溯码列表
            List<OrderSelfBarCodeDTO> barCodeList = new ArrayList<>();
            if (CollectionUtil.isNotEmpty(barCodeParamList)) {
                for (SelfDeliverBarCodeParam barCodeParam : barCodeParamList) {
                    if (itemIdList.contains(barCodeParam.getItemId())) {
                        barCodeList.add(BeanUtil.copyProperties(barCodeParam, OrderSelfBarCodeDTO.class));
                    }
                }
            }

            // 保存订单修改记录
            SaOrderChargeLog saOrderChargeLog = new SaOrderChargeLog();
            saOrderChargeLog.setPkOrder(saOrderExt.getPkId());
            saOrderChargeLog.setChargeType(EApprovalBusiness.SELF_DELIVERY_MANAGE.getValue());
            saOrderChargeLog.setBeforeData("");
            saOrderChargeLog.setAfterData(JSONUtil.toJsonStr(OrderSelfDTO.builder()
                    .postage(param.getPostage())
                    .pkStorehouse(param.getPkStorehouse())
                    .itemIdList(itemIdList)
                    .barCodeList(barCodeList)
                    .build()));
            saOrderChargeLog.setCreationTime(nowDate);
            saOrderChargeLog.setPkCreator(userId);
            saOrderChargeLog.setModifiedTime(saOrderChargeLog.getCreationTime());
            saOrderChargeLog.setPkModified(saOrderChargeLog.getPkCreator());
            saOrderChargeLog.setPkCountry(pkCountry);
            saOrderChargeLog.setApprovalStatus(EAgentApprovalStatus.UNAPPROVED.getValue());
            saOrderChargeLog.setBusinessCode(businessCode);
            saOrderChargeLogList.add(saOrderChargeLog);
        }

        // 条码列表
        List<BarCodeUseDTO> barCodeUseList = new ArrayList<>();
        for (SelfDeliverBarCodeParam bindCodeParam : barCodeParamList) {
            barCodeUseList.add(BarCodeUseDTO.builder()
                    .barCodeItemsId(bindCodeParam.getBarCodeId())
                    .build());
        }

        if (iSaOrderChargeLogService.saveBatch(saOrderChargeLogList)) {
            // 订单修改记录添加成功，提交签呈

            // 提交签呈处理
            R<String> resultR = iApprovalServiceApi.submitOrder(
                    ApprovalSubmitDTO.builder()
                            .eApprovalBusiness(EApprovalBusiness.SELF_DELIVERY_MANAGE)
                            .businessCode(businessCode)
                            .signType(ESignType.getEnumByValue(param.getSignType()))
                            .userIdList(param.getUserIdList())
                            .sendIdList(param.getSendIdList())
                            .remark(param.getRemark())
                            .fileList(param.getFileList())
                            .pkMemberList(pkMemberList)
                            .build(),
                    loginUser,
                    OrderUseBarCodeDTO.builder()
                            .barCodeUseList(barCodeUseList)
                            .pkCountry(pkCountry)
                            .userId(userId)
                            .build()
            );
            if (resultR.isSuccess()) {
                // 成功后判断id是否存在，存在的话说明是前台的自提清单，需要回写日志表
                if (param.getPkId() != null) {
                    SelfPickUpParam selfPickUpParam = SelfPickUpParam.builder().build();
                    selfPickUpParam.setPkCreator(userId);
                    selfPickUpParam.setApproveStatus(EApproveRechargeStatus.WAIT.getValue());
                    saOrderSelfLogService.updateSaOrderSelfLog(selfPickUpParam, param.getPkId());
                }
                return null;
            }
            throw new ServiceException(TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED) + "：" + resultR.getMsg());
        }
        return TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public String selfDeliverApprovalAgree(ApprovalBusinessResultDTO approvalBusinessResultDTO) {
        // 用户ID
        Long userId = approvalBusinessResultDTO.getLoginUser().getUserId();
        // 所属国家
        Integer pkCountry = approvalBusinessResultDTO.getLoginUser().getDataCountry();
        // 当前时间
        Date nowDate = new Date();

        // 查询订单修改记录
        List<SaOrderChargeLog> saOrderChargeLogList = iOrderBusinessService.getSaOrderChargeLogs(approvalBusinessResultDTO, EApprovalBusiness.SELF_DELIVERY_MANAGE);
        if (CollectionUtil.isEmpty(saOrderChargeLogList)) {
            log.error("订单自提同意处理失败: 签呈不存在!");
            return TransactionUtils.getContent(DocumentMsgConstants.SIGN_NOT_EXIST);
        }
        if (EAgentApprovalStatus.UNAPPROVED.getValue() != saOrderChargeLogList.get(0).getApprovalStatus()) {
            log.error("订单自提同意处理失败: 签呈已处理");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_HAS_HANDLE);
        }

        // 订单ID列表
        List<Long> orderIdList = new ArrayList<>();
        // 追溯码列表
        List<OrderSelfBarCodeDTO> barCodeList = new ArrayList<>();
        // 返还邮费
        BigDecimal postage = null;
        Integer pkStorehouse = null;

        for (SaOrderChargeLog saOrderChargeLog : saOrderChargeLogList) {
            OrderSelfDTO orderSelfDTO = JSONUtil.toBean(saOrderChargeLog.getAfterData(), OrderSelfDTO.class);
            // 订单ID列表
            orderIdList.add(saOrderChargeLog.getPkOrder());
            // 追溯码列表
            barCodeList.addAll(orderSelfDTO.getBarCodeList());

            // 邮费按整次退，每个订单的数据里面都是相同的，此处可以随便取一条使用
            postage = orderSelfDTO.getPostage();
            pkStorehouse = orderSelfDTO.getPkStorehouse();
        }

        // 订单列表
        List<SaOrderExt> orderList = iSaOrderService.queryOrderListByIdList(orderIdList, pkCountry);

        // 自提时，发货单地址等信息取第一条信息
        SaOrderExt saOrder = orderList.get(0);
        // 发货单
        SaDeliver saDeliver = new SaDeliver();
        saDeliver.setDeliverCode(CommonUtil.createSerialNumber(EOrderPrefix.DELIVERY_CODE));
        saDeliver.setRecName(saOrder.getRecName());
        saDeliver.setRecPhone(saOrder.getRecPhone());
        saDeliver.setRecProvince(saOrder.getRecProvince());
        saDeliver.setRecCity(saOrder.getRecCity());
        saDeliver.setRecCounty(saOrder.getRecCounty());
        saDeliver.setRecAddress(saOrder.getRecAddress());
        saDeliver.setDeliverStatus(EDeliveryStatus.RECEIVING.getValue());
        saDeliver.setDeliverTime(nowDate);
        saDeliver.setTranType(saDeliver.getTranType());
        saDeliver.setPkCreator(userId);
        saDeliver.setCreationTime(nowDate);
        saDeliver.setPkCountry(pkCountry);

        if (iOrderBusinessService.updateSaOrderChargeLog(EApprovalBusiness.SELF_DELIVERY_MANAGE, approvalBusinessResultDTO.getBusinessCode(), pkCountry, userId, EAgentApprovalStatus.APPROVED, approvalBusinessResultDTO.getApproveRemark())) {
            // 更新订单修改记录

            // 更新订单为 店铺自提
            LambdaUpdateWrapper<SaOrder> updateOrder = new LambdaUpdateWrapper<>();
            updateOrder.set(SaOrder::getDeliveryWay, EDelivery.COMPANY_PICKED_UP.getValue());
            // 更新仓库
            if (pkStorehouse != null) {
                updateOrder.set(SaOrder::getPkStorehouse, pkStorehouse);
            }
            updateOrder.set(SaOrder::getPkModified, userId);
            updateOrder.set(SaOrder::getModifiedTime, nowDate);
            updateOrder.in(SaOrder::getPkId, orderIdList);
            updateOrder.eq(SaOrder::getDelFlag, EDelFlag.UN_DELETE.getValue());
            iSaOrderService.update(updateOrder);

            // 更新订单明细状态为 已收货
            LambdaUpdateWrapper<SaOrderItems> updateOrderItem = new LambdaUpdateWrapper<>();
            updateOrderItem.set(SaOrderItems::getOrderStatus, EOrderStatus.RECEIVED.getValue());
            updateOrderItem.set(SaOrderItems::getPkModified, userId);
            updateOrderItem.set(SaOrderItems::getModifiedTime, nowDate);
            // 更新仓库
            if (pkStorehouse != null) {
                updateOrderItem.set(SaOrderItems::getPkStorehouse, pkStorehouse);
            }
            updateOrderItem.in(SaOrderItems::getPkOrder, orderIdList);
            updateOrderItem.eq(SaOrderItems::getDelFlag, EDelFlag.UN_DELETE.getValue());
            iSaOrderItemsService.update(updateOrderItem);
            // 添加发货单
            iSaDeliverService.save(saDeliver);

            // 发货单明细map（key：订单明细ID，value：发货单明细）
            Map<Long, SaDeliverItems> deliverItemsMap = new HashMap<>();
            // 添加发货单明细
            List<SaDeliverItems> deliverItemsList = new ArrayList<>();
            for (SaOrderExt saOrderExt : orderList) {
                for (SaOrderItemsExt saOrderItemsExt : saOrderExt.getOrderItemsExtList()) {
                    // 根据订单生成对应发货单
                    SaDeliverItems saDeliverItems = new SaDeliverItems();
                    saDeliverItems.setPkDeliver(saDeliver.getPkId());
                    saDeliverItems.setPkOrder(saOrderExt.getPkId());
                    saDeliverItems.setPkOrderItems(saOrderItemsExt.getPkId());
                    saDeliverItems.setPkProduct(saOrderItemsExt.getPkProduct());
                    saDeliverItems.setQuantity(saOrderItemsExt.getQuantity());
                    saDeliverItems.setPkStorehouse(pkStorehouse);
                    saDeliverItems.setPkCreator(userId);
                    saDeliverItems.setCreationTime(nowDate);
                    saDeliverItems.setPkCountry(pkCountry);
                    saDeliverItems.setSpecsName(saOrderItemsExt.getSpecsName());
                    saDeliverItems.setSpecsNameId(saOrderItemsExt.getSpecsNameId());
                    deliverItemsList.add(saDeliverItems);
                    deliverItemsMap.put(saOrderItemsExt.getPkId(), saDeliverItems);
                }
            }
            iSaDeliverItemsService.saveBatch(deliverItemsList);

            // 添加发货条码
            List<SaDeliverBarCode> deliverBarCodeList = new ArrayList<>();
            for (OrderSelfBarCodeDTO orderSelfBarCodeDTO : barCodeList) {
                SaDeliverItems saDeliverItems = deliverItemsMap.get(orderSelfBarCodeDTO.getItemId());
                // 封装发货条码
                SaDeliverBarCode saDeliverBarCode = new SaDeliverBarCode();
                saDeliverBarCode.setPkDeliver(saDeliverItems.getPkDeliver());
                saDeliverBarCode.setPkDeliverItems(saDeliverItems.getPkId());
                saDeliverBarCode.setPkProduct(orderSelfBarCodeDTO.getProductId());
                saDeliverBarCode.setPkBarCodeItems(orderSelfBarCodeDTO.getBarCodeId());
                saDeliverBarCode.setBarCode(orderSelfBarCodeDTO.getBarCode());
                saDeliverBarCode.setPkCreator(saDeliverItems.getPkCreator());
                saDeliverBarCode.setCreationTime(nowDate);
                saDeliverBarCode.setPkCountry(pkCountry);
                saDeliverBarCode.setPkModified(saDeliverItems.getPkCreator());
                saDeliverBarCode.setModifiedTime(nowDate);
                deliverBarCodeList.add(saDeliverBarCode);
            }
            if (deliverBarCodeList.size() > 0) {
                iSaDeliverBarCodeService.insertBatch(deliverBarCodeList);
            }

            // 处理是否前台自提（更新已通过）
            LambdaUpdateWrapper<SaOrderSelfLog> selfLogUpdateWrapper = new LambdaUpdateWrapper<>();
            selfLogUpdateWrapper.in(SaOrderSelfLog::getPkOrder, orderIdList);
            selfLogUpdateWrapper.eq(SaOrderSelfLog::getApproveStatus, EApproveRechargeStatus.WAIT.getValue());
            selfLogUpdateWrapper.set(SaOrderSelfLog::getApproveStatus, EApproveRechargeStatus.AGREE.getValue());
            selfLogUpdateWrapper.set(SaOrderSelfLog::getPkModified, userId);
            selfLogUpdateWrapper.set(SaOrderSelfLog::getModifiedTime, nowDate);
            saOrderSelfLogService.update(selfLogUpdateWrapper);

            if (null != postage && postage.compareTo(BigDecimal.ZERO) != 0) {
                // 返还邮费不为0，则需要处理邮费
                R resultR = iMemberAccountServiceApi.orderSelfDeliver(saOrder.getPkCreator(), saOrder.getPkRate(), saOrder.getPkCountry(), postage, userId);
                if (!resultR.isSuccess()) {
                    log.error("订单自提同意返还邮费处理失败: {}", resultR.getMsg());
                    // 签呈处理失败
                    throw new ServiceException(TransactionUtils.getContent(CommonMsgConstants.APPROVAL_ERROR) + "：" + resultR.getMsg());
                }
            }
            return null;
        }
        log.error("订单自提同意处理失败: 更新数据失败");
        return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_ERROR);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public String selfDeliverApprovalReject(ApprovalBusinessResultDTO approvalBusinessResultDTO) {
        // 用户ID
        Long userId = approvalBusinessResultDTO.getLoginUser().getUserId();
        // 所属国家
        Integer pkCountry = approvalBusinessResultDTO.getLoginUser().getDataCountry();

        // 查询订单修改记录
        List<SaOrderChargeLog> saOrderChargeLogList = iOrderBusinessService.getSaOrderChargeLogs(approvalBusinessResultDTO, EApprovalBusiness.SELF_DELIVERY_MANAGE);
        if (CollectionUtil.isEmpty(saOrderChargeLogList)) {
            log.error("订单自提驳回处理失败: 签呈不存在!");
            return TransactionUtils.getContent(DocumentMsgConstants.SIGN_NOT_EXIST);
        }
        // 只有多单一个自提，此处直接拿第一条
        if (EAgentApprovalStatus.UNAPPROVED.getValue() != saOrderChargeLogList.get(0).getApprovalStatus()) {
            log.error("订单自提驳回处理失败: 签呈已处理");
            return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_HAS_HANDLE);
        }

        // 订单ID列表
        List<Long> orderIdList = new ArrayList<>();
        // 获取追溯码ID列表
        List<Integer> barCodeItemsIdList = new ArrayList<>();

        for (SaOrderChargeLog saOrderChargeLog : saOrderChargeLogList) {
            OrderSelfDTO orderSelfDTO = JSONUtil.toBean(saOrderChargeLog.getAfterData(), OrderSelfDTO.class);
            // 订单ID列表
            orderIdList.add(saOrderChargeLog.getPkOrder());
            // 获取追溯码ID列表
            barCodeItemsIdList.addAll(orderSelfDTO.getBarCodeList().stream().map(OrderSelfBarCodeDTO::getBarCodeId).collect(Collectors.toList()));
        }

        if (iOrderBusinessService.updateSaOrderChargeLog(EApprovalBusiness.SELF_DELIVERY_MANAGE, approvalBusinessResultDTO.getBusinessCode(), pkCountry, userId, EAgentApprovalStatus.REFUSE, approvalBusinessResultDTO.getApproveRemark())) {
            // 处理是否前台自提（更新已通过）
            LambdaUpdateWrapper<SaOrderSelfLog> selfLogUpdateWrapper = new LambdaUpdateWrapper<>();
            selfLogUpdateWrapper.in(SaOrderSelfLog::getPkOrder, orderIdList);
            selfLogUpdateWrapper.eq(SaOrderSelfLog::getApproveStatus, EApproveRechargeStatus.WAIT.getValue());
            selfLogUpdateWrapper.set(SaOrderSelfLog::getApproveStatus, EApproveRechargeStatus.REJECT.getValue());
            selfLogUpdateWrapper.set(SaOrderSelfLog::getPkModified, userId);
            selfLogUpdateWrapper.set(SaOrderSelfLog::getModifiedTime, new Date());
            saOrderSelfLogService.update(selfLogUpdateWrapper);

            if (CollectionUtil.isNotEmpty(barCodeItemsIdList)) {
                // 存在条码，则取消条码使用状态
                R<String> resultR = iBarCodeServiceApi.clearBarCode(barCodeItemsIdList, pkCountry, userId);
                if (!resultR.isSuccess()) {
                    throw new ServiceException(TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED) + "：" + resultR.getMsg());
                }
            }
            return null;
        }
        log.error("订单自提驳回处理失败: 更新数据失败");
        return TransactionUtils.getContent(DocumentMsgConstants.DOCUMENT_ORDER_ERROR);
    }


}

