package cn.freemud.service.delivery;

import cn.freemud.amp.service.ProduceMQService;
import cn.freemud.base.entity.BaseResponse;
import cn.freemud.base.log.LogTreadLocal;
import cn.freemud.entities.dto.delivery.*;
import cn.freemud.entities.dto.pos.PosBaseRequestDto;
import cn.freemud.entities.vo.delivery.DeliveryAmountVo;
import cn.freemud.enums.DeliveryReviewStatus;
import cn.freemud.enums.DeliveryStatus;
import cn.freemud.enums.ResponseResult;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.management.entities.dto.request.order.OrderManagerRequest;
import cn.freemud.management.enums.OperateType;
import cn.freemud.management.service.adapter.OrderManagerAdapter;
import cn.freemud.service.Orderservice;
import cn.freemud.service.ThirdDeliveryService;
import cn.freemud.service.thirdparty.DeliveryFeiginClient;
import cn.freemud.service.thirdparty.PosClient;
import cn.freemud.utils.LogUtil;
import cn.freemud.utils.ResponseUtil;
import com.alibaba.fastjson.JSONObject;
import com.freemud.application.sdk.api.constant.ResponseConstant;
import com.freemud.application.sdk.api.deliverycenter.dto.CancelDeliveryOrderRequestDto;
import com.freemud.application.sdk.api.deliverycenter.response.DeliveryInfoDto;
import com.freemud.application.sdk.api.deliverycenter.response.DeliveryResponseDto;
import com.freemud.application.sdk.api.deliverycenter.service.DeliveryService;
import com.freemud.application.sdk.api.log.LogThreadLocal;
import com.freemud.application.sdk.api.ordercenter.request.OrderCollectReq;
import com.freemud.application.sdk.api.ordercenter.service.OrderSdkService;
import com.freemud.sdk.api.assortment.order.request.order.AssortmentUpdateDeliveryAbnormalRequest;
import com.freemud.sdk.api.assortment.order.request.order.UpdateDeliveryInfoByIdRequest;
import com.freemud.sdk.api.assortment.order.response.order.OrderBaseResponse;
import com.freemud.sdk.api.assortment.order.service.OrderCenterSdkService;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @version V1.6.0
 * @Title: ThirdDeliveryServiceImpl
 * @Description: 配送服务
 * @author: qin.zhou
 * @date: 2019/6/1119:55
 * @Copyright: ${DATE.YARE} www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */
@Slf4j
@Service
public class ThirdDeliveryServiceImpl implements ThirdDeliveryService {

    private final static Integer SUCCESS_RESPONSE_CODE = 100;
    @Autowired
    private DeliveryService deliveryService;
    @Autowired
    private OrderCenterSdkService orderCenterSdkService;
    @Autowired
    private PosClient posClient;
    @Autowired
    private ProduceMQService produceMQService;
    @Autowired
    private DeliveryFeiginClient deliveryFeiginClient;
    @Autowired
    private OrderManagerAdapter orderManagerAdapter;
    @Autowired
    private OrderSdkService orderSdkService;

