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.AddressTypeEnum;
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 com.sckw.transport.repository.KwtWaybillOrderSubtaskRepository;
import com.sckw.transport.repository.KwtWaybillOrderTicketRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

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

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

    @Autowired
    private KwtWaybillOrderTicketRepository waybillOrderTicketRepository;
    @Autowired
    private KwtWaybillOrderSubtaskRepository waybillOrderSubtaskRepository;


    @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) {
        List<KwtWaybillOrderTicket> ticketList = waybillOrderTicketRepository.queryByWOrderId(param.getWaybillOrderId());
        // 按 type 分组
        Map<Integer, KwtWaybillOrderTicket> ticketMap = ticketList.stream()
                .collect(Collectors.toMap(KwtWaybillOrderTicket::getType, Function.identity(), (a, b) -> a));
        //1.填充毛重
        updateGrossAmount(param, ticketMap);
        //2.填充装货净重
        updateLoadAmount(param, waybillOrder, ticketMap);
    }

    /**
     * 填充毛重
     * @param param
     * @param ticketMap
     */
    private void updateGrossAmount(WaybillOrderLeaveMockParam param, Map<Integer, KwtWaybillOrderTicket> ticketMap) {
        //查询卸货信息，用于记录毛重
        KwtWaybillOrderTicket takeTicket = ticketMap.get(AddressTypeEnum.TAKE.getCode());
        if (takeTicket == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_TICKET_NOT_FOUND, "当前物流运单装卸货信息不存在，无法记录毛重！");
        }
        takeTicket.setGrossAmount(param.getGrossAmount());
        waybillOrderTicketRepository.updateById(takeTicket);
    }

    /**
     * 填充装货净重
     * @param param
     * @param waybillOrder
     * @param ticketMap
     */
    private void updateLoadAmount(WaybillOrderLeaveMockParam param, KwtWaybillOrder waybillOrder, Map<Integer, KwtWaybillOrderTicket> ticketMap) {
        //查询卸货信息，用于获取皮重
        KwtWaybillOrderTicket shipmentTicket  = ticketMap.get(AddressTypeEnum.SHIPMENT.getCode());
        if (shipmentTicket == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_TICKET_NOT_FOUND, "当前物流运单装卸货信息不存在，无法获取皮重！");
        }
        //皮重
        BigDecimal tareAmount = shipmentTicket.getTareAmount();

        //更新子运单的装货净重
        KwtWaybillOrderSubtask subtask = waybillOrderSubtaskRepository.queryByWOrderId(waybillOrder.getId());
        if (subtask == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_SUB_NOT_FOUND, "未找到关联的子运单！");
        }
        BigDecimal loadAmount = param.getGrossAmount().subtract(Optional.ofNullable(tareAmount).orElse(BigDecimal.ZERO));
        subtask.setLoadAmount(loadAmount);
        subtask.setLoadTime(new Date());
        waybillOrderSubtaskRepository.updateById(subtask);
        log.info("物流运单离场过磅成功！运单ID: {}, 毛重: {}, 皮重: {}, 装货净重: {}", param.getWaybillOrderId(), param.getGrossAmount(), tareAmount, loadAmount);
    }

    @Override
    protected void updateStatus(WaybillOrderLeaveMockParam param, KwtWaybillOrder waybill) {
        // 离场过磅不更新状态
    }

    @Override
    protected String getProcessName() {
        return "离场过磅（计算毛重和净重）";
    }

    @Override
    protected String getRemark(WaybillOrderLeaveMockParam param, KwtWaybillOrder waybillOrder) {
        return "[" + param.getWeighbridgeName() + "]称重[" + param.getGrossAmount() + "吨]";
    }
}
