package com.clx.performance.listener;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.clx.open.sdk.callback.OpenCallBackClient;
import com.clx.open.sdk.callback.message.OrderChildLastOneMessage;
import com.clx.open.sdk.callback.message.OrderChildMessage;
import com.clx.open.sdk.callback.message.OrderChildSyncMessage;
import com.clx.open.sdk.enums.ResultStatusEnum;
import com.clx.order.enums.OrderEnum;
import com.clx.order.enums.SyncPlatformEnum;
import com.clx.order.feign.OrderFeign;
import com.clx.order.vo.feign.FeignOrderVO;
import com.clx.performance.config.ThirdAppConfig;
import com.clx.performance.constant.RabbitKeyConstants;
import com.clx.performance.dto.dts.DataTransportDTO;
import com.clx.performance.enums.DtsOperationTypeEnum;
import com.clx.performance.enums.OrderChildEnum;
import com.clx.performance.event.OrderChildCancelEvent;
import com.clx.performance.extranal.user.DriverService;
import com.clx.performance.model.OrderChild;
import com.clx.performance.service.LastTruckService;
import com.clx.user.vo.feign.FeignDriverTruckModelVo;
import com.msl.common.enums.ResultCodeEnum;
import com.msl.common.result.Result;
import com.msl.common.utils.DtsMapConvertUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.Optional;

@Slf4j
@Component
@AllArgsConstructor
public class OrderChildDtsListener  {
    private final OrderFeign orderFeign;
    private final LastTruckService lastTruckService;
    private final DriverService driverService;
    private final ApplicationEventPublisher applicationEventPublisher;
    private final ThirdAppConfig thirdAppConfig;



    @RabbitListener(queues = RabbitKeyConstants.CLX_PERFORMANCE_ORDER_CHILD_QUEUE)
    public void onMessage(Message message) {
        try {
            String msg = new String(message.getBody());
            log.info("DTS消息同步开始, database:clx_performance.order_child, msg:{}", msg);
            DataTransportDTO dataTransportDTO = JSON.parseObject(msg, DataTransportDTO.class);
            log.info("DTS消息同步开始, database:clx_performance.order_child, 实体:{}", dataTransportDTO);
            log.info("操作类型：{}",dataTransportDTO.getOperationType().getCode());
            OrderChildMessage before = DtsMapConvertUtil.convert(dataTransportDTO.getBeforeMap(), new OrderChildMessage());
            OrderChildMessage after = DtsMapConvertUtil.convert(dataTransportDTO.getAfterMap(), new OrderChildMessage());

            thirdpartySync(DtsMapConvertUtil.convert(dataTransportDTO.getAfterMap(), new OrderChildSyncMessage()));

            if(Objects.equals(DtsOperationTypeEnum.INSERT.getCode(),dataTransportDTO.getOperationType().getCode())){
                //同步after数据
                log.info("新增:{}",after);
                if(OrderChildEnum.SYNC_STATUS_lIST.contains(after.getStatus()) && !Objects.equals(before.getStatus(),after.getStatus())){
                    orderChildChangeAfter(after);
                }
            }else if(Objects.equals(DtsOperationTypeEnum.UPDATE.getCode(),dataTransportDTO.getOperationType().getCode())){
                log.info("修改:{}",after);
                if(OrderChildEnum.SYNC_STATUS_lIST.contains(after.getStatus()) &&
                        (!Objects.equals(before.getStatus(),after.getStatus()) ||
                         !Objects.equals(before.getLoadNet(),after.getLoadNet())) ||
                         !Objects.equals(before.getUnloadNet(),after.getUnloadNet())
                        ){
                    orderChildChangeAfter(after);
                }
                if(OrderChildEnum.DTS_LISTEN_CANCEL_lIST.contains(after.getStatus())){
                    //运单取消释放借款冻结金额
                    log.info("DTS运单取消释放借款冻结金额");
                    applicationEventPublisher.publishEvent(new OrderChildCancelEvent(this, after.getChildNo()));
                }

            }else if(Objects.equals(DtsOperationTypeEnum.DELETE.getCode(),dataTransportDTO.getOperationType().getCode())){
                //数据删除
                log.info("删除:{}",before);

            }
        } catch (Exception e) {
            log.info("DTS消息同步失败, database:clx_performance.order_child, error:{}", e.getMessage());
        }
    }

