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.app.AppCommon;
import com.wms_main.constant.AppConstant;
import com.wms_main.constant.enums.wcs.WcsStackerTaskStatusEnums;
import com.wms_main.constant.enums.wcs.WcsStackerTaskTypeEnums;
import com.wms_main.constant.enums.wms.*;
import com.wms_main.dao.*;
import com.wms_main.model.bo.wcs.WcsStackerTask;
import com.wms_main.model.bo.wms.GoodsInfoForTask;
import com.wms_main.model.bo.wms.StockConfirmEntity;
import com.wms_main.model.bo.wms.TaskConfirmEntity;
import com.wms_main.model.bo.wms.WmsPickTask;
import com.wms_main.model.dto.request.wcs.WcsBoxArriveRequest;
import com.wms_main.model.dto.request.wcs.WcsTaskResultRequest;
import com.wms_main.model.dto.request.wcs.WcsVehicleInRequest;
import com.wms_main.model.dto.request.wms.*;
import com.wms_main.model.dto.response.wcs.BaseWcsApiResponse;
import com.wms_main.model.dto.response.wcs.WcsApiResponse;
import com.wms_main.model.dto.response.wms.BaseWmsApiResponse;
import com.wms_main.model.dto.response.wms.WmsApiResponse;
import com.wms_main.model.po.*;
import com.wms_main.model.vo.wms.TaskConfirmVo;
import com.wms_main.model.vo.wms.WorkConfirmVo;
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.business.IStockDataService;
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 org.springframework.transaction.interceptor.TransactionAspectSupport;

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

