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.transport.model.KwtWaybillOrder;
import com.sckw.transport.model.KwtWaybillOrderSubtask;
import com.sckw.transport.model.KwtWaybillOrderTicket;
import com.sckw.transport.model.param.WaybillOrderLeaveMockParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.Objects;
import java.util.Optional;

/**
 * Author: donglang
 * Time: 2025-11-19
 * Des: 离场过磅（计算毛重和净重）
 * Version: 1.0
 */

@Slf4j
@Service
public class LeaveMockHandler extends AbstractWaybillOrderHandler<WaybillOrderLeaveMockParam> {

    //用于存储动态状态
    private Integer targetStatus;

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

    @Override
    protected void checkState(WaybillOrderLeaveMockParam param, KwtWaybillOrder waybillOrder) {
        if (!Objects.equals(CarWaybillV1Enum.EXIT_COMPLETED.getCode(), waybillOrder.getStatus())) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "运单状态不是“已装货”状态，无法推进下一节点！");
        }
    }

    @Override
    protected void doBusiness(WaybillOrderLeaveMockParam param, KwtWaybillOrder waybillOrder) {
        KwtWaybillOrderTicket shipmentTicket = waybillOrderTicketRepository.queryByWOrderIdByIdAndType(param.getWaybillOrderId(), 1);
        if (shipmentTicket == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_TICKET_NOT_FOUND, "当前物流运单装卸货信息不存在，无法记录毛重！");
        }
        //1.填充装货单毛重和装货净重
        BigDecimal loadAmount = updateGrossAmount(param, shipmentTicket);
        //2.填充运单装货净重
        updateLoadAmount(param, waybillOrder, loadAmount);
        //3.判断流程
        checkProcess(waybillOrder, loadAmount);
    }

    @Override
    protected void calculateAutoDispatchScore(WaybillOrderLeaveMockParam param, KwtWaybillOrder waybillOrder) {

    }

    /**
     * 填充毛重
     * @param param
     * @param shipmentTicket
     */
    private BigDecimal updateGrossAmount(WaybillOrderLeaveMockParam param, KwtWaybillOrderTicket shipmentTicket) {
        //毛重
        shipmentTicket.setGrossAmount(param.getGrossAmount());
        //皮重
        BigDecimal tareAmount = shipmentTicket.getTareAmount();
        //装货单装货净重
        BigDecimal loadAmount = param.getGrossAmount().subtract(Optional.ofNullable(tareAmount).orElse(BigDecimal.ZERO));
        shipmentTicket.setAmount(loadAmount);
        waybillOrderTicketRepository.updateById(shipmentTicket);
        return loadAmount;
    }

    /**
     * 填充装货净重
     * @param param
     * @param waybillOrder
     * @param loadAmount
     */
    private void updateLoadAmount(WaybillOrderLeaveMockParam param, KwtWaybillOrder waybillOrder, BigDecimal loadAmount) {
        //更新子运单装货净重
        KwtWaybillOrderSubtask subtask = getWaybillSubtask(waybillOrder.getId());
        subtask.setLoadAmount(loadAmount);
        subtask.setLoadTime(new Date());
        waybillOrderSubtaskRepository.updateById(subtask);
        log.info("物流运单离场过磅成功！运单ID: {}, 毛重: {}, 装货净重: {}", param.getWaybillOrderId(), param.getGrossAmount(), loadAmount);
    }

    // 计算并设定离场目标状态
    // 空载离场：净重<=0.5，        状态更改为：空载待离场
    // 正常流程：0.5<净重<=任务量，  状态更改为：待离场
    // 超载流程：净重>任务量，       状态更改为：卸货中
    private void checkProcess(KwtWaybillOrder waybillOrder, BigDecimal loadAmount) {
        //获取运单任务量
        KwtWaybillOrderSubtask waybillSubtask = getWaybillSubtask(waybillOrder.getId());
        if (waybillSubtask.getEntrustAmount() == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.SYSTEM_ERROR, "[称重过磅]子运单任务量信息缺失！");
        }
        BigDecimal entrustAmount = waybillSubtask.getEntrustAmount();

        //场景一：空载离场,净重<=0.5
        if (loadAmount.compareTo(BigDecimal.valueOf(0.5)) <= 0) {
            this.targetStatus = 1;
            return;
        }
        // 场景二：正常流程,0.5<净重<=任务量
        if (loadAmount.compareTo(entrustAmount) <= 0) {
            this.targetStatus = 2;
            return;
        }
        // 场景三：超载流程, 净重>任务量
        this.targetStatus = 3;
    }


    @Override
    protected String getProcessName() {
        return "离场过磅";
    }

    @Override
    protected void getStatus(KwtWaybillOrder waybillOrder) {
        if (this.targetStatus == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.SYSTEM_ERROR, "[称重过磅]数据异常！");
        }
        Integer status =  switch (this.targetStatus) {
            case 1 -> CarWaybillV1Enum.EMPTY_WAIT_LEAVE.getCode();
            case 2 -> CarWaybillV1Enum.WAIT_LEAVE.getCode();
            case 3 -> CarWaybillV1Enum.UNLOADING.getCode();
            default -> -1;
        };

        // 1. 修改运单状态
        waybillOrder.setStatus(status);
        waybillOrderRepository.updateById(waybillOrder);

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

    }


    @Override
    protected String getRemark(WaybillOrderLeaveMockParam param, KwtWaybillOrder waybillOrder) {
        if (this.targetStatus == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.SYSTEM_ERROR, "[离场过磅]数据异常！");
        }
        switch (this.targetStatus) {
            case 1:
                return "司机[" + waybillOrder.getDriverName() + "]已确认空载离场";
            case 2:
                String grossAmount = Objects.isNull(param.getGrossAmount()) ? "0.00" : param.getGrossAmount().setScale(2, RoundingMode.HALF_UP).toPlainString();
                return "[" + param.getWeighbridgeName() + "]称重[" + grossAmount + "吨]";
            case 3:
                return "司机[" + waybillOrder.getDriverName() + "]已超载，卸货中";
            default:
                return "";
        }
    }
}
