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.springframework.stereotype.Service;
import org.wcs.business.pub.ReportStandard;
import org.wcs.constant.ConstantData;
import org.wcs.constant.enums.database.ConveyTaskStatusEnum;
import org.wcs.constant.enums.database.ConveyTaskTypeEnum;
import org.wcs.constant.enums.http.ConveyCallBackStatusEnum;
import org.wcs.factory.AppServeResponseFactory;
import org.wcs.helper.PlcTaskIdHelper;
import org.wcs.mapper.intf.AppConveyTaskBakService;
import org.wcs.mapper.intf.AppConveyTaskService;
import org.wcs.model.bo.tuple.Tuple2;
import org.wcs.model.dto.client.ConveyTaskStatusUploadReq;
import org.wcs.model.dto.serve.conveyTask.AddConveyTaskReq;
import org.wcs.model.dto.serve.conveyTask.QueryConveyTaskReq;
import org.wcs.model.dto.serve.conveyTask.ReporterConveyTaskStatusReq;
import org.wcs.model.po.app.AppConveyTask;
import org.wcs.model.po.app.AppConveyTaskBak;
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.conveyTask.ExportConveyTaskBakVo;
import org.wcs.model.vo.serve.conveyTask.QueryConveyTaskVo;
import org.wcs.plugin.excel.ExcelPoi;
import org.wcs.plugin.webHttpClient.WebHttpClient;
import org.wcs.plugin.webHttpClient.model.HttpRequest;
import org.wcs.plugin.webHttpClient.model.HttpResponse;
import org.wcs.serve.service.intf.IConveyTaskService;
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 ConveyTaskService implements IConveyTaskService {

    private final AppConveyTaskService conveyTaskService;
    private final AppConveyTaskBakService conveyTaskBakService;
    private final PlcTaskIdHelper plcTaskIdHelper;
    private final ExcelPoi excelPoi;

    /**
     * 查询输送任务列表
     * @param request 查询参数
     * @param pageSize 每页数量
     * @param pageIndex 页码
     * @return 查询结果
     */
    @Override
    public AppServeDataResponse<PageDataResponse<QueryConveyTaskVo>> queryConveyTask(QueryConveyTaskReq request, Integer pageSize, Integer pageIndex) {
        if(request == null || pageSize == null || pageIndex == null || pageSize <= 0 || pageIndex <= 0) {
            return AppServeResponseFactory.fail("参数错误", null);
        }
        Tuple2<Long, List<AppConveyTask>> pageResult = conveyTaskService.queryConveyTask(request, pageSize, pageIndex);
        if(pageResult == null) {
            return AppServeResponseFactory.fail("数据服务异常", null);
        }
        PageDataResponse<QueryConveyTaskVo> response = new PageDataResponse<>();
        response.setPageIndex(pageIndex);
        response.setPageSize(pageSize);
        response.setTotalCount(pageResult.getItem1());
        response.setData(AppBeanUtils.copyListProperties(pageResult.getItem2(), QueryConveyTaskVo::new));
        return AppServeResponseFactory.success("查询成功", response);
    }

    /**
     * 获取所有输送任务列表 ---- 备份表
     * @param request 获取参数
     * @param pageSize 每页数量
     * @param pageIndex 页码
     * @return 获取结果
     */
    @Override
    public AppServeDataResponse<PageDataResponse<QueryConveyTaskVo>> queryConveyTaskBak(QueryConveyTaskReq request, Integer pageSize, Integer pageIndex) {
        if(request == null || pageSize == null || pageIndex == null || pageSize <= 0 || pageIndex <= 0) {
            return AppServeResponseFactory.fail("参数错误", null);
        }
        Tuple2<Long, List<AppConveyTaskBak>> pageResult = conveyTaskBakService.queryConveyTaskBak(request, pageSize, pageIndex);
        if(pageResult == null) {
            return AppServeResponseFactory.fail("数据服务异常", null);
        }
        PageDataResponse<QueryConveyTaskVo> response = new PageDataResponse<>();
        response.setPageIndex(pageIndex);
        response.setPageSize(pageSize);
        response.setTotalCount(pageResult.getItem1());
        response.setData(AppBeanUtils.copyListProperties(pageResult.getItem2(), QueryConveyTaskVo::new));
        return AppServeResponseFactory.success("查询成功", response);
    }

    /**
     * 新增输送任务
     * @param request 新增参数
     * @return 新增结果
     */
    @Override
    public AppServeResponse addConveyTask(AddConveyTaskReq request) {
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录", null);
        }
        String userId = userIdObj.toString();
        String taskId = AppUUIDUtils.getNewUUID();
        AppConveyTask appConveyTask = new AppConveyTask();
        appConveyTask.setTaskId(taskId);
        appConveyTask.setTaskGroup(taskId);
        appConveyTask.setTaskType(request.getTaskType());
        appConveyTask.setOrderId(request.getOrderId());
        appConveyTask.setVehicleNo(request.getVehicleNo());
        appConveyTask.setLocation(request.getLocation());
        appConveyTask.setSize(AppStringUtils.isEmptyOr(request.getSize(), "0"));
        appConveyTask.setWeight(request.getWeight());
        appConveyTask.setLength(request.getLength());
        appConveyTask.setWidth(request.getWidth());
        appConveyTask.setHeight(request.getHeight());
        appConveyTask.setTaskStatus(ConveyTaskStatusEnum.CREATED.getCode());
        appConveyTask.setTaskSource(ConstantData.SYSTEM_NAME);
        appConveyTask.setCreatePerson(userId);
        appConveyTask.setCreateTime(LocalDateTime.now());
        appConveyTask.setUpdateTime(LocalDateTime.now());
        appConveyTask.setPlcId(plcTaskIdHelper.newTaskId());
        appConveyTask.setRemark(request.getRemark());
        int saveResult = conveyTaskService.insertConveyTask(appConveyTask);
        return saveResult > 0 ? AppServeResponseFactory.success() : AppServeResponseFactory.fail("数据服务异常");
    }

    /**
     * 更新输送任务状态
     * @param taskId 任务ID
     * @param status 状态
     * @return 更新结果
     */
    @Override
    public AppServeResponse updateConveyTaskStatus(String taskId, Integer status) {
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录", null);
        }
        String userId = userIdObj.toString();
        if(AppStringUtils.isEmpty(taskId) || status == null) {
            return AppServeResponseFactory.fail("参数错误");
        }
        List<AppConveyTask> conveyTasks = conveyTaskService.queryByTaskId(taskId);
        if(conveyTasks == null) {
            return AppServeResponseFactory.fail("数据服务异常");
        }
        if(conveyTasks.isEmpty()) {
            return AppServeResponseFactory.fail("任务不存在");
        }
        AppConveyTask newAppConveyTask = new AppConveyTask();
        newAppConveyTask.setTaskId(taskId);
        newAppConveyTask.setTaskStatus(status);
        newAppConveyTask.setRemark(String.format("用户：%s 更新任务状态为：%s", userId, ConveyTaskStatusEnum.getMsgByCode(status)));
        int updateResult = conveyTaskService.updateConveyTask(newAppConveyTask);
        return updateResult > 0 ? AppServeResponseFactory.success() : AppServeResponseFactory.fail("数据服务异常");
    }

    /**
     * 完成输送任务
     * @param taskId 任务ID
     * @param arriveLocation 到达位置
     * @return 完成结果
     */
    @Override
    public AppServeResponse completeConveyTask(String taskId, String arriveLocation) {
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录", null);
        }
        String userId = userIdObj.toString();
        if(AppStringUtils.isEmpty(taskId) || AppStringUtils.isEmpty(arriveLocation)) {
            return AppServeResponseFactory.fail("参数错误");
        }
        List<AppConveyTask> conveyTasks = conveyTaskService.queryByTaskId(taskId);
        if(conveyTasks == null) {
            return AppServeResponseFactory.fail("数据服务异常");
        }
        if(conveyTasks.isEmpty()) {
            return AppServeResponseFactory.fail("任务不存在");
        }
        AppConveyTask newAppConveyTask = new AppConveyTask();
        newAppConveyTask.setTaskId(taskId);
        newAppConveyTask.setTaskStatus(ConveyTaskStatusEnum.ARRIVE.getCode());
        newAppConveyTask.setArriveLocation(arriveLocation);
        newAppConveyTask.setCompleteTime(LocalDateTime.now());
        newAppConveyTask.setRemark(String.format("用户：%s 完成任务，到达位置：%s", userId, arriveLocation));
        int updateResult = conveyTaskService.updateConveyTask(newAppConveyTask);
        return updateResult > 0 ? AppServeResponseFactory.success() : AppServeResponseFactory.fail("数据服务异常");
    }

    /**
     * 取消输送任务
     * @param taskId 输送任务ID
     * @return 取消结果
     */
    @Override
    public AppServeResponse cancelConveyTask(String taskId) {
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录", null);
        }
        String userId = userIdObj.toString();
        if(AppStringUtils.isEmpty(taskId)) {
            return AppServeResponseFactory.fail("参数错误");
        }
        List<AppConveyTask> conveyTasks = conveyTaskService.queryByTaskId(taskId);
        if(conveyTasks == null) {
            return AppServeResponseFactory.fail("数据服务异常");
        }
        if(conveyTasks.isEmpty()) {
            return AppServeResponseFactory.fail("任务不存在");
        }
        AppConveyTask newAppConveyTask = new AppConveyTask();
        newAppConveyTask.setTaskId(taskId);
        newAppConveyTask.setTaskStatus(ConveyTaskStatusEnum.CANCEL.getCode());
        newAppConveyTask.setRemark(String.format("用户：%s 取消任务", userId));
        newAppConveyTask.setCompleteTime(LocalDateTime.now());
        int updateResult = conveyTaskService.updateConveyTask(newAppConveyTask);
        return updateResult > 0 ? AppServeResponseFactory.success() : AppServeResponseFactory.fail("数据服务异常");
    }

    /**
     * 回报输送任务完成
     * @param request 回报参数
     * @return 回报结果
     */
    @Override
    public AppServeResponse reporterConveyTaskComplete(ReporterConveyTaskStatusReq request) {
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录", null);
        }
        String userId = userIdObj.toString();
        if(AppStringUtils.isEmpty(request.getArriveLocation())) {
            return AppServeResponseFactory.fail("到达位置为空");
        }
        List<AppConveyTask> conveyTasks = conveyTaskService.queryByTaskId(request.getTaskId());
        if(conveyTasks == null) {
            return AppServeResponseFactory.fail("数据服务异常");
        }
        if(conveyTasks.isEmpty()) {
            return AppServeResponseFactory.fail("任务不存在");
        }
        AppConveyTask conveyTask = conveyTasks.getFirst(); // 取第一个任务
        Tuple2<String, String> reportResult = ReportStandard.conveyTaskReport(ConveyCallBackStatusEnum.FINISH, conveyTask, String.format("用户：%s 回报任务完成", userId));
        if(AppStringUtils.isNotEmpty(reportResult.getItem1())) {
            return AppServeResponseFactory.fail(reportResult.getItem1());
        }
        return AppServeResponseFactory.success();
    }

    /**
     * 回报输送任务取消
     * @param request 回报参数
     * @return 回报结果
     */
    @Override
    public AppServeResponse reporterConveyTaskCancel(ReporterConveyTaskStatusReq request) {
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录", null);
        }
        String userId = userIdObj.toString();
        List<AppConveyTask> conveyTasks = conveyTaskService.queryByTaskId(request.getTaskId());
        if(conveyTasks == null) {
            return AppServeResponseFactory.fail("数据服务异常");
        }
        if(conveyTasks.isEmpty()) {
            return AppServeResponseFactory.fail("任务不存在");
        }
        AppConveyTask conveyTask = conveyTasks.getFirst(); // 取第一个任务
        Tuple2<String, String> reportResult = ReportStandard.conveyTaskReport(ConveyCallBackStatusEnum.CANCEL, conveyTask, String.format("用户：%s 回报任务取消", userId));
        if(AppStringUtils.isNotEmpty(reportResult.getItem1())) {
            return AppServeResponseFactory.fail(reportResult.getItem1());
        }
        return AppServeResponseFactory.success();
    }

    /**
     * 回报输送任务完成 ---- 备份表
     * @param request 回报参数
     * @return 回报结果
     */
    @Override
    public AppServeResponse reporterConveyTaskBakComplete(ReporterConveyTaskStatusReq request) {
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录", null);
        }
        String userId = userIdObj.toString();
        if(AppStringUtils.isEmpty(request.getArriveLocation())) {
            return AppServeResponseFactory.fail("到达位置为空");
        }
        List<AppConveyTaskBak> conveyTasks = conveyTaskBakService.queryByTaskId(request.getTaskId());
        if(conveyTasks == null) {
            return AppServeResponseFactory.fail("数据服务异常");
        }
        if(conveyTasks.isEmpty()) {
            return AppServeResponseFactory.fail("任务不存在");
        }
        AppConveyTaskBak conveyTaskBak = conveyTasks.getFirst(); // 取第一个任务
        AppConveyTask conveyTask = new AppConveyTask();
        AppBeanUtils.copyProperties(conveyTaskBak,conveyTask);
        Tuple2<String, String> reportResult = ReportStandard.conveyTaskReport(ConveyCallBackStatusEnum.FINISH, conveyTask, String.format("用户：%s 回报任务完成", userId));
        if(AppStringUtils.isNotEmpty(reportResult.getItem1())) {
            return AppServeResponseFactory.fail(reportResult.getItem1());
        }
        return AppServeResponseFactory.success();

    }

    /**
     * 回报输送任务取消 ---- 备份表
     * @param request 回报参数
     * @return 回报结果
     */
    @Override
    public AppServeResponse reporterConveyTaskBakCancel(ReporterConveyTaskStatusReq request) {
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录", null);
        }
        String userId = userIdObj.toString();
        List<AppConveyTaskBak> conveyTasks = conveyTaskBakService.queryByTaskId(request.getTaskId());
        if(conveyTasks == null) {
            return AppServeResponseFactory.fail("数据服务异常");
        }
        if(conveyTasks.isEmpty()) {
            return AppServeResponseFactory.fail("任务不存在");
        }
        AppConveyTaskBak conveyTaskBak = conveyTasks.getFirst(); // 取第一个任务
        AppConveyTask conveyTask = new AppConveyTask();
        AppBeanUtils.copyProperties(conveyTaskBak,conveyTask);
        Tuple2<String, String> reportResult = ReportStandard.conveyTaskReport(ConveyCallBackStatusEnum.CANCEL, conveyTask, String.format("用户：%s 回报任务取消", userId));
        if(AppStringUtils.isNotEmpty(reportResult.getItem1())) {
            return AppServeResponseFactory.fail(reportResult.getItem1());
        }
        return AppServeResponseFactory.success();
    }

    /**
     * 导出输送任务 ---- 备份表
     * @param response 响应对象
     * @param request 查询参数
     */
    @Override
    public void exportConveyTaskBak(HttpServletResponse response, QueryConveyTaskReq request) {
        List<AppConveyTaskBak> conveyTaskBakList = conveyTaskBakService.queryConveyTaskBak(request);
        if(conveyTaskBakList == null) {
            log.info("导出输送任务备份表查询数据库失败");
            return;
        }
        List<ExportConveyTaskBakVo> exportConveyTaskBakVoList = new ArrayList<>();
        for(AppConveyTaskBak conveyTaskBak : conveyTaskBakList) {
            ExportConveyTaskBakVo exportConveyTaskBakVo = new ExportConveyTaskBakVo();
            AppBeanUtils.copyProperties(conveyTaskBak, exportConveyTaskBakVo);
            exportConveyTaskBakVo.setTaskType(ConveyTaskTypeEnum.getMsgByCode(conveyTaskBak.getTaskType()));
            exportConveyTaskBakVo.setTaskStatus(ConveyTaskStatusEnum.getMsgByCode(conveyTaskBak.getTaskStatus()));
            exportConveyTaskBakVoList.add(exportConveyTaskBakVo);
        }
        try {
            excelPoi.doWriteExcel("输送任务", response, exportConveyTaskBakVoList, ExportConveyTaskBakVo.class);
        } catch (Exception e) {
            log.error("导出输送任务备份表失败", e);
        }
    }
}