    @Override
    public BaseResponse callbackUrl(CallbackUrlRequestDto request) {
        // 获取回调状态
        int deliveryStatus = request.getDeliveryStatus();
        // 获取配送单信息
        DeliveryResponseDto<DeliveryInfoDto> delivery = deliveryService.deliveryOrderOne(request.getDeliveryId(), LogThreadLocal.getTrackingNo());
        if (SUCCESS_RESPONSE_CODE != delivery.getCode() || delivery.getData() == null) {
            return ResponseUtil.error(ResponseResult.DELIVERY_QUERY_ERROR);
        }
        String partnerId = delivery.getData().getPartnerId();
        String storeCode = delivery.getData().getStoreCode();
        // 调用订单服务修改运单号，第三方运单号，骑手信息，运单状态
        UpdateDeliveryInfoByIdRequest requestDto = new UpdateDeliveryInfoByIdRequest();
        requestDto.setOrderId(request.getOrderId());
        requestDto.setDeliveryId(request.getDeliveryId());
        requestDto.setCourierName(request.getRiderName());
        requestDto.setCourierPhone(request.getRiderPhone());
        requestDto.setExpress(request.getChannelCode());
        requestDto.setExpressChannelName(request.getChannelName());
        requestDto.setExpressNo(request.getChannelDeliveryId());
        requestDto.setOrderSubState(deliveryStatus);
        if (StringUtils.isNotBlank(request.getRemark()))
        {
            requestDto.setRemark("配送:"+request.getRemark());
        }
        OrderBaseResponse orderBaseResponseDto = orderCenterSdkService.updateDeliveryInfoById(requestDto);
        //订单服务修改配送单信息失败
        if (!SUCCESS_RESPONSE_CODE.equals(orderBaseResponseDto.getErrcode())) {
            LogUtil.error("updateDeliveryInfoById_error", JSONObject.toJSONString(requestDto), JSONObject.toJSONString(orderBaseResponseDto));
            return ResponseUtil.success();
        }
        PosBaseRequestDto posBaseRequestDto = new PosBaseRequestDto();
        posBaseRequestDto.setOrder_id(request.getOrderId());
        posBaseRequestDto.setPartner_id(partnerId);
        if (deliveryStatus == DeliveryStatus.ALLOTRIDER.getCode()) {
            //骑手接单推送POS服务
            posBaseRequestDto.setStore_id(storeCode);
            posBaseRequestDto.setRider_name(request.getRiderName());
            posBaseRequestDto.setRider_phone(request.getRiderPhone());
            posBaseRequestDto.setDelivery_status(DeliveryStatus.ALLOTRIDER.getCode());
            posBaseRequestDto.setPartner_id(partnerId);
            sendPosService(deliveryStatus,posBaseRequestDto);
        } else if (deliveryStatus == DeliveryStatus.RIDERGETMEAL.getCode() || deliveryStatus == DeliveryStatus.RIDERSTARTDELIVERY.getCode()) {
            // 订单配送
            sendPosService(deliveryStatus,posBaseRequestDto);
        } else if (deliveryStatus == DeliveryStatus.DELIVERYARRIVED.getCode()) {
            // 订单已完成
            sendPosService(deliveryStatus,posBaseRequestDto);
        } else if (deliveryStatus == DeliveryStatus.DELIVERYERROR.getCode() || deliveryStatus == DeliveryStatus.DELIVERYCANCEL.getCode()) {

            // 取消外卖中台配送单 订单异常
            // 如果 "配送单异常并且顾客更改配送地址" 不取消配送单
            if (!isDeliveryAbnormalAndCustomerChangedAddress(request)) {
                partnerCancelOrder(request.getDeliveryId());
            }
            // 运单异常，取消订单
            posBaseRequestDto.setReason("没有骑手接单");
            posBaseRequestDto.setDeliveryId(request.getDeliveryId());
            sendPosService(deliveryStatus,posBaseRequestDto);
        }

        // 订单配送状态变化时发送到MQ
        if (DeliveryStatus.checkDeliveryStatueForPlatform(deliveryStatus)) {
            produceMQService.sendOfDeliveryInfo(request);
            produceMQService.sendRocketMqOfDeliveryInfo(request);
        }
//        else {
//            return ResponseUtil.error(ResponseResult.SYSTEM_ERROR.getCode(), "订单回调状态有误");
//        }
        return ResponseUtil.success();
    }

