package org.wcs.serve.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.wcs.constant.enums.common.TrueOrFalseEnum;
import org.wcs.constant.enums.database.StockSingleTaskStatusEnum;
import org.wcs.constant.enums.database.StockSingleTaskTypeEnum;
import org.wcs.factory.AppServeResponseFactory;
import org.wcs.helper.PlcTaskIdHelper;
import org.wcs.mapper.intf.AppStockSingleTaskBakService;
import org.wcs.mapper.intf.AppStockSingleTaskService;
import org.wcs.model.bo.tuple.Tuple2;
import org.wcs.model.dto.serve.stockSingleTask.AddSingleTaskReq;
import org.wcs.model.dto.serve.stockSingleTask.QueryStockSingleTaskReq;
import org.wcs.model.po.app.AppStockSingleTask;
import org.wcs.model.po.app.AppStockSingleTaskBak;
import org.wcs.model.vo.serve.AppServeDataResponse;
import org.wcs.model.vo.serve.AppServeResponse;
import org.wcs.model.vo.serve.common.PageDataResponse;
import org.wcs.model.vo.serve.stockSingleTask.AppStockSingleTaskVo;
import org.wcs.model.vo.serve.stockSingleTask.ExportAppStockSingleTaskVo;
import org.wcs.plugin.excel.ExcelPoi;
import org.wcs.serve.service.intf.IStockSingleTaskService;
import org.wcs.utils.AppBeanUtils;
import org.wcs.utils.AppStringUtils;
import org.wcs.utils.AppUUIDUtils;

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

@Slf4j
@Service
@RequiredArgsConstructor
public class StockSingleTaskService implements IStockSingleTaskService {

    private final AppStockSingleTaskService appStockSingleTaskDao;
    private final AppStockSingleTaskBakService stockSingleTaskBakService;
    private final PlcTaskIdHelper plcTaskIdHelper;
    private final ExcelPoi excelPoi;

    /**
     * 分页查询当前任务数据
     * @param request 查询参数
     * @param pageSize 每页数量
     * @param pageIndex 页码
     * @return 结果
     */
    @Override
    public AppServeDataResponse<PageDataResponse<AppStockSingleTaskVo>> query(QueryStockSingleTaskReq request, Integer pageSize, Integer pageIndex) {
        if(AppStringUtils.isNotEmpty(request.getPlcTaskId()) && !AppStringUtils.isNumber(request.getPlcTaskId())) {
            return AppServeResponseFactory.fail("plc任务号格式错误，仅限数字", null);
        }
        Tuple2<Long, List<AppStockSingleTask>> queryResult = appStockSingleTaskDao.query(request, pageSize, pageIndex);
        if(queryResult == null) {
            return AppServeResponseFactory.internalServerError("数据服务异常", null);
        }
        List<AppStockSingleTaskVo> queryResultVo = AppBeanUtils.copyListProperties(queryResult.getItem2(), AppStockSingleTaskVo::new);
        PageDataResponse<AppStockSingleTaskVo> pageDataResponse = new PageDataResponse<>();
        pageDataResponse.setPageIndex(pageIndex);
        pageDataResponse.setPageSize(pageSize);
        pageDataResponse.setTotalCount(queryResult.getItem1());
        pageDataResponse.setData(queryResultVo);
        return AppServeResponseFactory.success("查询成功", pageDataResponse);
    }

    /**
     * 分页查询历史任务数据
     * @param request 查询参数
     * @param pageSize 每页数量
     * @param pageIndex 页码
     * @return 结果
     */
    @Override
    public AppServeDataResponse<PageDataResponse<AppStockSingleTaskVo>> queryBak(QueryStockSingleTaskReq request, Integer pageSize, Integer pageIndex) {
        if(AppStringUtils.isNotEmpty(request.getPlcTaskId()) && !AppStringUtils.isNumber(request.getPlcTaskId())) {
            return AppServeResponseFactory.fail("plc任务号格式错误，仅限数字", null);
        }
        Tuple2<Long, List<AppStockSingleTaskBak>> queryResult = stockSingleTaskBakService.query(request, pageSize, pageIndex);
        if(queryResult == null) {
            return AppServeResponseFactory.internalServerError("数据服务异常", null);
        }
        List<AppStockSingleTaskVo> queryResultVo = AppBeanUtils.copyListProperties(queryResult.getItem2(), AppStockSingleTaskVo::new);
        PageDataResponse<AppStockSingleTaskVo> pageDataResponse = new PageDataResponse<>();
        pageDataResponse.setPageIndex(pageIndex);
        pageDataResponse.setPageSize(pageSize);
        pageDataResponse.setTotalCount(queryResult.getItem1());
        pageDataResponse.setData(queryResultVo);
        return AppServeResponseFactory.success("查询成功", pageDataResponse);
    }

