package com.ruoyi.web.controller.robot;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.scheduling.support.SimpleTriggerContext;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.robot.domain.LdTask;
import com.ruoyi.robot.domain.LdTaskExecutionLog;
import com.ruoyi.robot.service.ILdTaskExecutionLogService;
import com.ruoyi.robot.service.ILdTaskService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

/**
 * LD导航系统任务管理接口
 * 提供任务的增删改查及定时任务执行功能
 * 
 * 接口前缀: /v1
 */
@Api(tags = "LD导航系统任务管理接口")
@RestController
@RequestMapping("/v1")
public class LdTaskController extends BaseController {

    @Autowired
    private ILdTaskService ldTaskService;

    @Autowired
    private ILdTaskExecutionLogService ldTaskExecutionLogService;

    /**
     * 1.1 获取任务列表
     * GET /v1/path/list?map=地图名
     */
    @ApiOperation("获取任务列表")
    @GetMapping("/path/list")
    public ResponseEntity<Map<String, Object>> getTaskList(
            @ApiParam("地图名称") @RequestParam(value = "map", required = false) String mapName) {
        try {
            Map<String, Object> response = new HashMap<>();
            
            List<LdTask> taskList;
            if (mapName != null && !mapName.isEmpty()) {
                taskList = ldTaskService.selectLdTaskListByMapName(mapName);
            } else {
                taskList = ldTaskService.selectLdTaskList(new LdTask());
            }
            
            List<Map<String, Object>> paths = taskList.stream().map(task -> {
                Map<String, Object> path = new HashMap<>();
                path.put("taskId", task.getId());
                path.put("taskName", task.getTaskName());
                path.put("status", task.getStatus());
                path.put("cron", task.getCronExpression());
                path.put("executeTime", task.getExecuteTime());
                path.put("executeWeekdays", task.getExecuteWeekdays());
                path.put("repeatCount", task.getRepeatCount());
                
                // 解析目标点坐标
                if (task.getWaypointCoords() != null && !task.getWaypointCoords().isEmpty()) {
                    try {
                        path.put("coord", JSON.parse(task.getWaypointCoords()));
                    } catch (Exception e) {
                        path.put("coord", new java.util.ArrayList<>());
                    }
                } else {
                    path.put("coord", new java.util.ArrayList<>());
                }
                
                // 解析目标点类型
                if (task.getWaypointTypes() != null && !task.getWaypointTypes().isEmpty()) {
                    try {
                        path.put("plan", JSON.parse(task.getWaypointTypes()));
                    } catch (Exception e) {
                        path.put("plan", new java.util.ArrayList<>());
                    }
                } else {
                    path.put("plan", new java.util.ArrayList<>());
                }
                
                // 解析目标点动作
                if (task.getWaypointActions() != null && !task.getWaypointActions().isEmpty()) {
                    try {
                        path.put("action", JSON.parse(task.getWaypointActions()));
                    } catch (Exception e) {
                        path.put("action", new java.util.ArrayList<>());
                    }
                } else {
                    path.put("action", new java.util.ArrayList<>());
                }
                
                path.put("map", task.getMapName());
                path.put("lastExecuteTime", task.getLastExecuteTime());
                path.put("totalExecuteCount", task.getTotalExecuteCount());
                return path;
            }).collect(Collectors.toList());
            
            response.put("status", true);
            response.put("paths", paths);
            response.put("total", paths.size());
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("获取任务列表异常", e);
            return buildErrorResponse(4, "内部错误: " + e.getMessage());
        }
    }