/**
 * 任务控制类 服务实现
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class TaskControllerServiceImpl implements ITaskControllerService {
    private final ITAppWcsTaskService appWcsTaskService;// wcs任务服务
    private final ITAppWcsTaskBakService appWcsTaskBakService;// wcs任务备份服务
    private final ITAppTaskService appWmsTaskService;// wms任务服务
    private final IStackerTaskService stackerTaskService;// 堆垛机任务服务
    private final ITAppLocationService appLocationService;// 库位服务
    private final ITAppPickTaskService appPickTaskService;// 拣选任务服务
    private final ITAppVehicleService appVehicleService;// 载具服务
    private final ITAppStockService appStockService;// 库存服务
    private final ITAppStandService appStandService;// 站台服务
    private final ITAppOutsService appOutsService;// 出库单服务
    private final IStockDataService stockDataService;// 库存数据服务
    private final ITAppOutsRecordService appOutsRecordService;// 出库单记录服务
    private final AppCommon appCommon;

    /**
     * 实现
     *
     * @param stockInRequest 请求信息
     * @return 响应结果
     */
    @Override
    @Transactional
    public BaseWmsApiResponse requireStockIn(StockInRequest stockInRequest) {
        // 判断请求信息的正确性。
        if (stockInRequest == null || StringUtils.isEmpty(stockInRequest.getVehicleId())) {
            return BaseWmsApiResponse.error("请求参数不完整，缺少载具号。");
        }
        // 校验当前是否在库
        if (appVehicleService.exists(new LambdaQueryWrapper<TAppVehicle>()
                .eq(TAppVehicle::getVehicleId, stockInRequest.getVehicleId())
                .eq(TAppVehicle::getVehicleStatus, WmsVehicleStatusEnums.ON.getCode()))) {
            return BaseWmsApiResponse.error("当前载具显示已在库中，无法再次入库。");
        }
        // 判断这个箱子是否有其他的wcs任务
        if (appWcsTaskService.exists(new LambdaQueryWrapper<TAppWcsTask>()
                .eq(TAppWcsTask::getVehicleId, stockInRequest.getVehicleId()))) {
            return BaseWmsApiResponse.error("当前载具仍有未完成的WCS任务，无法创建新的入库任务。");
        }
        // 判断这个箱子是否有其他的wms任务
        if (appWmsTaskService.exists(new LambdaQueryWrapper<TAppTask>()
                .eq(TAppTask::getVehicleId, stockInRequest.getVehicleId()))) {
            return BaseWmsApiResponse.error("当前载具仍有未完成的WMS任务，无法创建新的入库任务。");
        }
        // 非空载具入库，但是未包含物料信息，设置为空
        if (!stockInRequest.isEmptyTask() && (stockInRequest.getGoodsInfo() == null || stockInRequest.getGoodsInfo().isEmpty())) {
            stockInRequest.setEmptyTask(true);
        }
        // 空载具入库但是请求包含物料信息，设置为非空
        if (stockInRequest.isEmptyTask() && stockInRequest.getGoodsInfo() != null && !stockInRequest.getGoodsInfo().isEmpty()) {
            stockInRequest.setEmptyTask(false);
        }
        // 查询当前载具的库存信息
        List<TAppStock> thisVehicleStocks = appStockService.list(
                new LambdaQueryWrapper<TAppStock>()
                        .eq(TAppStock::getVehicleId, stockInRequest.getVehicleId()));
        if (stockInRequest.isEmptyTask()) {
            // 创建空载具入库任务
            TAppTask task = new TAppTask(
                    UUIDUtils.getNewUUID(),
                    WmsTaskTypeEnums.IN.getCode(),
                    WmsStackerTaskStatusEnums.TEMP.getCode(),
                    1,
                    stockInRequest.getVehicleId(),
                    stockInRequest.getOrigin(),
                    null,
                    null,
                    LocalDateTime.now(),
                    null,
                    AppConstant.EMPTY_GOODS_ID,
                    0,
                    0,
                    stockInRequest.getUserName(),
                    "",
                    stockInRequest.getStandId(),
                    "",
                    "",
                    ""
            );
            try {
                // 保存任务
                appWmsTaskService.save(task);
            } catch (Exception e) {
                return BaseWmsApiResponse.error("创建空载具入库任务失败。");
            }
        } else {
            Map<String, TAppTask> goodsIdTaskMap = new HashMap<>();
            Map<String, TAppGoods> goodsMap = new HashMap<>();
            // 循环物料生成入库任务
            for (GoodsInfoForTask goodsInfoForTask : stockInRequest.getGoodsInfo()) {
                if (goodsIdTaskMap.containsKey(goodsInfoForTask.getGoodsId())) {
                    // 如果同一物料，则数量叠加。
                    TAppTask task = goodsIdTaskMap.get(goodsInfoForTask.getGoodsId());
                    task.setOpNum(task.getOpNum() + goodsInfoForTask.getOpNum());
                    goodsIdTaskMap.replace(goodsInfoForTask.getGoodsId(), task);
                } else {
                    // 判断当前料号是否存在于立库信息中
                    TAppGoods goods = appCommon.getInstantGoodsByGoodsId(goodsInfoForTask.getGoodsId());
                    if (goods == null) {
                        return BaseWmsApiResponse.error("入库物料列表中有物料不在立库维护信息中。物料号：" + goodsInfoForTask.getGoodsId() + "。");
                    }
                    if (!Objects.equals(goods.getPutArea(), "ASRS")) {
                        return BaseWmsApiResponse.error("非库内料不允许入库。物料号：" + goodsInfoForTask.getGoodsId() + "。");
                    }
                    // 创建入库任务
                    TAppTask task = new TAppTask(
                            UUIDUtils.getNewUUID(),
                            WmsTaskTypeEnums.IN.getCode(),
                            WmsStackerTaskStatusEnums.TEMP.getCode(),
                            1,
                            stockInRequest.getVehicleId(),
                            stockInRequest.getOrigin(),
                            null,
                            null,
                            LocalDateTime.now(),
                            null,
                            goodsInfoForTask.getGoodsId(),
                            goodsInfoForTask.getOpNum(),
                            0,
                            stockInRequest.getUserName(),
                            goodsInfoForTask.getRemark(),
                            stockInRequest.getStandId(),
                            goods.getGoodsDescription(),
                            "",
                            ""
                    );
                    goodsIdTaskMap.put(goodsInfoForTask.getGoodsId(), task);
                    goodsMap.put(goodsInfoForTask.getGoodsId(), goods);
                }
                if (goodsMap.containsKey(goodsInfoForTask.getGoodsId())) {
                    // 判断数量是否超载
                    TAppGoods thisGoods = goodsMap.get(goodsInfoForTask.getGoodsId());
                    int maxQty1Vehicle = thisGoods.getBoxQty() * thisGoods.getMaxBoxNum();
                    int oldStockNum = 0;
                    if (thisVehicleStocks != null && !thisVehicleStocks.isEmpty()) {
                        // 计算出该物料的库存数量
                        oldStockNum = thisVehicleStocks.stream()
                                .filter(stock -> stock.getGoodsId().equals(goodsInfoForTask.getGoodsId()))
                                .mapToInt(TAppStock::getRealNum)
                                .sum();
                    }
                    if (goodsIdTaskMap.get(goodsInfoForTask.getGoodsId()).getOpNum() + oldStockNum > maxQty1Vehicle) {
                        return BaseWmsApiResponse.error("物料号：" + goodsInfoForTask.getGoodsId() + "数量超过阈值" + maxQty1Vehicle + "，不允许入库。");
                    }
                }
            }
            try {
                appWmsTaskService.saveBatch(goodsIdTaskMap.values());
            } catch (Exception e) {
                // 回滚事务
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return BaseWmsApiResponse.error("创建入库任务失败。");
            }
        }

        return BaseWmsApiResponse.success("生成入库任务成功。");
    }

    /**
     * 请求出库---实现
     *
     * @param stockOutRequest 请求信息
     * @return 处理结果
     */
    @Override
    @Transactional
    public BaseWmsApiResponse requireStockOut(StockOutRequest stockOutRequest) {
        // 保存
        if (stockOutRequest == null || stockOutRequest.getOutType() == null || stockOutRequest.getNeedNum() == null
                || stockOutRequest.getNeedNum() <= 0 || StringUtils.isEmpty(stockOutRequest.getDestination())) {
            return BaseWmsApiResponse.error("请求参数不完整。");
        }
        // 判断终点对不对
        if (!appStandService.exists(new LambdaQueryWrapper<TAppStand>().eq(TAppStand::getStandId, stockOutRequest.getDestination()))) {
            return BaseWmsApiResponse.error("请求的终点站台不存在。");
        }
        // 针对不同的出库类型验证请求
        if (stockOutRequest.getOutType().equals(WmsOutTypeEnums.EMPTY.getCode())) {
            // 如果指定了载具号，则验证该载具是否为空载具
            if (StringUtils.isNotEmpty(stockOutRequest.getVehicleId())) {
                // 查询这个载具号
                boolean haveThisEmptyVehicleFlag = appVehicleService.exists(new LambdaQueryWrapper<TAppVehicle>()
                        .eq(TAppVehicle::getVehicleId, stockOutRequest.getVehicleId())
                                .eq(TAppVehicle::getVehicleStatus, WmsVehicleStatusEnums.ON.getCode())
                        .eq(TAppVehicle::getIsEmpty, 1)
                );
                if (!haveThisEmptyVehicleFlag) {
                    return BaseWmsApiResponse.error("请求错误：目标不存在。");
                }
            } else {
                // 判断空载具数量够不够

            }
        }
        // 添加任务
        TAppOuts task = new TAppOuts(
                UUIDUtils.getNewUUID(),
                stockOutRequest.getGoodsId(),
                stockOutRequest.getVehicleId(),
                stockOutRequest.getNeedNum(),
                0,
                0,
                stockOutRequest.getOutType(),
                stockOutRequest.getDestination(),
                stockOutRequest.getUserName()
        );
        try {
            appOutsService.save(task);
            return BaseWmsApiResponse.success("添加出库请求成功。");
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return BaseWmsApiResponse.error("添加出库请求失败。");
        }
    }

    /**
     * 实现
     *
     * @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())
            );
            // 移除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("处理任务状态反馈成功。");
    }
}
