package com.yiqi.order.service.impl;

import cn.binarywang.wx.miniapp.bean.express.WxMaExpressAccount;
import cn.binarywang.wx.miniapp.bean.express.WxMaExpressDelivery;
import cn.binarywang.wx.miniapp.bean.express.WxMaExpressPath;
import cn.binarywang.wx.miniapp.bean.express.request.*;
import cn.binarywang.wx.miniapp.bean.express.result.WxMaExpressOrderInfoResult;
import com.yiqi.common.exception.ServiceException;
import com.yiqi.common.config.CompositeWxMaService;
import com.yiqi.common.config.RuoYiConfig;
import com.yiqi.common.config.WxMaProperties;
import com.yiqi.common.core.domain.AuthHolder;
import com.yiqi.common.enums.PlatformType;
import com.yiqi.common.enums.SystemEnv;
import com.yiqi.common.enums.ThirdDeliveryActionType;
import com.yiqi.common.utils.EnumUtils;
import com.yiqi.common.utils.OrderNoUtils;
import com.yiqi.core.domain.dto.WxNotifyDTO;
import com.yiqi.core.domain.dto.WxNotifyDeliveryActionDTO;
import com.yiqi.order.domain.dto.*;
import com.yiqi.order.domain.vo.ExpressDeliveryVO;
import com.yiqi.order.domain.vo.OrderDeliveryPathVO;
import com.yiqi.order.service.IOrderClothService;
import com.yiqi.order.service.IOrderGoodsService;
import com.yiqi.order.service.IOrderPurchaseGoodsService;
import com.yiqi.order.service.IThirdDeliveryService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * @author xiaohei
 * @date 2024/1/21
 */
@Service
public class ThirdDeliveryServiceImpl implements IThirdDeliveryService {

    @Autowired
    private CompositeWxMaService compositeWxMaService;
    @Autowired
    private RuoYiConfig ruoYiConfig;
    @Autowired
    private WxMaProperties wxMaProperties;
    @Autowired
    private IOrderGoodsService orderGoodsService;
    @Autowired
    private IOrderPurchaseGoodsService orderPurchaseGoodsService;
    @Autowired
    private IOrderClothService orderClothService;

    @Override
    public List<ExpressDeliveryVO> getAllDeliveryList() throws Exception{
        List<WxMaExpressAccount> allAccount = compositeWxMaService.getWxapp().getExpressService().getAllAccount();

        Map<String,WxMaExpressDelivery> deliveryMap = compositeWxMaService.getWxapp().getExpressService()
                .getAllDelivery().stream()
                .collect(Collectors.toMap(WxMaExpressDelivery::getDeliveryId,WxMaExpressDelivery -> WxMaExpressDelivery));

        List<ExpressDeliveryVO> expressDeliveries = new ArrayList<>();
        if(PlatformType.MANAGER.getCode().equals(AuthHolder.platform())){
            //月付的账号
            for (WxMaExpressAccount wxMaExpressAccount : allAccount) {
                if(!deliveryMap.containsKey(wxMaExpressAccount.getDeliveryId())){
                    continue;
                }
                WxMaExpressDelivery wxMaExpressDelivery = deliveryMap.get(wxMaExpressAccount.getDeliveryId());
                ExpressDeliveryVO expressDeliveryVO = new ExpressDeliveryVO();
                BeanUtils.copyProperties(wxMaExpressDelivery, expressDeliveryVO);
                if(!SystemEnv.PROD.getCode().equals(ruoYiConfig.getEnv())){
                    expressDeliveryVO.setBizId("test_biz_id");
                    expressDeliveryVO.setDeliveryId("TEST");
                }
                expressDeliveryVO.setCreateTime(new Date(wxMaExpressAccount.getCreateTime() * 1000L));
                expressDeliveryVO.setUpdateTime(new Date(wxMaExpressAccount.getUpdateTime() * 1000L));
                expressDeliveryVO.setStatusCode(wxMaExpressAccount.getStatusCode() + "");
                expressDeliveryVO.setRemarkContent(wxMaExpressAccount.getRemarkContent());
                expressDeliveryVO.setRemarkWrongMsg(wxMaExpressAccount.getRemarkWrongMsg());
                expressDeliveryVO.setQuotaNum(wxMaExpressAccount.getQuotaNum());
                if(wxMaExpressAccount.getQuotaUpdateTime() != null){
                    expressDeliveryVO.setQuotaUpdateTime(new Date(wxMaExpressAccount.getQuotaUpdateTime() * 1000L));
                }
                List<ExpressDeliveryVO.ServiceType> serviceTypes = new ArrayList<>();
                for (WxMaExpressDelivery.ServiceType item : wxMaExpressAccount.getServiceType()) {
                    ExpressDeliveryVO.ServiceType serviceType = new ExpressDeliveryVO.ServiceType();
                    if(SystemEnv.PROD.getCode().equals(ruoYiConfig.getEnv())){
                        serviceType.setServiceType(item.getServiceType());
                        serviceType.setServiceName(item.getServiceName());
                    }else{
                        serviceType.setServiceType(1);
                        serviceType.setServiceName("test_service_name");
                    }
                    serviceTypes.add(serviceType);
                }
                expressDeliveryVO.setServiceType(serviceTypes);
                expressDeliveries.add(expressDeliveryVO);
            }
        }
        //现付快递
        expressDeliveries.add(buildSFExpress());
        expressDeliveries.add(buildDBExpress());

        return expressDeliveries;
    }

