package com.clx.performance.listener;

import com.alibaba.fastjson.JSON;
import com.clx.order.enums.UpdateEnum;
import com.clx.order.enums.VehicleUsageEnum;
import com.clx.performance.common.MqWrapper;
import com.clx.performance.component.GoodsOrderTruckRecordComponent;
import com.clx.performance.component.OrderCancelComponent;
import com.clx.performance.constant.RabbitKeyConstants;
import com.clx.performance.dao.OrderGoodsDao;
import com.clx.performance.dto.dts.DataTransportDTO;
import com.clx.performance.enums.DtsOperationTypeEnum;
import com.clx.performance.enums.OrderGoodsLogsEnum;
import com.clx.performance.enums.OrderGoodsPendingOrderWayStatusEnum;
import com.clx.performance.enums.OrderGoodsStatusEnum;
import com.clx.performance.model.OrderGoods;
import com.clx.performance.model.OrderGoodsAdjustmentPrice;
import com.clx.performance.service.OrderGoodsLogService;
import com.msl.common.utils.DtsMapConvertUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Objects;

import static com.clx.performance.constant.RabbitKeyConstants.*;

@Slf4j
@Component
@AllArgsConstructor
public class OrderGoodsDtsListener {

    private final OrderCancelComponent orderCancelComponent;
    private final GoodsOrderTruckRecordComponent goodsOrderTruckRecordComponent;
    private final OrderGoodsDao orderGoodsDao;
    private final OrderGoodsLogService orderGoodsLogService;
    private final RabbitTemplate rabbitTemplate;


    @RabbitListener(queues = RabbitKeyConstants.CLX_PERFORMANCE_ORDER_GOODS_QUEUE)
    public void onMessage(Message message) {
        try {
            String msg = new String(message.getBody());
            log.info("DTS消息同步开始, database:clx_performance.order_goods, msg:{}", msg);
            DataTransportDTO dataTransportDTO = JSON.parseObject(msg, DataTransportDTO.class);
            OrderGoods before = DtsMapConvertUtil.convert(dataTransportDTO.getBeforeMap(), new OrderGoods());
            OrderGoods after = DtsMapConvertUtil.convert(dataTransportDTO.getAfterMap(), new OrderGoods());
            if(Objects.equals(DtsOperationTypeEnum.INSERT.getCode(),dataTransportDTO.getOperationType().getCode())){
                //同步after数据
                log.info("新增:{}",JSON.toJSONString(after));
                syncPerformanceProgress(before,after,DtsOperationTypeEnum.INSERT.getCode());
                sendSaveOrderGoodsAdjustmentPriceMessage(before,after,DtsOperationTypeEnum.INSERT.getCode());
            }else if(Objects.equals(DtsOperationTypeEnum.UPDATE.getCode(),dataTransportDTO.getOperationType().getCode())){
                log.info("修改:{}",JSON.toJSONString(after));
                backFillOrderWeight(after);
                syncPerformanceProgress(before,after,DtsOperationTypeEnum.UPDATE.getCode());
                sendSaveOrderGoodsAdjustmentPriceMessage(before,after,DtsOperationTypeEnum.UPDATE.getCode());
            }else if(Objects.equals(DtsOperationTypeEnum.DELETE.getCode(),dataTransportDTO.getOperationType().getCode())){
                //数据删除
                log.info("删除:{}",JSON.toJSONString(before));
            }
        } catch (Exception e) {
            log.info("DTS消息同步失败, database:clx_performance.order_goods, error:{}", e.getMessage());
        }
    }

    //货单剩余吨数不足35吨，自动恢复吨数到订单上
    public void backFillOrderWeight(OrderGoods after){
        //剩余吨数小于35吨并且大于0，自动归还订单上
        if(new BigDecimal("35").compareTo(after.getResidueTransportWeight()) > 0 &&
                after.getResidueTransportWeight().compareTo(BigDecimal.ZERO) > 0){
            log.info("开始自动恢复吨数到订单,订单号:{},货单号:{},货单剩余吨数:{}",
                    after.getOrderNo(),after.getOrderGoodsNo(),after.getResidueTransportWeight());
            orderCancelComponent.backFillOrderWeight(after,after.getResidueTransportWeight(), UpdateEnum.ADD.getCode());
            OrderGoods orderGoods = new OrderGoods();
            orderGoods.setId(after.getId());
            orderGoods.setResidueTransportWeight(BigDecimal.ZERO);
            orderGoodsDao.updateEntityByKey(orderGoods);
            orderGoodsLogService.saveLog(after.getOrderGoodsNo(), 0L, "系统", OrderGoodsLogsEnum.Type.SYSTEM_RELEASE.getName(),
                    String.format("系统自动释放：%s吨", after.getResidueTransportWeight()));
            //释放定向单(非自由车辆)对应的定向车辆
            if( (  Objects.equals(after.getPendingOrderWay(), OrderGoodsPendingOrderWayStatusEnum.Status.EXCLUSIVE.getCode())
                || Objects.equals(after.getPendingOrderWay(), OrderGoodsPendingOrderWayStatusEnum.Status.FLEET_EXCLUSIVE.getCode()) )
            && !Objects.equals(after.getVehicleUsage(), VehicleUsageEnum.Status.OWN.getCode())){
                goodsOrderTruckRecordComponent.releaseOrderGoodsDriverAndTruck(after.getOrderGoodsNo());
            }
            log.info("结束自动恢复吨数到订单,订单号:{},货单号:{},货单剩余吨数:{}",
                    after.getOrderNo(),after.getOrderGoodsNo(),after.getResidueTransportWeight());
        }
    }