    /**
     * 1.2 获取任务详情
     * GET /v1/path?map=地图名&path=任务名
     */
    @ApiOperation("获取任务详情")
    @GetMapping("/path")
    public ResponseEntity<Map<String, Object>> getTask(
            @ApiParam("地图名称") @RequestParam("map") String mapName,
            @ApiParam("任务名称") @RequestParam("path") String taskName) {
        try {
            LdTask task = ldTaskService.selectLdTaskByMapAndName(mapName, taskName);
            
            if (task == null) {
                return buildErrorResponse(2, "任务不存在");
            }
            
            Map<String, Object> response = new HashMap<>();
            response.put("status", true);
            response.put("taskId", task.getId());
            response.put("taskName", task.getTaskName());
            response.put("taskDesc", task.getTaskDesc());
            response.put("status", task.getStatus());
            response.put("cron", task.getCronExpression());
            response.put("executeTime", task.getExecuteTime());
            response.put("executeWeekdays", task.getExecuteWeekdays());
            response.put("repeatCount", task.getRepeatCount());
            response.put("coord_type", task.getCoordType());
            response.put("map", task.getMapName());
            
            // 解析目标点坐标
            if (task.getWaypointCoords() != null && !task.getWaypointCoords().isEmpty()) {
                response.put("coord", JSON.parse(task.getWaypointCoords()));
            } else {
                response.put("coord", new java.util.ArrayList<>());
            }
            
            // 解析目标点类型
            if (task.getWaypointTypes() != null && !task.getWaypointTypes().isEmpty()) {
                response.put("plan", JSON.parse(task.getWaypointTypes()));
            } else {
                response.put("plan", new java.util.ArrayList<>());
            }
            
            // 解析目标点动作
            if (task.getWaypointActions() != null && !task.getWaypointActions().isEmpty()) {
                response.put("action", JSON.parse(task.getWaypointActions()));
            } else {
                response.put("action", new java.util.ArrayList<>());
            }
            
            // 解析目标点ID
            if (task.getWaypointIds() != null && !task.getWaypointIds().isEmpty()) {
                response.put("waypointIds", JSON.parse(task.getWaypointIds()));
            } else {
                response.put("waypointIds", new java.util.ArrayList<>());
            }
            
            response.put("lastExecuteTime", task.getLastExecuteTime());
            response.put("lastExecuteStatus", task.getLastExecuteStatus());
            response.put("nextExecuteTime", task.getNextExecuteTime());
            response.put("totalExecuteCount", task.getTotalExecuteCount());
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("获取任务详情异常", e);
            return buildErrorResponse(4, "内部错误: " + e.getMessage());
        }
    }

    /**
     * 1.3 创建任务
     * POST /v1/path
     */
    @ApiOperation("创建任务")
    @PostMapping("/path")
    public ResponseEntity<Map<String, Object>> createTask(@RequestBody JSONObject taskData) {
        try {
            String mapName = taskData.getString("map");
            String pathName = taskData.getString("path");
            
            if (mapName == null || mapName.isEmpty() || pathName == null || pathName.isEmpty()) {
                return buildErrorResponse(1, "请求参数不合法：缺少map或path参数");
            }
            
            // 检查任务是否已存在
            LdTask existingTask = ldTaskService.selectLdTaskByMapAndName(mapName, pathName);
            if (existingTask != null) {
                return buildErrorResponse(2, "任务已存在");
            }
            
            // 构建任务对象
            LdTask task = new LdTask();
            task.setMapName(mapName);
            task.setTaskName(pathName);
            task.setTaskDesc(taskData.getString("desc"));
            task.setCronExpression(taskData.getString("cron"));
            task.setExecuteTime(taskData.getString("executeTime"));
            task.setExecuteWeekdays(taskData.getString("executeWeekdays"));
            task.setRepeatCount(taskData.getInteger("repeate") != null ? taskData.getInteger("repeate") : 1);
            task.setCoordType(taskData.getString("coord_type") != null ? taskData.getString("coord_type") : "local");
            task.setStatus("idle");
            task.setTotalExecuteCount(0);
            
            // 保存目标点坐标
            Object coordObj = taskData.get("coord");
            if (coordObj != null) {
                task.setWaypointCoords(JSON.toJSONString(coordObj));
            }
            
            // 保存目标点类型
            Object planObj = taskData.get("plan");
            if (planObj != null) {
                task.setWaypointTypes(JSON.toJSONString(planObj));
            }
            
            // 保存目标点动作
            Object actionObj = taskData.get("action");
            if (actionObj != null) {
                task.setWaypointActions(JSON.toJSONString(actionObj));
            }
            
            // 保存目标点ID
            Object waypointIdsObj = taskData.get("waypointIds");
            if (waypointIdsObj != null) {
                task.setWaypointIds(JSON.toJSONString(waypointIdsObj));
            }
            
            // 计算下次执行时间
            if (task.getCronExpression() != null && !task.getCronExpression().isEmpty()) {
                task.setNextExecuteTime(calculateNextExecuteTime(task.getCronExpression()));
            }
            
            int result = ldTaskService.insertLdTask(task);
            
            Map<String, Object> response = new HashMap<>();
            if (result > 0) {
                response.put("status", true);
                response.put("taskId", task.getId());
                response.put("msg", "任务创建成功");
            } else {
                response.put("status", false);
                response.put("msg", "任务创建失败");
            }
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("创建任务异常", e);
            return buildErrorResponse(4, "内部错误: " + e.getMessage());
        }
    }

