package com.wms_main.service.controller.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.wms_main.constant.enums.wcs.WcsStackerTaskStatusEnums;
import com.wms_main.constant.enums.wms.*;
import com.wms_main.dao.*;
import com.wms_main.model.dto.request.wcs.WcsTaskResultRequest;
import com.wms_main.model.dto.request.wcs.WcsVehicleInRequest;
import com.wms_main.model.dto.response.wcs.BaseWcsApiResponse;
import com.wms_main.model.dto.response.wcs.WcsVehicleInResponse;
import com.wms_main.model.po.*;
import com.wms_main.repository.utils.ConvertUtils;
import com.wms_main.repository.utils.StringUtils;
import com.wms_main.repository.utils.UUIDUtils;
import com.wms_main.service.business.IStackerTaskService;
import com.wms_main.service.controller.ITaskControllerService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 任务控制类 服务实现
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class TaskControllerServiceImpl implements ITaskControllerService {
    private final ITAppTaskService appWmsTaskService;
    private final ITAppWcsTaskService appWcsTaskService;// wcs任务服务
    private final IStackerTaskService stackerTaskService;// 堆垛机任务服务
    private final ITAppOrderInService orderInService;
    private final ITAppWcsTaskBakService appWcsTaskBakService;

    @Override
    @Transactional
    public WcsVehicleInResponse requireInTask(WcsVehicleInRequest request) {
        String vehicleNo = request.getVehicleNo();
        String origin = request.getOrigin();
        String inboundPort = "R1"; // 默认入库口
        
        log.info("收到入库请求 - 载具号: {}, 来源: {}, 入库口: {}", 
                vehicleNo, origin, inboundPort);
        
        TAppOrderIn orderIn = orderInService.getOne(
                new LambdaQueryWrapper<TAppOrderIn>()
                        .eq(StringUtils.isNotEmpty(vehicleNo), TAppOrderIn::getVehicleNo, vehicleNo)
                        .eq(TAppOrderIn::getOrderStatus, OrderStatusEnum.CREATE.getCode())
        );
        if (orderIn == null) {
            return WcsVehicleInResponse.error(String.format("条码：%s 不存在待入库的订单", vehicleNo));
        }

        /* 查找可用库位 */
        TAppLocation useLocation = stackerTaskService.requestOneLocation(null, vehicleNo);
        if (useLocation == null) {
            return WcsVehicleInResponse.error("暂没有可以直接使用的库位，因为存在互锁的库位，请等待当前任务都执行完成后再试");
        }
        TAppTask newInTask = appWmsTaskService.getOne(new LambdaQueryWrapper<TAppTask>()
                .eq(TAppTask::getVehicleId, vehicleNo)
                .eq(TAppTask::getTaskType, WmsTaskTypeEnums.IN.getCode()));
        if (newInTask != null) {
            newInTask.setTaskStatus(WmsStackerTaskStatusEnums.WAIT.getCode());
            newInTask.setDestination(useLocation.getLocationId());
            newInTask.setTaskGroup(orderIn.getOrderId());
            if (!appWmsTaskService.updateById(newInTask)) {
                return WcsVehicleInResponse.error("生成任务失败，无法插入新的入库任务");
            }
        } else {
            newInTask = new TAppTask();
            newInTask.setTaskId(UUIDUtils.getNewUUID());
            newInTask.setTaskGroup(orderIn.getOrderId());
            newInTask.setTaskType(WmsTaskTypeEnums.IN.getCode());
            newInTask.setTaskStatus(WmsStackerTaskStatusEnums.WAIT.getCode());
            newInTask.setOrigin(request.getOrigin());
            newInTask.setDestination(useLocation.getLocationId());
            newInTask.setCreateTime(LocalDateTime.now());
            newInTask.setOpUser("wcs");
            newInTask.setVehicleId(vehicleNo);
            newInTask.setTaskPriority(1);

            if (!appWmsTaskService.save(newInTask)) {
                return WcsVehicleInResponse.error("生成任务失败，无法插入新的入库任务");
            }
        }
        orderInService.update(
                new LambdaUpdateWrapper<TAppOrderIn>()
                        .eq(TAppOrderIn::getRecordId, orderIn.getRecordId())
                        .set(TAppOrderIn::getOrderStatus, OrderStatusEnum.RUNNING.getCode())
                        .set(TAppOrderIn::getUpdateTime, LocalDateTime.now())
        );

        WcsVehicleInResponse success = new WcsVehicleInResponse();
        success.setCode("200");
        success.setMessage("生成并箱入库任务成功");
        success.setWmsTaskId(newInTask.getTaskId());
        success.setVehicleNo(vehicleNo);
        success.setOrigin(request.getOrigin());
        success.setDestination(useLocation.getLocationId());
        return success;
    }


    /**
     * 实现
     *
     * @param wcsTaskResultRequest 请求信息
     * @return 响应信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseWcsApiResponse sendTaskResult(WcsTaskResultRequest wcsTaskResultRequest) {
        if (StringUtils.isEmpty(wcsTaskResultRequest.getTaskId()) || wcsTaskResultRequest.getTaskStatus() == null) {
            return BaseWcsApiResponse.error("请求缺少关键信息：任务号、任务状态。");
        }
        // 查询对应的wcs任务
        TAppWcsTask wcsTask = appWcsTaskService.getOne(
                new LambdaQueryWrapper<TAppWcsTask>()
                        .eq(TAppWcsTask::getWcsTaskId, wcsTaskResultRequest.getTaskId())
        );
        if (wcsTask == null) {
            return BaseWcsApiResponse.error("未找到对应的wcs任务。");
        }
        // 转换堆垛机任务状态
        int wmsTaskStatus = ConvertUtils.convertWcsStackerTaskStatusToWmsTaskStatus(wcsTaskResultRequest.getTaskStatus());
        if (wmsTaskStatus == -1) {
            return BaseWcsApiResponse.error("反馈的任务状态值无效。");
        }
        // 判断反馈的任务状态是否是「已完成」
        if (Objects.equals(wcsTaskResultRequest.getTaskStatus(), WcsStackerTaskStatusEnums.FINISH.getCode())) {
            // 更新wms任务状态
            appWmsTaskService.update(
                    new LambdaUpdateWrapper<TAppTask>()
                            .set(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.FINISH.getCode())
                            .set(TAppTask::getFinishTime, LocalDateTime.now())
                            .eq(TAppTask::getWcsTaskId, wcsTaskResultRequest.getTaskId())
            );
            TAppTask wmsTask = appWmsTaskService.getOne(new LambdaQueryWrapper<TAppTask>().eq(TAppTask::getWcsTaskId, wcsTaskResultRequest.getTaskId()));
            orderInService.update(new LambdaUpdateWrapper<TAppOrderIn>()
                    .eq(TAppOrderIn::getOrderId, wmsTask.getTaskGroup())
                    .set(TAppOrderIn::getOrderStatus, OrderStatusEnum.COMPLETE.getCode())
                    .set(TAppOrderIn::getCompleteTime, LocalDateTime.now()));

            // 移除wcs任务，并向wcs备份表添加记录
            TAppWcsTaskBak wcsTaskBak = new TAppWcsTaskBak(
                    wcsTask.getWcsTaskId(),
                    wcsTask.getWcsTaskStatus(),
                    wcsTask.getWcsTaskType(),
                    wcsTask.getTaskPriority(),
                    wcsTask.getVehicleId(),
                    wcsTask.getOrigin(),
                    wcsTask.getDestination(),
                    wcsTask.getCreateTime(),
                    wcsTask.getSendTime(),
                    wcsTask.getFinishTime(),
                    wcsTask.getRemark()
            );
            appWcsTaskService.removeById(wcsTask.getWcsTaskId());
            appWcsTaskBakService.save(wcsTaskBak);
        } else {
            // 更新wms任务状态
            appWmsTaskService.update(
                    new LambdaUpdateWrapper<TAppTask>()
                            .set(TAppTask::getTaskStatus, wmsTaskStatus)
                            .eq(TAppTask::getWcsTaskId, wcsTaskResultRequest.getTaskId())
            );
            // 更新wcs任务状态
            appWcsTaskService.update(
                    new LambdaUpdateWrapper<TAppWcsTask>()
                            .set(TAppWcsTask::getWcsTaskStatus, wcsTaskResultRequest.getTaskStatus())
                            .eq(TAppWcsTask::getWcsTaskId, wcsTaskResultRequest.getTaskId())
            );
        }
        return BaseWcsApiResponse.success("处理任务状态反馈成功。");
    }
}