    /**
     * 配送回调
     *
     * @param request
     */
    @Override
    public BaseResponse macCafeCallbackUrl(MacCafeCallbackUrlRequestDto request) {
        OrderManagerRequest orderManagerRequest=new OrderManagerRequest();
        orderManagerRequest.setPartnerId(request.getPartnerId());
        orderManagerRequest.setOrderId(request.getOrderId());
        orderManagerRequest.setOperator("配送回调");


        Integer reviewStatus = request.getReviewStatus();
        int deliveryStatus = request.getDeliveryStatus();
        if (reviewStatus!=null && reviewStatus.equals(DeliveryReviewStatus.AGREE.getCode())){
            orderManagerRequest.setOperateType(OperateType.ORDER_AGREE_REFUND.getOpType());
            orderManagerRequest.setReason("配送回调-同意退款");
            return orderManagerAdapter.orderAgreeRefund(orderManagerRequest);
        }
        if (reviewStatus!=null && reviewStatus.equals(DeliveryReviewStatus.REJECT.getCode())){
            orderManagerRequest.setOperateType(OperateType.ORDER_REJECT_REFUND.getOpType());
            orderManagerRequest.setReason("配送回调-拒绝退款");
            return orderManagerAdapter.orderRejectRefund(orderManagerRequest);
        }
        if (deliveryStatus == DeliveryStatus.RIDERGETMEAL.getCode() || deliveryStatus == DeliveryStatus.RIDERSTARTDELIVERY.getCode()){
            orderManagerRequest.setOperateType(OperateType.ORDER_SEND.getOpType());
            return orderManagerAdapter.orderDelivery(orderManagerRequest);
        } else if (deliveryStatus == DeliveryStatus.DELIVERYARRIVED.getCode() ){
            orderManagerRequest.setOperateType(OperateType.ORDER_AFFIRM.getOpType());
            return orderManagerAdapter.orderAffirm(orderManagerRequest,null);
        } else if(deliveryStatus == DeliveryStatus.WATINGORDER.getCode() || deliveryStatus == DeliveryStatus.SYSTEMGETORDER.getCode()
                || deliveryStatus == DeliveryStatus.ALLOTRIDER.getCode()|| deliveryStatus == DeliveryStatus.RIDERARRIVESTORE.getCode()) {
            return ResponseUtil.success();
        } else if(deliveryStatus == DeliveryStatus.COLLECTING.getCode()) {
            //推送订单到拉单队列
            OrderCollectReq orderCollectReq = new OrderCollectReq();
            orderCollectReq.setOrderCode(request.getOrderId());
            orderCollectReq.setPartnerId(request.getPartnerId());
            com.freemud.application.sdk.api.ordercenter.response.BaseResponse baseResponse = orderSdkService.collectOrder(orderCollectReq, LogTreadLocal.getTrackingNo());
            if(ResponseConstant.SUCCESS_RESPONSE_CODE_STR.equals(baseResponse.getCode())) {
                ResponseUtil.error(ResponseResult.ORDER_COLLECT_FAILED);
            }
            //回调成功，记录汇集状态
            UpdateDeliveryInfoByIdRequest updateDeliveryInfoByIdRequest = new UpdateDeliveryInfoByIdRequest();
            updateDeliveryInfoByIdRequest.setOrderId(request.getOrderId());
            updateDeliveryInfoByIdRequest.setOrderSubState(DeliveryStatus.COLLECTING.getCode());
            updateDeliveryInfoByIdRequest.setOperator("sys");
            orderCenterSdkService.updateDeliveryInfoById(updateDeliveryInfoByIdRequest);
            return ResponseUtil.success();
        }
        return ResponseUtil.error(ResponseResult.ORDER_DELIVERY_CALL_BACK_FAILED);
    }

    /**
     * 配送单异常并且顾客更改配送地址
     *
     * @return
     */
    public boolean isDeliveryAbnormalAndCustomerChangedAddress(CallbackUrlRequestDto request) {
        if (DeliveryStatus.DELIVERYERROR.getCode() != request.getDeliveryStatus()) return false;
        if (StringUtils.isBlank(request.getRemark())) return false;

        List<String> abnormalDesc = Lists.newArrayList("顾客更改配送地址", "顾客更改收货地址", "顾客更改送货地址");
        for (String str : abnormalDesc) {
            if (request.getRemark().contains(str)) {
                log.info("isDeliveryAbnormalAndCustomerChangedAddress.true of {}", JSONObject.toJSONString(request));
                return true;
            }
        }
        return false;
    }

    @Override
    public BaseResponse mallCallbackUrl(CallbackUrlRequestDto request) {
        return ResponseUtil.success();
    }