    /**
     * 1.4 更新任务
     * PUT /v1/path
     */
    @ApiOperation("更新任务")
    @PutMapping("/path")
    public ResponseEntity<Map<String, Object>> updateTask(@RequestBody JSONObject taskData) {
        try {
            Long taskId = taskData.getLong("taskId");
            String mapName = taskData.getString("map");
            String pathName = taskData.getString("path");
            
            if (taskId == null && (mapName == null || mapName.isEmpty() || pathName == null || pathName.isEmpty())) {
                return buildErrorResponse(1, "请求参数不合法：缺少taskId或map/path参数");
            }
            
            LdTask task;
            if (taskId != null) {
                task = ldTaskService.selectLdTaskById(taskId);
            } else {
                task = ldTaskService.selectLdTaskByMapAndName(mapName, pathName);
            }
            
            if (task == null) {
                return buildErrorResponse(2, "任务不存在");
            }
            
            // 更新字段
            if (taskData.containsKey("taskName")) {
                String newTaskName = taskData.getString("taskName");
                if (!newTaskName.equals(task.getTaskName())) {
                    // 检查新名称是否已存在
                    LdTask existingTask = ldTaskService.selectLdTaskByMapAndName(task.getMapName(), newTaskName);
                    if (existingTask != null) {
                        return buildErrorResponse(2, "任务名称已存在");
                    }
                    task.setTaskName(newTaskName);
                }
            }
            
            task.setTaskDesc(taskData.getString("desc"));
            task.setCronExpression(taskData.getString("cron"));
            task.setExecuteTime(taskData.getString("executeTime"));
            task.setExecuteWeekdays(taskData.getString("executeWeekdays"));
            
            if (taskData.containsKey("repeate")) {
                task.setRepeatCount(taskData.getInteger("repeate"));
            }
            
            // 更新目标点数据
            Object coordObj = taskData.get("coord");
            if (coordObj != null) {
                task.setWaypointCoords(JSON.toJSONString(coordObj));
            }
            
            Object planObj = taskData.get("plan");
            if (planObj != null) {
                task.setWaypointTypes(JSON.toJSONString(planObj));
            }
            
            Object actionObj = taskData.get("action");
            if (actionObj != null) {
                task.setWaypointActions(JSON.toJSONString(actionObj));
            }
            
            Object waypointIdsObj = taskData.get("waypointIds");
            if (waypointIdsObj != null) {
                task.setWaypointIds(JSON.toJSONString(waypointIdsObj));
            }
            
            // 重新计算下次执行时间
            if (task.getCronExpression() != null && !task.getCronExpression().isEmpty()) {
                task.setNextExecuteTime(calculateNextExecuteTime(task.getCronExpression()));
            }
            
            int result = ldTaskService.updateLdTask(task);
            
            Map<String, Object> response = new HashMap<>();
            response.put("status", result > 0);
            response.put("msg", result > 0 ? "任务更新成功" : "任务更新失败");
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("更新任务异常", e);
            return buildErrorResponse(4, "内部错误: " + e.getMessage());
        }
    }

    /**
     * 1.5 删除任务
     * DELETE /v1/path
     */
    @ApiOperation("删除任务")
    @DeleteMapping("/path")
    public ResponseEntity<Map<String, Object>> deleteTask(@RequestBody JSONObject params) {
        try {
            String mapName = params.getString("map");
            String taskName = params.getString("path");
            Long taskId = params.getLong("taskId");
            
            if (taskId == null && (mapName == null || taskName == null)) {
                return buildErrorResponse(1, "请求参数不合法：缺少taskId或map/path参数");
            }
            
            LdTask task;
            if (taskId != null) {
                task = ldTaskService.selectLdTaskById(taskId);
            } else {
                task = ldTaskService.selectLdTaskByMapAndName(mapName, taskName);
            }
            
            if (task == null) {
                return buildErrorResponse(2, "任务不存在");
            }
            
            int result = ldTaskService.deleteLdTaskById(task.getId());
            
            Map<String, Object> response = new HashMap<>();
            response.put("status", result > 0);
            response.put("msg", result > 0 ? "任务删除成功" : "任务删除失败");
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("删除任务异常", e);
            return buildErrorResponse(4, "内部错误: " + e.getMessage());
        }
    }