    public void syncPerformanceProgress(OrderGoods before,OrderGoods after, Integer updateType) {
        boolean isSend = false;
        if(after.getOrderGoodsStatus() >= OrderGoodsStatusEnum.Status.PAYING.getCode()){
            if(Objects.equals(updateType,DtsOperationTypeEnum.INSERT.getCode())){
                isSend = true;
            }
            if(Objects.equals(updateType,DtsOperationTypeEnum.UPDATE.getCode())
            && (!Objects.equals(before.getOrderGoodsStatus(),after.getOrderGoodsStatus())
                || !Objects.equals(before.getSeniorLogisticsManagerId(),after.getSeniorLogisticsManagerId())
                || !Objects.equals(before.getPendingOrderFreight(),after.getPendingOrderFreight())
            )){
                isSend = true;
            }
            if(isSend){
                log.info("开始发送同步履约进度表消息,订单号:{},货单号:{}", after.getOrderNo(),after.getOrderGoodsNo());
                Message body = MessageBuilder.withBody(JSON.toJSONString(new MqWrapper<>(after)).getBytes()).build();
                rabbitTemplate.send(SYNC_PERFORMANCE_PROGRESS_FOR_ORDER_GOODS_EXCHANGE,
                        SYNC_PERFORMANCE_PROGRESS_FOR_ORDER_GOODS_ROUTING_KEY, body);
                log.info("结束发送同步履约进度表消息,订单号:{},货单号:{}", after.getOrderNo(),after.getOrderGoodsNo());
            }
        }
    }

    //保存货单调价记录
    public void sendSaveOrderGoodsAdjustmentPriceMessage(OrderGoods before,OrderGoods after, Integer updateType){
        boolean isSend = false;
        //插入的货单是挂单中状态的
        if(Objects.equals(updateType,DtsOperationTypeEnum.INSERT.getCode()) &&
                Objects.equals(after.getOrderGoodsStatus(),OrderGoodsStatusEnum.Status.PAYING.getCode())){
            isSend = true;
        }
        //货单状态发生变化(从已挂单变成挂单中)  ||  挂单中状态的挂单运费发生变化
        if(Objects.equals(updateType,DtsOperationTypeEnum.UPDATE.getCode()) &&
             //货单状态发生变化(从已挂单变成挂单中)
            (
                (Objects.equals(before.getOrderGoodsStatus(),OrderGoodsStatusEnum.Status.CREATED.getCode()) &&
                 Objects.equals(after.getOrderGoodsStatus(),OrderGoodsStatusEnum.Status.PAYING.getCode()))
            ||     //挂单中之后的状态的挂单运费发生变化
                (after.getOrderGoodsStatus() >= OrderGoodsStatusEnum.Status.PAYING.getCode() &&
                 !Objects.equals(before.getPendingOrderFreight(),after.getPendingOrderFreight()))
            )
        ){
            isSend = true;
        }


        if(isSend){
            log.info("开始发送货单调整挂单运费消息,订单号:{},货单号:{}", after.getOrderNo(),after.getOrderGoodsNo());
            OrderGoodsAdjustmentPrice message = new OrderGoodsAdjustmentPrice();
            message.setOrderNo(after.getOrderNo());
            message.setOrderGoodsNo(after.getOrderGoodsNo());
            message.setAmount(after.getPendingOrderFreight());
            message.setPreAmount(Objects.nonNull(before) ? before.getPendingOrderFreight() : BigDecimal.ZERO);
            Message body = MessageBuilder.withBody(JSON.toJSONString(new MqWrapper<>(message)).getBytes()).build();
            rabbitTemplate.send(SAVE_ORDER_GOODS_ADJUSTMENT_PRICE_EXCHANGE,
                    SAVE_ORDER_GOODS_ADJUSTMENT_PRICE_ROUTING_KEY, body);
            log.info("结束发送货单调整挂单运费消息,订单号:{},货单号:{}", after.getOrderNo(),after.getOrderGoodsNo());
        }
    }

}
