package com.wms.controller;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wms.annotation.MyLog;
import com.wms.constants.enums.ResponseCode;
import com.wms.constants.enums.WmsTaskStatus;
import com.wms.entity.app.ResponseEntity;
import com.wms.entity.app.dto.PageDto;
import com.wms.entity.app.request.PickTaskQuery;
import com.wms.entity.app.request.TaskQuery;
import com.wms.entity.app.vo.PickTaskVo;
import com.wms.entity.app.wcs.WcsTaskResultRequest;
import com.wms.entity.table.PickTask;
import com.wms.entity.table.Task;
import com.wms.service.PickTaskService;
import com.wms.service.TaskService;
import com.wms.utils.HttpUtils;
import com.wms.utils.StringUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import java.util.Objects;

import static com.wms.utils.StringUtils.convertJsonString;

/**
 * 任务监控控制类
 */
@Controller
@CrossOrigin
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@RequestMapping(value = "/wms/taskMonitor")
public class TaskMonitorController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
     * 请求头部信息
     */
    private final HttpServletRequest servletRequest;
    /**
     * 拣选任务服务
     */
    private final PickTaskService pickTaskService;
    /**
     * 任务服务
     */
    private final TaskService taskService;
    /**
     * 任务控制类
     */
    private final TaskController taskController;

    /**
     * 查询拣选任务---分页
     *
     * @param pickTaskQuery 查询参数
     * @return 查询结果
     */
    @PostMapping("/getPickTasksByPage")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "查询拣选任务", logMethod = "getPickTasksByPage")
    public String getTasksByPage(@RequestBody PickTaskQuery pickTaskQuery) {
        logger.info("接收到查询拣选任务请求：{}，ip地址：{}", convertJsonString(pickTaskQuery), HttpUtils.getIpAddr(servletRequest));
        ResponseEntity response = new ResponseEntity();
        try {
            Page<PickTask> page = pickTaskQuery.toMpPage();
            //更新条件
            LambdaQueryWrapper<PickTask> lambdaQueryWrapper = new LambdaQueryWrapper<PickTask>()
                    .eq(pickTaskQuery.getPickStatus() != null, PickTask::getPickStatus, pickTaskQuery.getPickStatus())
                    .like(StringUtils.isNotEmpty(pickTaskQuery.getPickTaskId()), PickTask::getPickTaskId, pickTaskQuery.getPickTaskId())
                    .like(StringUtils.isNotEmpty(pickTaskQuery.getVehicleId()), PickTask::getVehicleId, pickTaskQuery.getVehicleId())
                    .like(StringUtils.isNotEmpty(pickTaskQuery.getStandId()), PickTask::getStandId, pickTaskQuery.getStandId());
            Page<PickTask> pickTasksPage = pickTaskService.page(page, lambdaQueryWrapper);
            // 生成数据
            PageDto<PickTaskVo> pageDto = PageDto.of(pickTasksPage, pickTasks -> BeanUtil.copyProperties(pickTasks, PickTaskVo.class));
            response.setCode(ResponseCode.OK.getCode());
            response.setMessage("查询拣选任务成功");
            response.setReturnData(pageDto);
            return convertJsonString(response);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.error("查询拣选任务发生异常");
            response.setCode(ResponseCode.ERROR.getCode());
            response.setMessage("查询拣选任务发生异常");
            return convertJsonString(response);
        }
    }

    /**
     * 更新拣选任务信息
     *
     * @param pickTaskQuery 拣选任务请求
     * @return 结果
     */
    @PostMapping("/updatePickTaskInfo")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "更新拣选任务信息", logMethod = "updatePickTaskInfo")
    public String updatePickTaskInfo(@RequestBody PickTaskQuery pickTaskQuery) {
        logger.info("接收到更新拣选任务信息请求：{}，请求ip：{}", convertJsonString(pickTaskQuery), HttpUtils.getIpAddr(servletRequest));
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            if (StringUtils.isEmpty(pickTaskQuery.getPickTaskId())) {// 拣选任务号为空
                logger.error("缺少拣选任务号。");
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("缺少拣选任务号。");
                return convertJsonString(rsp);
            }
            if (pickTaskService.update(pickTaskQuery.toPickTaskPo(), new LambdaQueryWrapper<PickTask>().eq(PickTask::getPickTaskId, pickTaskQuery.getPickTaskId()))) {
                // 返回成功
                logger.info("更新拣选任务信息成功。");
                rsp.setCode(ResponseCode.OK.getCode());
                rsp.setMessage("更新拣选任务信息成功。");
            } else {
                // 返回失败
                logger.error("更新拣选任务信息失败。");
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("更新拣选任务信息失败。");
            }

            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.info("更新拣选任务信息发生异常：{}", convertJsonString(e));
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("更新拣选任务信息发生异常");
            return JSON.toJSONString(rsp);
        }
    }

    /**
     * 修改任务信息
     *
     * @param taskQuery 任务信息
     * @return 结果
     */
    @PostMapping("/updateTaskInfo")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "修改任务信息", logMethod = "updateTaskInfo")
    public String updateTaskInfo(@RequestBody TaskQuery taskQuery) {
        logger.info("接收到修改任务信息请求：{}，请求ip：{}", convertJsonString(taskQuery), HttpUtils.getIpAddr(servletRequest));
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            if (StringUtils.isEmpty(taskQuery.getTaskId())) {// 任务号为空
                logger.error("缺少任务号。");
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("缺少任务号。");
                return convertJsonString(rsp);
            }
            // 只支持修改任务状态
            if (taskQuery.getTaskStatus() != null) {
                // 查询对应的任务
                Task task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getTaskId, taskQuery.getTaskId()).last("limit 1"));
                if (task == null) {
                    logger.error("任务号错误：没有任务。");
                    rsp.setCode(ResponseCode.ERROR.getCode());
                    rsp.setMessage("任务号错误：没有任务。");
                    return convertJsonString(rsp);
                }
                if (!Objects.equals(task.getTaskStatus(), taskQuery.getTaskStatus())) {
                    if (Objects.equals(taskQuery.getTaskStatus(), WmsTaskStatus.TEMP.getCode())
                            || Objects.equals(taskQuery.getTaskStatus(), WmsTaskStatus.NEW.getCode())
                            || Objects.equals(taskQuery.getTaskStatus(), WmsTaskStatus.PICKING.getCode())
                            || Objects.equals(taskQuery.getTaskStatus(), WmsTaskStatus.INVENTORY.getCode())) {
                        if (taskService.update(new LambdaUpdateWrapper<Task>()
                                .set(Task::getTaskStatus, taskQuery.getTaskStatus())
                                .eq(Task::getTaskGroup, task.getTaskGroup())
                                .ne(Task::getTaskStatus, taskQuery.getTaskStatus()))) {
                            // 返回成功
                            logger.info("修改任务信息成功。");
                            rsp.setCode(ResponseCode.OK.getCode());
                            rsp.setMessage("修改任务信息成功。");
                        } else {
                            // 返回失败
                            logger.error("修改任务信息失败。");
                            rsp.setCode(ResponseCode.ERROR.getCode());
                            rsp.setMessage("修改任务信息失败。");
                        }
                    } else {
                        WcsTaskResultRequest taskResultRequest = new WcsTaskResultRequest();
                        taskResultRequest.setTaskId(task.getTaskGroup());
                        taskResultRequest.setTaskStatus(taskQuery.getTaskStatus());
                        taskResultRequest.setMessage("任务状态修改");
                        taskResultRequest.setUserName(taskQuery.getUserName());
                        taskResultRequest.setVehicleId(task.getVehicleId());
                        taskResultRequest.setDestination(task.getDestination());
                        ResponseEntity result = JSON.parseObject(taskController.receiveTaskResult(taskResultRequest), ResponseEntity.class);
                        if (result == null || !Objects.equals(result.getCode(), ResponseCode.OK.getCode())) {
                            logger.error("修改任务信息失败。");
                            rsp.setCode(ResponseCode.ERROR.getCode());
                            rsp.setMessage(result == null ? "修改任务信息失败" : "修改任务信息失败：" + result.getMessage());
                        } else {
                            logger.info("修改任务信息成功。");
                            rsp.setCode(ResponseCode.OK.getCode());
                            rsp.setMessage("修改任务信息成功。");
                        }
                    }
                } else {
                    logger.error("任务状态没有变化。");
                    rsp.setCode(ResponseCode.ERROR.getCode());
                    rsp.setMessage("任务状态没有变化。");
                }
            } else {
                logger.error("缺少任务状态。");
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("缺少任务状态。");
            }
            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.info("修改任务发生异常：{}", convertJsonString(e));
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("修改任务发生异常");
            return JSON.toJSONString(rsp);
        }
    }
}
