package com.sckw.transport.handler;


import com.sckw.core.common.enums.enums.ErrorCodeEnum;
import com.sckw.core.exception.BusinessPlatfromException;
import com.sckw.core.model.enums.CarWaybillV1Enum;
import com.sckw.core.model.enums.GatekeeperStatusEnum;
import com.sckw.core.model.enums.GatekeeperTypeEnum;
import com.sckw.core.utils.DateUtils;
import com.sckw.fleet.api.model.vo.DriverConductRulesVO;
import com.sckw.order.api.model.OrderDetailVo;
import com.sckw.order.api.model.UpdateActualAmountParam;
import com.sckw.transport.model.*;
import com.sckw.transport.model.param.WaybillOrderCancelParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * Author: donglang
 * Time: 2025-11-19
 * Des: 取消
 * Version: 1.0
 */

@Slf4j
@Service
@RequiredArgsConstructor
public class CancelHandler extends AbstractWaybillOrderHandler<WaybillOrderCancelParam>{


    @Override
    protected KwtWaybillOrder getWaybillOrder(WaybillOrderCancelParam param) {
        return getWaybillOrder(param.getWaybillOrderId());
    }

    @Override
    protected void checkState(WaybillOrderCancelParam param, KwtWaybillOrder waybill) {
        if (!Objects.equals(CarWaybillV1Enum.PENDING_VEHICLE.getCode(), waybill.getStatus())) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "当前物流运单状态不是“已接单”状态，无法取消接单！");
        }
    }

    @Override
    protected void doBusiness(WaybillOrderCancelParam param, KwtWaybillOrder waybill) {
        //1.获取子运单任务量
        KwtWaybillOrderSubtask subtask = getWaybillSubtask(waybill.getId());
        BigDecimal entrustAmount = subtask.getEntrustAmount();

        //2.更新上游订单：更新物流订单运输量
        KwtLogisticsOrder logOrder = updateLogOrder(param, entrustAmount);

        //3.解绑车辆
        unbindTruck(subtask.getWOrderId());

        //4.更新上游订单：更新贸易订单运输量
//        updateTradeOrder(logOrder, entrustAmount);

        //5.取消门卫订单
        cancelGatekeeperStatus(waybill);

    }

    /**
     * 更新上游物流订单 - 减运输量
     * @param param
     * @param entrustAmount
     * @return
     */
    private KwtLogisticsOrder updateLogOrder(WaybillOrderCancelParam param, BigDecimal entrustAmount) {
        KwtLogisticsOrder logOrder = logisticsOrderRepository.queryByLogisticsOrderId(param.getLogOrderId());
        if (logOrder == null) {
            log.info("当前物流运单无关联物流订单数据：{}", param.getLogOrderId());
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_NOT_LOG_ORDER, "当前物流运单无关联物流订单数据！");
        }
        //取消接单的物流订单的总运输量不能为空
        if (logOrder.getEntrustAmount() == null || logOrder.getEntrustAmount().compareTo(BigDecimal.ZERO) <= 0) {
            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_AMOUNT_ERROR, "已接单物订单的总运单量不能为空或0！");
        }

        logOrder.setEntrustAmount(logOrder.getEntrustAmount().subtract(entrustAmount));
        logisticsOrderRepository.updateById(logOrder);

        log.info("更新上游物流订单运输量成功, 物流订单ID：{}", logOrder.getId());
        return logOrder;
    }

    /**
     * 解绑车辆
     * @param wOrderId
     */
    private void unbindTruck(Long wOrderId) {
        //查询运单运单信息
        KwtWaybillOrder waybillOrder = getWaybillOrder(wOrderId);
        remoteFleetService.unbindTruck(waybillOrder.getEntId(), waybillOrder.getDriverId());
        log.info("解绑完成，解绑司机与车辆关系，运单id：{},企业id:{},司机id：{}", wOrderId, waybillOrder.getEntId(), waybillOrder.getDriverId());
    }

    /**
     * 更新上游贸易订单 - 减运输量
     * @param logOrder
     * @param entrustAmount
     */
    private void updateTradeOrder(KwtLogisticsOrder logOrder, BigDecimal entrustAmount) {
        OrderDetailVo tradeOrder = tradeOrderInfoService.queryByTradeOrderId(logOrder.getTOrderId());
        //取消接单的物流订单的总运输量不能为空
        if (tradeOrder.getActualAmount() == null || tradeOrder.getActualAmount().compareTo(BigDecimal.ZERO) <= 0) {
            throw new BusinessPlatfromException(ErrorCodeEnum.TRADE_ORDER_AMOUNT_ERROR, "已接单交易订单的总运输量不能为空或0！");
        }

        UpdateActualAmountParam tradeParam = new UpdateActualAmountParam();
        tradeParam.setTOrderId(tradeOrder.getId());
        tradeParam.setActualLoadAmount(tradeOrder.getActualAmount().subtract(entrustAmount));
        tradeOrderInfoService.updateOrderActualAmount(tradeParam);
        log.info("更新上游贸易订单运输量成功, 贸易订单ID：{}", tradeOrder.getId());
    }


    /**
     * 取消门卫订单
     * @param waybill
     */
    private void cancelGatekeeperStatus(KwtWaybillOrder waybill) {
        KwtGatekeeperWaybillOrder gatekeeperWaybillOrder = gatekeeperWaybillOrderRepository
                .queryGatekeeperWaybillOrderByWOrderId(waybill.getId(), GatekeeperTypeEnum.LOADING.getCode());
        if (gatekeeperWaybillOrder == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.GATEKEEPER_ORDER_NOT_FOUND, "门卫订单不存在！");
        }
        if (!GatekeeperStatusEnum.PENDING_ENTRY.getCode().equals(gatekeeperWaybillOrder.getStatus())) {
            throw new BusinessPlatfromException(ErrorCodeEnum.GATEKEEPER_ORDER_STATUS_ERROR, "门卫状态异常，不能取消订单！");
        }

        gatekeeperWaybillOrder.setStatus(GatekeeperStatusEnum.CANCEL.getCode());
        gatekeeperWaybillOrderRepository.updateById(gatekeeperWaybillOrder);
    }

    @Override
    protected String getProcessName() {
        return "取消接单";
    }

    @Override
    protected void getStatus(KwtWaybillOrder waybillOrder) {
        // 1. 修改运单状态
        waybillOrder.setStatus(CarWaybillV1Enum.CANCELLED.getCode());
        waybillOrder.setOpened(1);
        waybillOrderRepository.updateById(waybillOrder);

        // 2. 修改子运单状态
        KwtWaybillOrderSubtask waybillSubtask = getWaybillSubtask(waybillOrder.getId());
        waybillSubtask.setStatus(CarWaybillV1Enum.CANCELLED.getCode());
        waybillOrderSubtaskRepository.updateById(waybillSubtask);
    }

    @Override
    protected String getRemark(WaybillOrderCancelParam param, KwtWaybillOrder waybillOrder) {
        return "司机[" + waybillOrder.getDriverName() + "]取消订单";
    }

    /**
     * 校验司机是否违规取消运单
     * @param param
     * @param waybillOrder
     */
    @Override
    protected void calculateAutoDispatchScore(WaybillOrderCancelParam param, KwtWaybillOrder waybillOrder) {
        //供应商
        Long supEntId = getSupplierId(waybillOrder);
        // 获取司机行为规则配置
        DriverConductRulesVO driverRulesVO = getDriverConductRulesByEntId(supEntId);
        //分数
        Integer cancelOrderScore = driverRulesVO.getIllegalCancelOrderScore();
        //分钟数
        Integer cancelOrderMinutes = driverRulesVO.getIllegalCancelOrderMinutes();
        if (cancelOrderScore <= 0 || cancelOrderMinutes<= 0) {
            log.warn("【司机违规取消运单】企业{}的司机违规取消运单分钟数/分数异常，运单ID：{}", supEntId, waybillOrder.getId());
            throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "【司机违规取消运单】配置的分钟数/分数需大于0!");
        }
        //司机接单时间
        KwtWaybillOrderNode takingOrderNodes = getNodesByOrderId(waybillOrder.getId(), CarWaybillV1Enum.PENDING_VEHICLE.getCode());
        Date takingOrderTime = takingOrderNodes.getCreateTime();
        //司机取消接单时间
        KwtWaybillOrderNode cancelNode = getNodesByOrderId(waybillOrder.getId(), CarWaybillV1Enum.CANCELLED.getCode());
        Date cancelNodeTime = cancelNode.getCreateTime();

        // 计算两个时间的秒差
        Long timeDiffMinutes = DateUtils.calculateTimeDiffMinutes(takingOrderTime, cancelNodeTime);
        if (timeDiffMinutes > TimeUnit.MINUTES.toSeconds(cancelOrderMinutes)) {
            log.info("【司机违规取消运单】超时！司机违规取消运单分钟数限制：" + cancelOrderMinutes + "分钟，实际：" + timeDiffMinutes + "分钟");
            //1、更新司机分数（减分）
            cancelOrderScore = -Math.abs(cancelOrderScore);
            updateDriverScore(supEntId, waybillOrder.getEntId(), waybillOrder.getDriverId(), cancelOrderScore, "司机违规取消运单");

            //2、更新企业分数（减分）
            updateLogEntScore(waybillOrder, supEntId, cancelOrderScore, "司机违规取消运单");
        }

    }


}