    /**
     * 下载历史任务数据
     * @param response 响应
     * @param request 查询参数
     */
    @Override
    public void downLoadBak(HttpServletResponse response, QueryStockSingleTaskReq request) {
        List<AppStockSingleTaskBak> queryResult = stockSingleTaskBakService.query(request);
        if(queryResult == null) {
            log.error("下载历史任务失败，数据服务异常");
            return;
        }
        List<ExportAppStockSingleTaskVo> queryResultVo = new ArrayList<>();
        for (AppStockSingleTaskBak appStockSingleTask : queryResult) {
            ExportAppStockSingleTaskVo exportAppStockSingleTaskVo = new ExportAppStockSingleTaskVo();
            exportAppStockSingleTaskVo.setTaskId(appStockSingleTask.getTaskId());
            exportAppStockSingleTaskVo.setTaskGroup(appStockSingleTask.getTaskGroup());
            exportAppStockSingleTaskVo.setPlcTaskId(appStockSingleTask.getPlcTaskId());
            exportAppStockSingleTaskVo.setUpperTaskId(AppStringUtils.isEmptyOr(appStockSingleTask.getUpperTaskId(), ""));
            exportAppStockSingleTaskVo.setExecuteMachine(appStockSingleTask.getExecuteMachine());
            exportAppStockSingleTaskVo.setTaskType(StockSingleTaskTypeEnum.getByCode(appStockSingleTask.getTaskType()).getDesc());
            exportAppStockSingleTaskVo.setOrigin(appStockSingleTask.getOrigin());
            exportAppStockSingleTaskVo.setDestination(appStockSingleTask.getDestination());
            exportAppStockSingleTaskVo.setComposeDestination(appStockSingleTask.getComposeDestination());
            exportAppStockSingleTaskVo.setTaskStatus(StockSingleTaskStatusEnum.getByCode(appStockSingleTask.getTaskStatus()).getMsg());
            exportAppStockSingleTaskVo.setCanCancel(TrueOrFalseEnum.getByCode(appStockSingleTask.getCanCancel()).getMsg());
            exportAppStockSingleTaskVo.setPriority(appStockSingleTask.getPriority());
            exportAppStockSingleTaskVo.setVehicleNo(appStockSingleTask.getVehicleNo());
            exportAppStockSingleTaskVo.setVehicleNoNumber(appStockSingleTask.getVehicleNoNumber());
            exportAppStockSingleTaskVo.setVehicleSize(appStockSingleTask.getVehicleSize());
            exportAppStockSingleTaskVo.setWeight(appStockSingleTask.getWeight());
            exportAppStockSingleTaskVo.setCreateTime(appStockSingleTask.getCreateTime());
            exportAppStockSingleTaskVo.setUpdateTime(appStockSingleTask.getUpdateTime());
            exportAppStockSingleTaskVo.setStartTime(appStockSingleTask.getStartTime());
            exportAppStockSingleTaskVo.setCompleteTime(appStockSingleTask.getCompleteTime());
            exportAppStockSingleTaskVo.setEndTime(appStockSingleTask.getEndTime());
            exportAppStockSingleTaskVo.setTaskSource(appStockSingleTask.getTaskSource());
            exportAppStockSingleTaskVo.setCreatePerson(appStockSingleTask.getCreatePerson());
            exportAppStockSingleTaskVo.setTaskMsg(appStockSingleTask.getTaskMsg());
            queryResultVo.add(exportAppStockSingleTaskVo);
        }
        try {
            excelPoi.doWriteExcel("历史任务", response, queryResultVo, ExportAppStockSingleTaskVo.class);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 新增单任务
     * @param request 新增单任务数据
     * @return 结果
     */
    @Override
    public AppServeResponse addSingleTask(AddSingleTaskReq request) {
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录");
        }
        String userId = userIdObj.toString();
        Integer plcTaskId = plcTaskIdHelper.newTaskId();
        if(plcTaskId == null) {
            return AppServeResponseFactory.internalServerError("数据服务异常");
        }
        AppStockSingleTask appStockSingleTask = new AppStockSingleTask();
        String thisId = AppUUIDUtils.getNewUUID();
        appStockSingleTask.setTaskId(thisId);
        appStockSingleTask.setTaskGroup(thisId);
        appStockSingleTask.setPlcTaskId(plcTaskId);
        appStockSingleTask.setUpperTaskId("");
        appStockSingleTask.setExecuteMachine(request.getExecuteMachine());
        appStockSingleTask.setTaskType(request.getTaskType());
        appStockSingleTask.setOrigin(request.getOrigin());
        appStockSingleTask.setDestination(request.getDestination());
        appStockSingleTask.setComposeDestination(request.getDestination());
        appStockSingleTask.setTaskStatus(StockSingleTaskStatusEnum.CREATE.getCode());
        appStockSingleTask.setCanCancel(TrueOrFalseEnum.TRUE.getCode());
        appStockSingleTask.setPriority(request.getPriority());
        appStockSingleTask.setVehicleNo(request.getVehicleNo());
        appStockSingleTask.setVehicleNoNumber(AppStringUtils.forceToInt(request.getVehicleNo()));
        appStockSingleTask.setVehicleSize(request.getVehicleSize());
        appStockSingleTask.setWeight(request.getWeight());
        appStockSingleTask.setCreateTime(LocalDateTime.now());
        appStockSingleTask.setUpdateTime(LocalDateTime.now());
        appStockSingleTask.setTaskSource("WCS");
        appStockSingleTask.setCreatePerson(userId);
        boolean insert = appStockSingleTaskDao.insert(appStockSingleTask);
        if(!insert) {
            return AppServeResponseFactory.internalServerError("数据服务异常");
        }
        return AppServeResponseFactory.success("添加成功");
    }

    /**
     * 将这个任务换一个新的 PLC 任务号
     * @param taskId 任务ID
     * @return 结果
     */
    @Override
    public AppServeResponse newPlcTaskId(String taskId) {
        if(AppStringUtils.isEmpty(taskId)) {
            return AppServeResponseFactory.fail("任务ID不能为空");
        }
        Integer newPlcTaskId = plcTaskIdHelper.newTaskId();
        if(newPlcTaskId == null || newPlcTaskId <= 0) {
            return AppServeResponseFactory.internalServerError("数据服务异常");
        }
        AppStockSingleTask stockSingleTask = appStockSingleTaskDao.queryByTaskId(taskId);
        if(stockSingleTask == null) {
            return AppServeResponseFactory.fail("任务不存在");
        }
        AppStockSingleTask stockSingleTaskUpdater = new AppStockSingleTask();
        stockSingleTaskUpdater.setTaskId(taskId);
        stockSingleTaskUpdater.setPlcTaskId(newPlcTaskId);
        boolean update = appStockSingleTaskDao.update(stockSingleTaskUpdater);
        if(!update) {
            return AppServeResponseFactory.internalServerError("数据服务异常");
        }
        return AppServeResponseFactory.success("更新成功");
    }

    /**
     * 更新任务状态
     * @param taskId 任务ID
     * @param taskStatus 任务状态
     * @return 结果
     */
    @Override
    public AppServeResponse updateTaskStatus(String taskId, Integer taskStatus) {
        if(AppStringUtils.isEmpty(taskId) || taskStatus == null) {
            return AppServeResponseFactory.fail("参数错误");
        }
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录");
        }
        String userId = userIdObj.toString();
        AppStockSingleTask stockSingleTask = appStockSingleTaskDao.queryByTaskId(taskId);
        if(stockSingleTask == null) {
            return AppServeResponseFactory.fail("任务不存在或数据服务异常");
        }
        AppStockSingleTask stockSingleTaskUpdater = new AppStockSingleTask();
        stockSingleTaskUpdater.setTaskId(taskId);
        stockSingleTaskUpdater.setTaskStatus(taskStatus);
        boolean updated = appStockSingleTaskDao.update(stockSingleTaskUpdater);
        log.info("用户：{} 更新独立任务：{} 的任务状态为：{}", userId, taskId, taskStatus);
        if(!updated) {
            return AppServeResponseFactory.internalServerError("数据服务异常");
        }
        return AppServeResponseFactory.success("更新成功");
    }