    private ExpressDeliveryVO buildSFExpress(){
        ExpressDeliveryVO expressDeliveryVO = new ExpressDeliveryVO();
        if(!SystemEnv.PROD.getCode().equals(ruoYiConfig.getEnv())){
            expressDeliveryVO.setBizId("test_biz_id");
            expressDeliveryVO.setDeliveryId("TEST");
        }else{
            expressDeliveryVO.setDeliveryId("SF");
            expressDeliveryVO.setBizId("SF_CASH");
        }
        expressDeliveryVO.setDeliveryName("顺丰速运（现付）");
        List<ExpressDeliveryVO.ServiceType> serviceTypes = new ArrayList<>();
        if(!SystemEnv.PROD.getCode().equals(ruoYiConfig.getEnv())){
            serviceTypes.add(new ExpressDeliveryVO.ServiceType(1,"test_service_name"));
        }else{
            serviceTypes.add(new ExpressDeliveryVO.ServiceType(0,"标准快递"));
            serviceTypes.add(new ExpressDeliveryVO.ServiceType(1,"顺丰即日"));
            serviceTypes.add(new ExpressDeliveryVO.ServiceType(2,"顺丰特快"));
            serviceTypes.add(new ExpressDeliveryVO.ServiceType(3,"顺丰标快"));
        }
        expressDeliveryVO.setServiceType(serviceTypes);
        return expressDeliveryVO;
    }

    private ExpressDeliveryVO buildDBExpress(){
        ExpressDeliveryVO expressDeliveryVO = new ExpressDeliveryVO();
        if(!SystemEnv.PROD.getCode().equals(ruoYiConfig.getEnv())){
            expressDeliveryVO.setBizId("test_biz_id");
            expressDeliveryVO.setDeliveryId("TEST");
        }else{
            expressDeliveryVO.setDeliveryId("DB");
            expressDeliveryVO.setBizId("DB_CASH");
        }
        expressDeliveryVO.setDeliveryName("德邦快递（现付）");
        List<ExpressDeliveryVO.ServiceType> serviceTypes = new ArrayList<>();
        if(!SystemEnv.PROD.getCode().equals(ruoYiConfig.getEnv())){
            serviceTypes.add(new ExpressDeliveryVO.ServiceType(1,"test_service_name"));
        }else{
            serviceTypes.add(new ExpressDeliveryVO.ServiceType(1,"大件快递3.60"));
            serviceTypes.add(new ExpressDeliveryVO.ServiceType(2,"特准快件"));
        }
        expressDeliveryVO.setServiceType(serviceTypes);
        return expressDeliveryVO;
    }