    public void orderChildChangeAfter(OrderChildMessage after){
        FeignOrderVO orderInfoFeign = orderFeign.getOrderInfoFeign(after.getOrderNo());
        if (orderInfoFeign == null) {
            return;
        }
        //同步交易平台的运单
        if(Objects.equals(orderInfoFeign.getOrderSource(), SyncPlatformEnum.Source.TRADE_PLATFORM.getCode())){

            String truckModel = after.getTruckModel();
            if(StringUtils.isNotBlank(truckModel)){
                FeignDriverTruckModelVo dumpType = driverService.getDumpType(truckModel).orElseThrow(ResultCodeEnum.FAIL);
                after.setDumpType(dumpType.getDumpType());
            }
            //同步after数据
            Optional<OrderChildEnum.Status> option = OrderChildEnum.Status.getByCode(after.getStatus());
            String statusName = option.isPresent()?option.get().getName():"未知状态";
            log.info("同步运单数据，运单号:{},运单状态:{}",after.getChildNo(),statusName);
            //如果订单是取消操作，同步给交易平台统一 10000 的code
            if(OrderChildEnum.DTS_LISTEN_CANCEL_lIST.contains(after.getStatus())){
                after.setStatus(com.clx.open.sdk.enums.OrderChildEnum.Status.COMMON_CANCEL.getCode());
            }
            after.setLastFlag(ResultStatusEnum.NO.getCode());
            String data = JSON.toJSONString(after);
            OpenCallBackClient openCallBackClient = thirdAppConfig.getOpenCallBackClient(orderInfoFeign.getOrderSource().toString());
            Result<?> result = openCallBackClient.encryptPost(data,after.topic());
            log.info("运单信息同步，运单编号:{},响应结果:{}",after.getChildNo(),JSON.toJSONString(result));
            syncLastTruck(orderInfoFeign,after);
            return;
        }

        if (Objects.equals(orderInfoFeign.getOrderSource(), SyncPlatformEnum.Source.NEW_OWNER_CLIENT.getCode())) {
            if(Objects.equals(com.clx.open.sdk.enums.OrderChildEnum.Status.COMMON_CANCEL.getCode(),after.getStatus()) ||
                    (after.getStatus() >= OrderChildEnum.Status.ARRIVE_RECEIVE.getCode()  && after.getStatus() <= OrderChildEnum.Status.COMPLETE.getCode())){
                OrderChild child;
                if(Objects.equals(orderInfoFeign.getOrderStatus(), OrderEnum.Status.COMPLETED.getCode()) ||
                        Objects.equals(orderInfoFeign.getOrderStatus(), OrderEnum.Status.SUCCESS.getCode())) { //订单变成已完成 || 已完结
                    OrderEnum.Status byCode = OrderEnum.Status.getByCode(orderInfoFeign.getOrderStatus());
                    log.info("订单号:{},运单号：{},订单状态：{},开始查询最后一车运单===========" ,orderInfoFeign.getOrderNo(),after.getChildNo(),
                            Objects.nonNull(byCode)?byCode.getName():"未知状态");
                    child = lastTruckService.getOrderCompleteLastTruck(after.getOrderNo());
                }else{  // 订单除  已完成 || 已完结  外的其他状态
                    child = lastTruckService.getLastTruckChild(after.getOrderNo());
                }
                if (Objects.nonNull(child)) {
                    log.info("开始同步新货主客户端最后一车的运单，运单编号:{}", child.getChildNo());
                    OpenCallBackClient openCallBackClient = thirdAppConfig.getOpenCallBackClient(SyncPlatformEnum.Source.NEW_OWNER_CLIENT.getCode().toString());
                    OrderChildLastOneMessage message = new OrderChildLastOneMessage();
                    message.setChildNo(child.getChildNo());
                    Result<?> result = openCallBackClient.encryptPost(JSONUtil.parse(message).toString(), message.topic());
                    log.info("结束同步新货主客户端最后一车的运单，运单编号:{}，响应结果:{}", child.getChildNo(), JSONUtil.parse(result));
                }

            }
        }
    }

    public void syncLastTruck(FeignOrderVO orderInfoFeign,OrderChildMessage after){
        //当运单状态为到达目的地之后的状态时候，需要判断最后一车的逻辑
        if(Objects.equals(com.clx.open.sdk.enums.OrderChildEnum.Status.COMMON_CANCEL.getCode(),after.getStatus()) ||
                (after.getStatus() >= OrderChildEnum.Status.ARRIVE_RECEIVE.getCode()  && after.getStatus() <= OrderChildEnum.Status.COMPLETE.getCode())){
            OrderChild child;
            if(Objects.equals(orderInfoFeign.getOrderStatus(), OrderEnum.Status.COMPLETED.getCode()) ||
                    Objects.equals(orderInfoFeign.getOrderStatus(), OrderEnum.Status.SUCCESS.getCode())) { //订单变成已完成 || 已完结
                OrderEnum.Status byCode = OrderEnum.Status.getByCode(orderInfoFeign.getOrderStatus());
                log.info("订单号:{},运单号：{},订单状态：{},开始查询最后一车运单===========" ,orderInfoFeign.getOrderNo(),after.getChildNo(),
                        Objects.nonNull(byCode)?byCode.getName():"未知状态");
                child = lastTruckService.getOrderCompleteLastTruck(after.getOrderNo());
            }else{  // 订单除  已完成 || 已完结  外的其他状态
                child = lastTruckService.getLastTruckChild(after.getOrderNo());
            }
            if(Objects.nonNull(child)){
                lastTruckService.syncLastTruckChild(child);
            }

        }
    }

    /**
     * 第三方同步
     */
    public void thirdpartySync(OrderChildSyncMessage message){
        FeignOrderVO orderInfoFeign = orderFeign.getOrderInfoFeign(message.getOrderNo());
        if (orderInfoFeign == null) {
            return;
        }
        // 同步新货主客户端的运单
        if(!Objects.equals(orderInfoFeign.getOrderSource(), SyncPlatformEnum.Source.NEW_OWNER_CLIENT.getCode())){
            return;
        }

        try{
            OpenCallBackClient openCallBackClient = thirdAppConfig.getOpenCallBackClient(SyncPlatformEnum.Source.NEW_OWNER_CLIENT.getCode().toString());
            log.info("运单同步:{}", message.getId());
            Result<?> result = openCallBackClient.encryptPost(JSON.toJSONString(message), message.topic());
            if (result.succeed()) {
                log.info("运单同步成功:{}", message.getId());


            }else{
                log.info("运单同步失败:{}", message.getId());
            }

        }catch (Exception e){

        }

    }

}