    /**
     * 完成任务
     * @param taskId 任务ID
     * @return 结果
     */
    @Override
    public AppServeResponse completeTask(String taskId) {
        if(AppStringUtils.isEmpty(taskId)) {
            return AppServeResponseFactory.fail("参数错误");
        }
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录");
        }
        String userId = userIdObj.toString();
        AppStockSingleTask stockSingleTask = appStockSingleTaskDao.queryByTaskId(taskId);
        if(stockSingleTask == null) {
            return AppServeResponseFactory.fail("任务不存在或数据服务异常");
        }
        AppStockSingleTask stockSingleTaskUpdater = new AppStockSingleTask();
        stockSingleTaskUpdater.setTaskId(taskId);
        stockSingleTaskUpdater.setTaskStatus(StockSingleTaskStatusEnum.COMPLETE.getCode());
        boolean updated = appStockSingleTaskDao.update(stockSingleTaskUpdater);
        log.info("用户：{} 手动在WCS客户端完成独立任务：{} ", userId, taskId);
        if(!updated) {
            return AppServeResponseFactory.internalServerError("数据服务异常");
        }
        return AppServeResponseFactory.success("更新成功");
    }

    /**
     * 取消任务
     * @param taskId 任务ID
     * @return 结果
     */
    @Override
    public AppServeResponse cancelTask(String taskId) {
        if(AppStringUtils.isEmpty(taskId)) {
            return AppServeResponseFactory.fail("参数错误");
        }
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录");
        }
        String userId = userIdObj.toString();
        AppStockSingleTask stockSingleTask = appStockSingleTaskDao.queryByTaskId(taskId);
        if(stockSingleTask == null) {
            return AppServeResponseFactory.fail("任务不存在或数据服务异常");
        }
        AppStockSingleTask stockSingleTaskUpdater = new AppStockSingleTask();
        stockSingleTaskUpdater.setTaskId(taskId);
        stockSingleTaskUpdater.setTaskStatus(StockSingleTaskStatusEnum.CANCEL.getCode());
        boolean updated = appStockSingleTaskDao.update(stockSingleTaskUpdater);
        log.info("用户：{} 手动在WCS客户端取消独立任务：{} ", userId, taskId);
        if(!updated) {
            return AppServeResponseFactory.internalServerError("数据服务异常");
        }
        return AppServeResponseFactory.success("更新成功");
    }
}