    /**
     * 1.6 更新任务状态
     * PUT /v1/path/status
     */
    @ApiOperation("更新任务状态")
    @PutMapping("/path/status")
    public ResponseEntity<Map<String, Object>> updateTaskStatus(
            @ApiParam("任务ID") @RequestParam("taskId") Long taskId,
            @ApiParam("新状态") @RequestParam("status") String status) {
        try {
            LdTask task = ldTaskService.selectLdTaskById(taskId);
            if (task == null) {
                return buildErrorResponse(2, "任务不存在");
            }
            
            int result = ldTaskService.updateTaskStatus(taskId, status);
            
            Map<String, Object> response = new HashMap<>();
            response.put("status", result > 0);
            response.put("msg", result > 0 ? "状态更新成功" : "状态更新失败");
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("更新任务状态异常", e);
            return buildErrorResponse(4, "内部错误: " + e.getMessage());
        }
    }

    /**
     * 1.7 获取任务执行记录
     * GET /v1/path/logs
     */
    @ApiOperation("获取任务执行记录")
    @GetMapping("/path/logs")
    public ResponseEntity<Map<String, Object>> getTaskLogs(
            @ApiParam("任务ID") @RequestParam(value = "taskId", required = false) Long taskId,
            @ApiParam("设备ID") @RequestParam(value = "deviceId", required = false) String deviceId,
            @ApiParam("地图名称") @RequestParam(value = "map", required = false) String mapName) {
        try {
            LdTaskExecutionLog logQuery = new LdTaskExecutionLog();
            if (taskId != null) {
                logQuery.setTaskId(taskId);
            }
            if (deviceId != null) {
                logQuery.setDeviceId(deviceId);
            }
            if (mapName != null) {
                logQuery.setMapName(mapName);
            }
            
            List<LdTaskExecutionLog> logs = ldTaskExecutionLogService.selectLdTaskExecutionLogList(logQuery);
            
            List<Map<String, Object>> logList = logs.stream().map(log -> {
                Map<String, Object> logMap = new HashMap<>();
                logMap.put("id", log.getId());
                logMap.put("taskId", log.getTaskId());
                logMap.put("taskName", log.getTaskName());
                logMap.put("mapName", log.getMapName());
                logMap.put("executeTime", log.getExecuteTime());
                logMap.put("endTime", log.getEndTime());
                logMap.put("status", log.getStatus());
                logMap.put("startWaypoint", log.getStartWaypoint());
                logMap.put("endWaypoint", log.getEndWaypoint());
                logMap.put("completedWaypoints", log.getCompletedWaypoints());
                logMap.put("totalWaypoints", log.getTotalWaypoints());
                logMap.put("errorCode", log.getErrorCode());
                logMap.put("errorMessage", log.getErrorMessage());
                logMap.put("deviceId", log.getDeviceId());
                return logMap;
            }).collect(Collectors.toList());
            
            Map<String, Object> response = new HashMap<>();
            response.put("status", true);
            response.put("logs", logList);
            response.put("total", logList.size());
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("获取任务执行记录异常", e);
            return buildErrorResponse(4, "内部错误: " + e.getMessage());
        }
    }

    /**
     * 1.8 获取设备今日执行记录
     * GET /v1/path/logs/today
     */
    @ApiOperation("获取设备今日执行记录")
    @GetMapping("/path/logs/today")
    public ResponseEntity<Map<String, Object>> getTodayExecutionLogs(
            @ApiParam("设备ID") @RequestParam("deviceId") String deviceId) {
        try {
            List<LdTaskExecutionLog> logs = ldTaskExecutionLogService.selectTodayExecutionLogsByDeviceId(deviceId);
            
            Map<String, Object> response = new HashMap<>();
            response.put("status", true);
            response.put("logs", logs);
            response.put("total", logs.size());
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("获取今日执行记录异常", e);
            return buildErrorResponse(4, "内部错误: " + e.getMessage());
        }
    }

    /**
     * 辅助方法：根据Cron表达式计算下次执行时间
     */
    private java.util.Date calculateNextExecuteTime(String cronExpression) {
        try {
            CronTrigger cronTrigger = new CronTrigger(cronExpression);
            SimpleTriggerContext triggerContext = new SimpleTriggerContext();

            return cronTrigger.nextExecutionTime(triggerContext);
        } catch (Exception e) {
            logger.warn("解析Cron表达式失败: {}", cronExpression, e);
            return null;
        }
    }

    /**
     * 构建错误响应
     */
    private ResponseEntity<Map<String, Object>> buildErrorResponse(int code, String msg) {
        Map<String, Object> response = new HashMap<>();
        response.put("status", false);
        response.put("code", code);
        response.put("msg", msg);
        return ResponseEntity.ok(response);
    }
}