    @Override
    public WxMaExpressOrderInfoResult addDeliveryOrder(OrderThirdDeliveryAddDTO orderThirdDeliveryAddDTO) throws Exception {
        WxMaExpressAddOrderRequest wxMaExpressAddOrderRequest = new WxMaExpressAddOrderRequest();
        wxMaExpressAddOrderRequest.setOrderId(orderThirdDeliveryAddDTO.getOrderNo());
        wxMaExpressAddOrderRequest.setOpenid(orderThirdDeliveryAddDTO.getOpenid());
        wxMaExpressAddOrderRequest.setBizId(orderThirdDeliveryAddDTO.getBizId());
        wxMaExpressAddOrderRequest.setDeliveryId(orderThirdDeliveryAddDTO.getDeliveryId());
        wxMaExpressAddOrderRequest.setCustomRemark(orderThirdDeliveryAddDTO.getCustomRemark());
        wxMaExpressAddOrderRequest.setAddSource(orderThirdDeliveryAddDTO.getAddSource());
        wxMaExpressAddOrderRequest.setWxAppid(wxMaProperties.getAppid());
        WxMaExpressOrderPerson sender = new WxMaExpressOrderPerson();
        BeanUtils.copyProperties(orderThirdDeliveryAddDTO.getSender(),sender);
        wxMaExpressAddOrderRequest.setSender(sender);
        WxMaExpressOrderPerson receiver = new WxMaExpressOrderPerson();
        BeanUtils.copyProperties(orderThirdDeliveryAddDTO.getReceiver(),receiver);
        wxMaExpressAddOrderRequest.setReceiver(receiver);
        WxMaExpressOrderCargo cargo = new WxMaExpressOrderCargo();
        BeanUtils.copyProperties(orderThirdDeliveryAddDTO.getCargo(),cargo);
        wxMaExpressAddOrderRequest.setCargo(cargo);
        WxMaExpressOrderShop shop = new WxMaExpressOrderShop();
        shop.setDetailList(new ArrayList<>());
        for (OrderThirdDeliveryGoodsDTO orderThirdDeliveryGoodsDTO : orderThirdDeliveryAddDTO.getGoodsList()) {
            WxMaExpressOrderShopDetail wxMaExpressOrderShopDetail = new WxMaExpressOrderShopDetail();
            BeanUtils.copyProperties(orderThirdDeliveryGoodsDTO,wxMaExpressOrderShopDetail);
            shop.getDetailList().add(wxMaExpressOrderShopDetail);
        }
        wxMaExpressAddOrderRequest.setShop(shop);
        wxMaExpressAddOrderRequest.setInsured(new WxMaExpressOrderInsured());
        wxMaExpressAddOrderRequest.setExpectTime(orderThirdDeliveryAddDTO.getExpectTime().getTime()/1000);

        WxMaExpressOrderInfoResult result = compositeWxMaService.getWxapp().getExpressService().addOrder(wxMaExpressAddOrderRequest);
        if(result.getErrcode() != 0){
            throw new ServiceException("快递订单新增异常，errorCode:" + result.getErrcode() + "；errorMsg:" + result.getErrmsg());
        }
        return result;
    }

