package org.wcs.serve.service.pub.impl;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.wcs.constant.enums.common.TrueOrFalseEnum;
import org.wcs.constant.enums.database.*;
import org.wcs.factory.PubServeResponseFactory;
import org.wcs.helper.PlcTaskIdHelper;
import org.wcs.mapper.intf.AppConveyTaskService;
import org.wcs.mapper.intf.AppEtagTaskService;
import org.wcs.mapper.intf.AppStockComposeTaskBakService;
import org.wcs.mapper.intf.AppStockComposeTaskService;
import org.wcs.model.dto.pub.AddConveyTaskReq;
import org.wcs.model.dto.pub.AddEtagTaskReq;
import org.wcs.model.dto.pub.AddStockTaskReq;
import org.wcs.model.dto.pub.EtagTaskItem;
import org.wcs.model.po.app.AppConveyTask;
import org.wcs.model.po.app.AppEtagTask;
import org.wcs.model.po.app.AppStockComposeTask;
import org.wcs.model.po.app.AppStockComposeTaskBak;
import org.wcs.model.vo.pub.PubServeDataResponse;
import org.wcs.model.vo.pub.PubServeResponse;
import org.wcs.model.vo.pub.task.StockTaskDetailVo;
import org.wcs.serve.service.pub.intf.ITaskService;
import org.wcs.utils.AppBeanUtils;
import org.wcs.utils.AppStringUtils;
import org.wcs.utils.AppUUIDUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class TaskService implements ITaskService {

    private final PlcTaskIdHelper plcTaskIdHelper;
    private final AppStockComposeTaskService stockComposeTaskService; // 仓库任务服务
    private final AppStockComposeTaskBakService stockComposeTaskBakService; // 仓库任务备份服务

    private final AppConveyTaskService conveyTaskService; // 箱式线任务服务

    private final AppEtagTaskService etagTaskService; // 电子标签任务服务

    /**
     * 添加仓库任务
     * @param addStockTaskReq 添加仓库任务请求
     * @return 添加仓库任务结果
     */
    @Override
    public PubServeResponse addStockTask(AddStockTaskReq addStockTaskReq) {
        List<AppStockComposeTask> stockComposeTasks = stockComposeTaskService.queryByUpperTaskId(addStockTaskReq.getTaskId());
        if(stockComposeTasks == null) {
            return PubServeResponseFactory.fail("数据服务异常，请重试");
        }
        if(!stockComposeTasks.isEmpty()) {
            return PubServeResponseFactory.success("任务已存在，请勿重复添加");
        }
        StockComposeTaskTypeEnum composeTaskTypeEnum = StockComposeTaskTypeEnum.getByCode(addStockTaskReq.getTaskType());
        if(composeTaskTypeEnum.equals(StockComposeTaskTypeEnum.UNKNOWN)) {
            return PubServeResponseFactory.fail("不允许的任务类型");
        }
        AppStockComposeTask insertStockComposeTask = new AppStockComposeTask();
        insertStockComposeTask.setTaskId(AppUUIDUtils.getNewUUID());
        insertStockComposeTask.setTaskGroup(AppStringUtils.isEmptyOr(addStockTaskReq.getTaskGroup(), addStockTaskReq.getTaskId()));
        insertStockComposeTask.setUpperTaskId(addStockTaskReq.getTaskId());
        insertStockComposeTask.setTaskType(addStockTaskReq.getTaskType());
        insertStockComposeTask.setOrigin(addStockTaskReq.getOrigin());
        insertStockComposeTask.setDestination(addStockTaskReq.getDestination());
        insertStockComposeTask.setTaskStatus(StockComposeTaskStatusEnum.CREATE.getCode());
        insertStockComposeTask.setStepStatus(StockComposeTaskStatusEnum.CREATE.getCode());
        insertStockComposeTask.setCanCancel(TrueOrFalseEnum.TRUE.getCode());
        insertStockComposeTask.setPriority(addStockTaskReq.getPriority() == null ? 5 : addStockTaskReq.getPriority());
        insertStockComposeTask.setVehicleNo(addStockTaskReq.getVehicleNo());
        insertStockComposeTask.setVehicleSize(addStockTaskReq.getSize() == null ? 0 : addStockTaskReq.getSize());
        insertStockComposeTask.setWeight(BigDecimal.valueOf(addStockTaskReq.getWeight() == null ? 0 : addStockTaskReq.getWeight()));
        insertStockComposeTask.setCreateTime(LocalDateTime.now());
        insertStockComposeTask.setUpdateTime(LocalDateTime.now());
        insertStockComposeTask.setTaskSource(addStockTaskReq.getSysName());
        insertStockComposeTask.setCreatePerson("?");
        int insertResult = stockComposeTaskService.insert(insertStockComposeTask);
        if(insertResult <= 0) {
            return PubServeResponseFactory.fail("数据服务异常，请重试");
        }
        return PubServeResponseFactory.success("添加任务成功");
    }

    /**
     * 查询仓库任务详情
     * @param taskId 任务ID
     * @return 仓库任务详情
     */
    @Override
    public PubServeDataResponse<StockTaskDetailVo> queryStockTaskDetail(String taskId) {
        /* 检索当前表 */
        List<AppStockComposeTask> stockComposeTasks = stockComposeTaskService.queryByUpperTaskId(taskId);
        if(stockComposeTasks == null) {
            return PubServeResponseFactory.fail("数据服务异常，请重试", null);
        }
        if(!stockComposeTasks.isEmpty()) {
            AppStockComposeTask stockComposeTask = stockComposeTasks.getFirst();
            StockTaskDetailVo stockTaskDetailVo = new StockTaskDetailVo();
            AppBeanUtils.copyProperties(stockComposeTask, stockTaskDetailVo);
            return PubServeResponseFactory.success("查询任务详情成功", stockTaskDetailVo);
        }
        /* 检索备份表 */
        List<AppStockComposeTaskBak> stockComposeTasksBak = stockComposeTaskBakService.queryByUpperTaskId(taskId);
        if(stockComposeTasksBak == null) {
            return PubServeResponseFactory.fail("数据服务异常，请重试", null);
        }
        if(!stockComposeTasksBak.isEmpty()) {
            AppStockComposeTaskBak stockComposeTaskBak = stockComposeTasksBak.getFirst();
            StockTaskDetailVo stockTaskDetailVo = new StockTaskDetailVo();
            AppBeanUtils.copyProperties(stockComposeTaskBak, stockTaskDetailVo);
            return PubServeResponseFactory.success("查询任务详情成功", stockTaskDetailVo);
        }
        return PubServeResponseFactory.fail("您要找的任务不存在", null);
    }

    /**
     * 取消仓库任务
     * @param taskId 仓库任务ID
     * @return 取消仓库任务结果
     */
    @Override
    public PubServeResponse cancelStockTask(String taskId) {
        /* 检索当前表 */
        List<AppStockComposeTask> stockComposeTasks = stockComposeTaskService.queryByUpperTaskId(taskId);
        if(stockComposeTasks == null) {
            return PubServeResponseFactory.fail("数据服务异常，请重试");
        }
        if(stockComposeTasks.isEmpty()) {
            return PubServeResponseFactory.success("任务不存在");
        }
        AppStockComposeTask stockComposeTask = stockComposeTasks.getFirst();
        if(StockComposeTaskStatusEnum.CANCEL.getCode().equals(stockComposeTask.getTaskStatus())) {
            return PubServeResponseFactory.success("任务已取消");
        }
        if(stockComposeTask.getCanCancel().equals(TrueOrFalseEnum.FALSE.getCode())) {
            return PubServeResponseFactory.fail("任务不允许取消");
        }
        int updateRows = stockComposeTaskService.setTaskStatusAndMsgWithOldTaskStatus(taskId, stockComposeTask.getTaskStatus(), StockComposeTaskStatusEnum.CANCEL, "取消任务");
        if(updateRows <= 0) {
            return PubServeResponseFactory.fail("数据服务异常，请重试");
        }
        // 更新成功，二次校验任务是否真取消
        List<AppStockComposeTask> stockComposeTasksNew = stockComposeTaskService.queryByUpperTaskId(taskId);
        if(stockComposeTasksNew == null) {
            return PubServeResponseFactory.fail("数据服务异常，请重试");
        }
        if(stockComposeTasksNew.isEmpty()) {
            return PubServeResponseFactory.fail("任务校验不存在");
        }
        AppStockComposeTask stockComposeTaskNew = stockComposeTasksNew.getFirst();
        if(StockComposeTaskStatusEnum.CANCEL.getCode().equals(stockComposeTaskNew.getTaskStatus())) {
            return PubServeResponseFactory.success("任务已取消");
        }
        return PubServeResponseFactory.fail("取消任务失败");
    }

    /**
     * 添加箱式线任务
     * @param addConveyTaskReq 添加任务数据
     * @return 添加结果
     */
    @Override
    public PubServeResponse addConveyTask(AddConveyTaskReq addConveyTaskReq) {
        boolean exist = ConveyTaskTypeEnum.isExist(addConveyTaskReq.getTaskType());
        if(!exist) {
            return PubServeResponseFactory.fail("任务类型不满足要求");
        }
        List<AppConveyTask> conveyTasks = conveyTaskService.queryByTaskId(addConveyTaskReq.getTaskId());
        if(conveyTasks == null) {
            return PubServeResponseFactory.fail("数据服务异常，请重试");
        }
        if(!conveyTasks.isEmpty()) {
            return PubServeResponseFactory.success("任务已存在，请勿重复发送");
        }
        Integer plcTaskId = plcTaskIdHelper.newTaskId();
        if(plcTaskId == null) {
            return PubServeResponseFactory.fail("数据服务异常,无法生成任务号，请重试");
        }
        AppConveyTask appConveyTask = new AppConveyTask();
        appConveyTask.setTaskId(addConveyTaskReq.getTaskId());
        appConveyTask.setTaskGroup(addConveyTaskReq.getTaskGroup() == null ? addConveyTaskReq.getTaskId() : addConveyTaskReq.getTaskGroup());
        appConveyTask.setTaskType(addConveyTaskReq.getTaskType());
        appConveyTask.setOrderId(addConveyTaskReq.getOrderId());
        appConveyTask.setVehicleNo(addConveyTaskReq.getVehicleNo());
        appConveyTask.setLocation(addConveyTaskReq.getLocation());
        appConveyTask.setSize(addConveyTaskReq.getSize());
        appConveyTask.setWeight(BigDecimal.valueOf(addConveyTaskReq.getWeight() == null ? 0 : addConveyTaskReq.getWeight()));
        appConveyTask.setLength(BigDecimal.valueOf(addConveyTaskReq.getLength() == null ? 0 : addConveyTaskReq.getLength()));
        appConveyTask.setWidth(BigDecimal.valueOf(addConveyTaskReq.getWidth() == null ? 0 : addConveyTaskReq.getWidth()));
        appConveyTask.setHeight(BigDecimal.valueOf(addConveyTaskReq.getHeight() == null ? 0 : addConveyTaskReq.getHeight()));
        appConveyTask.setTaskStatus(ConveyTaskStatusEnum.CREATED.getCode());
        appConveyTask.setTaskSource(addConveyTaskReq.getSysName());
        appConveyTask.setCreatePerson("?");
        appConveyTask.setCreateTime(LocalDateTime.now());
        appConveyTask.setUpdateTime(LocalDateTime.now());
        int insertRows = conveyTaskService.insertConveyTask(appConveyTask);
        return insertRows > 0 ? PubServeResponseFactory.success("添加任务成功") : PubServeResponseFactory.fail("数据服务异常，请重试");
    }

    /**
     * 添加电子标签任务
     * @param addEtagTaskReq 添加任务数据
     * @return 添加结果
     */
    @Override
    public PubServeResponse addEtagTask(AddEtagTaskReq addEtagTaskReq) {
        boolean validTaskTypeResult = EtagTaskTypeEnum.isValid(addEtagTaskReq.getTaskType());
        if(!validTaskTypeResult) {
            return PubServeResponseFactory.fail("任务类型不在支持的范围内");
        }
        boolean validLightModelResult = EtagTaskLightModelEnum.isValid(addEtagTaskReq.getLightModel());
        if(!validLightModelResult) {
            return PubServeResponseFactory.fail("点亮模式不在支持的范围内");
        }
        // 定义任务组
        String taskGroup = addEtagTaskReq.getTaskGroup();
        if(AppStringUtils.isEmpty(taskGroup)) {
            taskGroup = AppUUIDUtils.getNewUUID();
        }
        List<AppEtagTask> newEtagTaskList = new ArrayList<>(); // 新增任务列表
        List<EtagTaskItem> taskItemList = addEtagTaskReq.getTaskItemList();
        for (EtagTaskItem etagTaskItem : taskItemList) {
            // 检验任务是否存在
            List<AppEtagTask> appEtagTasks = etagTaskService.queryByTaskId(etagTaskItem.getTaskId());
            if(appEtagTasks == null) {
                return PubServeResponseFactory.fail("数据服务异常，请重试");
            }
            if(!appEtagTasks.isEmpty()) {
                log.info("收到一个重复的电子标签任务：{}", AppStringUtils.objectToString(etagTaskItem));
                continue;
            }
            AppEtagTask appEtagTask = new AppEtagTask();
            appEtagTask.setTaskId(etagTaskItem.getTaskId());
            appEtagTask.setTaskGroup(taskGroup);
            appEtagTask.setTaskType(addEtagTaskReq.getTaskType());
            appEtagTask.setVehicleNo(addEtagTaskReq.getVehicleNo());
            appEtagTask.setOrderId(etagTaskItem.getOrderId());
            appEtagTask.setLocation(etagTaskItem.getLocation());
            appEtagTask.setGoodsId(etagTaskItem.getGoodsId());
            appEtagTask.setGoodsName(etagTaskItem.getGoodsName());
            appEtagTask.setLightNum(BigDecimal.valueOf(etagTaskItem.getLightNum()));
            appEtagTask.setTaskStatus(EtagTaskStatusEnum.NOT_ACTIVATED.getCode());
            if(addEtagTaskReq.getLightModel() == null) {
                appEtagTask.setLightModel(EtagTaskLightModelEnum.IMMEDIATELY.getCode());
            } else {
                appEtagTask.setLightModel(addEtagTaskReq.getLightModel());
            }
            appEtagTask.setTaskSource(addEtagTaskReq.getSysName());
            appEtagTask.setCreatePerson("?");
            appEtagTask.setCreateTime(LocalDateTime.now());
            newEtagTaskList.add(appEtagTask);
        }
        if(newEtagTaskList.isEmpty()) {
            return PubServeResponseFactory.success("任务已存在，请勿重复发送");
        }
        Integer result = etagTaskService.insert(newEtagTaskList).result();
        return result > 0 ? PubServeResponseFactory.success("添加成功") : PubServeResponseFactory.fail("数据服务异常，请重试");
    }


}
