package com.ruoyi.logistics.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lop.open.api.sdk.domain.ECAP.CommonQueryOrderApi.commonGetActualFeeInfoV1.CommonActualFeeInfoDetailResponse;
import com.lop.open.api.sdk.domain.ECAP.CommonQueryOrderApi.commonGetActualFeeInfoV1.CommonActualFeeResponse;
import com.lop.open.api.sdk.domain.ECAP.CommonQueryOrderApi.commonGetOrderByMonthSettleQRV1.CommonMonthSettleQRQueryResponse;
import com.lop.open.api.sdk.domain.ECAP.CommonQueryOrderApi.commonGetOrderByMonthSettleQRV1.WaybillQRVerifyInfo;
import com.lop.open.api.sdk.domain.ECAP.CommonQueryOrderApi.commonGetOrderInfoV1.addedProducts;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.redis.service.RedisIdGenerator;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.logistics.constant.RedisCacheConstants;
import com.ruoyi.logistics.domain.BizFinancialFeeItems;
import com.ruoyi.logistics.domain.BizWaybillCostDetails;
import com.ruoyi.logistics.domain.BizWaybillOrder;
import com.ruoyi.logistics.dto.MonthQRCodeDTO;
import com.ruoyi.logistics.mapper.BizWaybillCostDetailsMapper;
import com.ruoyi.logistics.mapper.BizWaybillOrderMapper;
import com.ruoyi.logistics.response.CommonOrderInfoResponse;
import com.ruoyi.logistics.service.*;
import com.ruoyi.system.api.domain.SysDept;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MonthQRCodeTaskServiceImpl implements IMonthQRCodeTaskService {

    @Autowired
    private RedisService redisService;

    @Autowired
    private LogisticsOrderService logisticsOrderService;

    @Autowired
    private FeeItemsCacheService feeItemsCacheService;

    @Autowired
    private BizWaybillOrderMapper bizWaybillOrderMapper;

    @Autowired
    private BizWaybillCostDetailsMapper bizWaybillCostDetailsMapper;

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Autowired
    private SysUserMapper sysUserMapper;


    @Autowired
    private RedisIdGenerator redisIdGenerator;

    @Override
    public void consumeQRCode() {
        Collection<String> keys = redisService.keys(RedisCacheConstants.MONTH_QRCODE_CACHE_KEY + "*");
        if (keys == null || keys.size() == 0) {
            return;
        }

        for (String key : keys) {
            MonthQRCodeDTO monthQRCodeDTO = redisService.getCacheObject(key);
            if (DateUtils.differentMinutes(monthQRCodeDTO.getCreateTime(), DateUtils.getNowDate()) < 5) {
                continue;
            }

            SysUser sysUser = sysUserMapper.selectUserById(monthQRCodeDTO.getUserId());
            SysDept sysDept = sysDeptMapper.selectDeptById(monthQRCodeDTO.getDeptId());

            if (1 == monthQRCodeDTO.getSource()) {
                this.jdQRCodeConsume(monthQRCodeDTO, sysUser, sysDept, key);
            }
        }
    }

    private void jdQRCodeConsume(MonthQRCodeDTO monthQRCodeDTO, SysUser sysUser, SysDept sysDept, String key) {
        JSONObject waybillCode = logisticsOrderService.queryOrderByQRCode(1, monthQRCodeDTO.getQrCodeContent());
        if(!waybillCode.getBooleanValue("success")){
            log.info("根据二维码查询运单号失败{}", waybillCode.getString("msg"));
            return;
        }

        CommonMonthSettleQRQueryResponse response = JSON.parseObject(waybillCode.getString("msg"), CommonMonthSettleQRQueryResponse.class);

        if (response.getWaybillQRVerifyInfoList() != null && response.getWaybillQRVerifyInfoList().size() > 0) {

            for (WaybillQRVerifyInfo waybillQRVerifyInfo : response.getWaybillQRVerifyInfoList()) {
                // 判断订单是否已经处理过
                if (monthQRCodeDTO.getProcessWaybillCodes().contains(waybillQRVerifyInfo.getWaybillCode())) {
                    continue;
                }
                monthQRCodeDTO.getProcessWaybillCodes().add(waybillQRVerifyInfo.getWaybillCode());

                JSONObject orderDetail = logisticsOrderService.queryOrderDetailByWaybillCode(1, waybillQRVerifyInfo.getWaybillCode());
                if(!waybillCode.getBooleanValue("success")){
                    log.info("根据运单号查询运单详情失败{}", waybillCode.getString("msg"));
                    continue;
                }
                JSONObject orderFeeInfo = logisticsOrderService.queryOrderFeeInfoByWaybillCode(1, waybillQRVerifyInfo.getWaybillCode());
                if(!waybillCode.getBooleanValue("success")){
                    log.info("根据运单号查询运单费用失败{}", waybillCode.getString("msg"));
                    continue;
                }

                CommonOrderInfoResponse orderInfo = (CommonOrderInfoResponse) orderDetail.get("msg");
                CommonActualFeeResponse actualFee = JSON.parseObject(orderFeeInfo.getString("msg"), CommonActualFeeResponse.class);

                BizWaybillOrder bizWaybillOrder = new BizWaybillOrder();
                bizWaybillOrder.setWaybillNo(redisIdGenerator.generateUniqueId("RJSD"));
                bizWaybillOrder.setExternalWaybillNo(orderInfo.getWaybillCode());
                bizWaybillOrder.setOrderType(1);
//                    bizWaybillOrder.setSenderName(orderInfo.gets());
//                    bizWaybillOrder.setSenderPhone(orderInfo.getSenderPhone());
                bizWaybillOrder.setSenderProvince(orderInfo.getSenderContact().getProvince());
                bizWaybillOrder.setSenderCity(orderInfo.getSenderContact().getCity());
                bizWaybillOrder.setSenderCounty(orderInfo.getSenderContact().getCounty());
                bizWaybillOrder.setSenderAddress(orderInfo.getSenderContact().getTown());
                bizWaybillOrder.setReceiverName(sysUser.getNickName());
                bizWaybillOrder.setReceiverPhone(sysUser.getPhonenumber());
                bizWaybillOrder.setReceiverProvince(orderInfo.getReceiverContact().getProvince());
                bizWaybillOrder.setReceiverCity(orderInfo.getReceiverContact().getCity());
                bizWaybillOrder.setReceiverCounty(orderInfo.getReceiverContact().getCounty());
                bizWaybillOrder.setReceiverAddress(orderInfo.getReceiverContact().getTown());
                bizWaybillOrder.setGoodsName(orderInfo.getCargoes().get(0).getName());
                bizWaybillOrder.setGoodsWeight(new BigDecimal(orderInfo.getCargoes().get(0).getWeight()));
                bizWaybillOrder.setGoodsVolume(new BigDecimal(orderInfo.getCargoes().get(0).getVolume()));
                bizWaybillOrder.setGoodsQty(orderInfo.getCargoes().get(0).getQuantity().longValue());
                bizWaybillOrder.setOrderStatus(6);
                bizWaybillOrder.setPickupType(orderInfo.getShipmentInfo().getPickupType());
                bizWaybillOrder.setSendStartTime(new Date(orderInfo.getShipmentInfo().getPickupStartTime()));
                bizWaybillOrder.setSendEndTime(new Date(orderInfo.getShipmentInfo().getPickupEndTime()));
//                    bizWaybillOrder.setPickupTime(new Date(orderInfo.getShipmentInfo().geta()));
//                    bizWaybillOrder.setDeliveryTime(waybillQRVerifyInfo.getDeliveryTime());
//                    bizWaybillOrder.setSignTime(waybillQRVerifyInfo.getSignTime());
                bizWaybillOrder.setProductCode(orderInfo.getProducts().getProductCode());
                bizWaybillOrder.setAddedService(assembleJDAddedService(orderInfo.getProducts().getAddedProducts()));
                bizWaybillOrder.setCreateTime(DateUtils.getNowDate());
                bizWaybillOrder.setUserId(monthQRCodeDTO.getUserId());
                bizWaybillOrder.setDeptId(monthQRCodeDTO.getDeptId());

                bizWaybillOrderMapper.insertBizWaybillOrder(bizWaybillOrder);

                List<BizWaybillCostDetails> details = assembleJDCostDetails(sysDept, bizWaybillOrder, actualFee.getCommonActualFeeInfoDetails());

                details.forEach(detail -> {
                    bizWaybillCostDetailsMapper.insertBizWaybillCostDetails(detail);
                });
            }

            redisService.setCacheObject(key, monthQRCodeDTO);
        }
    }

    private List<BizWaybillCostDetails> assembleJDCostDetails(SysDept sysDept, BizWaybillOrder bizWaybillOrder, List<CommonActualFeeInfoDetailResponse> commonActualFeeInfoDetails) {
        List<BizWaybillCostDetails> details = new ArrayList<>();
        commonActualFeeInfoDetails.forEach(item -> {
            BizWaybillCostDetails costDetail = new BizWaybillCostDetails();
            costDetail.setWaybillId(bizWaybillOrder.getWaybillId());
            costDetail.setExternalWaybillNo(bizWaybillOrder.getExternalWaybillNo());

            // 匹配费用类型项
            BizFinancialFeeItems feeItemByExtFeeCode = feeItemsCacheService.getFeeItemByExtFeeCode(item.getFeeType());
            if (feeItemByExtFeeCode != null) {
                costDetail.setFeeItemCode(feeItemByExtFeeCode.getFeeItemCode());
                costDetail.setFeeItemName(feeItemByExtFeeCode.getFeeItemName());
                costDetail.setFeeName(item.getFeeTypeName());
                costDetail.setAmount(item.getMoney());
                costDetail.setRateAmount(item.getMoney().multiply(new BigDecimal(StringUtils.isNotBlank(sysDept.getRateValue()) ? sysDept.getRateValue() : "1")).setScale(2, BigDecimal.ROUND_HALF_UP));
                costDetail.setDeptId(bizWaybillOrder.getDeptId());
                costDetail.setUserId(bizWaybillOrder.getUserId());
            }

            details.add(costDetail);
        });
        return details;
    }

    private String assembleJDAddedService(List<addedProducts> addedProducts) {
        JSONObject addedService = new JSONObject();

        addedService.put("isPack", null);
        addedService.put("isGuaranteeMoney", null);
        addedService.put("isReceiptCollect", null);

        List<String> collect = addedProducts.stream().map(com.lop.open.api.sdk.domain.ECAP.CommonQueryOrderApi.commonGetOrderInfoV1.addedProducts::getProductCode).collect(Collectors.toList());

        collect.forEach(item -> {
            switch (item) {
                case "ed-a-0011":
                case "fr-a-0005":
                    addedService.put("isPack", true);
                    break;
                case "ed-a-0002":
                case "fr-a-0002":
                    addedService.put("isGuaranteeMoney", true);
                    break;
                case "ed-a-0010":
                case "fr-a-0007":
                    addedService.put("isReceiptCollect", true);
            }
        });
        return addedService.toJSONString();
    }
}