    @Override
    public OrderDeliveryPathVO getDeliveryPath(OrderThirdDeliveryPathDTO orderThirdDeliveryPathDTO) throws Exception {
        WxMaExpressGetOrderRequest request = new WxMaExpressGetOrderRequest();
        request.setDeliveryId(orderThirdDeliveryPathDTO.getDeliveryId());
        request.setWaybillId(orderThirdDeliveryPathDTO.getWaybillId());
        request.setOpenid(orderThirdDeliveryPathDTO.getOpenId());
        WxMaExpressPath path = compositeWxMaService.getWxapp().getExpressService().getPath(request);
        OrderDeliveryPathVO orderDeliveryPathVO = new OrderDeliveryPathVO();
        orderDeliveryPathVO.setDeliveryId(path.getDeliveryId());
        orderDeliveryPathVO.setPathItemNum(path.getPathItemNum());
        orderDeliveryPathVO.setWaybillId(path.getWaybillId());
        for (WxMaExpressPath.PathItem item : path.getPathItemList()) {
            OrderDeliveryPathVO.PathItem pathItem = new OrderDeliveryPathVO.PathItem();
            pathItem.setActionMsg(item.getActionMsg());
            pathItem.setActionTime(new Date(item.getActionTime() * 1000L));
            pathItem.setActionType(item.getActionType());
            orderDeliveryPathVO.getPathItemList().add(pathItem);
        }
        return orderDeliveryPathVO;
    }

    @Override
    public void testUpdateOrder(OrderThirdDeliveryTestUpdateStatusDTO orderThirdDeliveryTestUpdateStatusDTO) throws Exception {
        WxMaExpressTestUpdateOrderRequest request = new WxMaExpressTestUpdateOrderRequest(
                orderThirdDeliveryTestUpdateStatusDTO.getBizId()
                ,orderThirdDeliveryTestUpdateStatusDTO.getDeliveryId()
                ,orderThirdDeliveryTestUpdateStatusDTO.getOrderId()
                ,orderThirdDeliveryTestUpdateStatusDTO.getWaybillId()
                ,orderThirdDeliveryTestUpdateStatusDTO.getActionTime().getTime()/1000L
                , orderThirdDeliveryTestUpdateStatusDTO.getActionType()
                , EnumUtils.getIntEnumByType(orderThirdDeliveryTestUpdateStatusDTO.getActionType(), ThirdDeliveryActionType.class).getInfo());
        compositeWxMaService.getWxapp().getExpressService().testUpdateOrder(request);
    }

    @Override
    public void cancelOrder(OrderThirdDeliveryCancelDTO orderThirdDeliveryCancelDTO) throws Exception {
        WxMaExpressGetOrderRequest request = new WxMaExpressGetOrderRequest();
        request.setOpenid(orderThirdDeliveryCancelDTO.getOpenId());
        request.setDeliveryId(orderThirdDeliveryCancelDTO.getDeliveryId());
        request.setWaybillId(orderThirdDeliveryCancelDTO.getWaybillId());
        request.setOrderId(orderThirdDeliveryCancelDTO.getOrderNo());
        compositeWxMaService.getWxapp().getExpressService().cancelOrder(request);
    }

    @Override
    public void onDeliveryOrderChangeNotify(WxNotifyDTO wxNotifyDTO) throws Exception {
        for (WxNotifyDeliveryActionDTO action : wxNotifyDTO.getActions()) {
            if(action.getActionType().equals(ThirdDeliveryActionType._300003.getCode())){
                onDeliveryFinish(wxNotifyDTO);
                break;
            }
        }
    }

    private void onDeliveryFinish(WxNotifyDTO wxNotifyDTO){
        switch (wxNotifyDTO.getOrderNo().substring(0,2)){
            case OrderNoUtils
                    .delivery_order_header://洗衣订单配送完成
            {
                orderClothService.handleDeliverySuccessUpdateOrderStatus(wxNotifyDTO.getOrderNo());
                break;
            }
            case OrderNoUtils
                    .goods_order_header://商品订单配送完成
            {
                orderGoodsService.handleDeliverySuccessUpdateOrderStatus(wxNotifyDTO.getOrderNo());
                break;
            }
            case OrderNoUtils
                    .purchase_order_header://进销存订单配送完成
            {
                orderPurchaseGoodsService.handleDeliverySuccessUpdateOrderStatus(wxNotifyDTO.getOrderNo());
                break;
            }
        }
    }
}