    @Override
    public BaseResponse<DeliveryAmountVo> queryDeliveryAmount(WeixinDeliveryAddressDto request) {

        QueryDeliveryAmountRequestDto requestDto = new QueryDeliveryAmountRequestDto();
        requestDto.setPartnerId(request.getPartnerId());
        requestDto.setProvince(request.getProvinceName());
        QueryDeliveryAmountResponseDto responseDto = deliveryFeiginClient.queryDeliveryAmount(requestDto);
        if(responseDto == null || SUCCESS_RESPONSE_CODE != responseDto.getCode() || CollectionUtils.isEmpty(responseDto.getData())) {
            return ResponseUtil.error(ResponseResult.DELIVERY_INFO_NOT_DELIVERY);
        }

        DeliveryAmountVo deliveryAmountVo = new DeliveryAmountVo();
        QueryDeliveryAmountResponseDto.QueryDeliveryAmountResult amountResult = responseDto.getData().get(0);
        deliveryAmountVo.setId(amountResult.getId());
        deliveryAmountVo.setPartnerId(amountResult.getPartnerId());
        deliveryAmountVo.setProvinceName(amountResult.getSendProvince());
        deliveryAmountVo.setDeliveryAmount(amountResult.getDeliveryAmount().intValue());
        return ResponseUtil.success(deliveryAmountVo);
    }

    /**
     * 配送单异常取消配送单
     */
    public BaseResponse partnerCancelOrder(String deliveryId) {
        CancelDeliveryOrderRequestDto deliveryOrderRequestDto = new CancelDeliveryOrderRequestDto();
        deliveryOrderRequestDto.setDeliveryId(deliveryId);
        deliveryOrderRequestDto.setOrderCancelCode(4);
        deliveryOrderRequestDto.setOrderCancelDescription("运单异常，商户取消订单");
        String trackingNo = "";
        DeliveryResponseDto responseDto = deliveryService.deliveryOrderCancel(deliveryOrderRequestDto,trackingNo);
        if (SUCCESS_RESPONSE_CODE != responseDto.getCode()) {
            throw new ServiceException(ResponseResult.DELIVERY_CANCEL_ORDER_ERROR);
        }
        return ResponseUtil.success();
    }

    /**
     * 配送订单回调同步POS服务
     */
    public BaseResponse sendPosService(Integer deliveryStatus,PosBaseRequestDto posBaseRequestDto) {
        BaseResponse response = null;
        if (deliveryStatus == DeliveryStatus.ALLOTRIDER.getCode()) {
            response = posClient.deliveryRiderStatus(posBaseRequestDto);
        } else if (deliveryStatus == DeliveryStatus.RIDERGETMEAL.getCode() || deliveryStatus == DeliveryStatus.RIDERSTARTDELIVERY.getCode()) {
            // 告知订单配送
            response = posClient.posSend(posBaseRequestDto);
        } else if (deliveryStatus == DeliveryStatus.DELIVERYARRIVED.getCode()) {
            // 告知订单已完成
            response = posClient.posAffirm(posBaseRequestDto);
        } else if (deliveryStatus == DeliveryStatus.DELIVERYERROR.getCode() || deliveryStatus == DeliveryStatus.DELIVERYCANCEL.getCode()) {
            // 更新订单状态为异常单
            updateDeliveryAbnormal(posBaseRequestDto.getPartner_id(),posBaseRequestDto.getOrder_id(),posBaseRequestDto.getDeliveryId());
        }
        return response;
    }

    /**
     * 更新订单为异常单
     * @param partnerCode
     * @param orderCode
     * @param deliveryId
     */
    private void updateDeliveryAbnormal(String partnerCode, String orderCode, String deliveryId) {
        AssortmentUpdateDeliveryAbnormalRequest request = AssortmentUpdateDeliveryAbnormalRequest.builder()
                .abnormalDesc("配送异常")
                .deliveryId(deliveryId)
                .orderCode(orderCode)
                .partnerId(partnerCode).build();
        orderCenterSdkService.updateDeliveryAbnormal(request);
    }

}
