package org.xyzh.crontab.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.xyzh.api.crontab.CrontabService;
import org.xyzh.api.crontab.TaskMetaService;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.dto.crontab.TbCrontabTaskMeta;
import org.xyzh.common.core.page.PageParam;
import org.xyzh.common.core.page.PageRequest;
import org.xyzh.common.dto.crontab.CreateTaskRequest;
import org.xyzh.common.dto.crontab.TbCrontabTask;
import org.xyzh.common.dto.crontab.TbCrontabLog;


/**
 * @description 定时任务控制器
 * @filename CrontabController.java
 * @author yslg
 * @copyright xyzh
 * @since 2025-10-25
 */
@RestController
@RequestMapping("/crontab")
public class CrontabController {

    private static final Logger logger = LoggerFactory.getLogger(CrontabController.class);

    @Autowired
    private CrontabService crontabService;

    @Autowired
    private TaskMetaService taskMetaService;

    /**
     * 获取可创建的定时任务（从数据库获取任务元数据列表）
     * @return ResultDomain<TbCrontabTaskMeta>
     */
    @GetMapping("/getEnabledCrontabList")
    public ResultDomain<TbCrontabTaskMeta> getEnabledCrontabList(@RequestParam(required = false) String param) {
        try {
            // 从数据库查询所有任务元数据
            ResultDomain<TbCrontabTaskMeta> result =  taskMetaService.getAllTaskMeta();
            result.getDataList().forEach(item->{
                item.setBeanName("");
                item.setMethodName("");
                item.setScriptPath("");
            });
            return result;
        } catch (Exception e) {
            ResultDomain<TbCrontabTaskMeta> rd = new ResultDomain<>();
            rd.fail("获取可创建定时任务失败: " + e.getMessage());
            return rd;
        }
    }

    /**
     * 创建定时任务并绑定邮件接收人（从数据库获取元数据配置）
     * @param request 创建任务请求（包含任务信息、元数据ID、是否使用默认接收人、额外接收人列表）
     * @return ResultDomain<TbCrontabTask>
     */
    @PostMapping("/crontabTask")
    public ResultDomain<TbCrontabTask> createCrontab(@RequestBody CreateTaskRequest request) {
        ResultDomain<TbCrontabTask> rd = new ResultDomain<>();
        try {
            TbCrontabTask crontabItem = request.getTask();
            String metaId = request.getMetaId();
            
            // 验证元数据ID
            if (metaId == null || metaId.isEmpty()) {
                rd.fail("任务元数据ID不能为空");
                return rd;
            }
            
            // 从数据库查询任务元数据
            ResultDomain<TbCrontabTaskMeta> metaResult = taskMetaService.getTaskMetaById(metaId);
            if (!metaResult.isSuccess() || metaResult.getData() == null) {
                rd.fail("未找到对应的任务元数据: metaId=" + metaId);
                return rd;
            }
            
            TbCrontabTaskMeta taskMeta = metaResult.getData();
            
            // 填充任务信息
            crontabItem.setTaskGroup(taskMeta.getCategory()); // 任务分组使用category
            crontabItem.setBeanName(taskMeta.getBeanName());
            crontabItem.setMethodName(taskMeta.getMethodName());
            crontabItem.setMetaId(metaId); // 保存metaId，执行时从数据库读取scriptPath
            
            logger.info("创建任务并绑定接收人 - metaId: {}, name: {}, category: {}, defaultRecipient: {}, additionalCount: {}",
                metaId, taskMeta.getName(), taskMeta.getCategory(),
                crontabItem.getDefaultRecipient(),
                request.getAdditionalRecipients() != null ? request.getAdditionalRecipients().size() : 0);
            
            return crontabService.createTaskWithRecipients(request);
        } catch (Exception e) {
            logger.error("创建定时任务并绑定接收人失败", e);
            rd.fail("创建定时任务并绑定接收人失败: " + e.getMessage());
            return rd;
        }
    }

    /**
     * 更新定时任务并更新邮件接收人（从数据库获取元数据配置）
     * @param request 更新任务请求（包含任务信息、元数据ID、是否使用默认接收人、额外接收人列表）
     * @return ResultDomain<TbCrontabTask>
     */
    @PutMapping("/crontabTask")
    public ResultDomain<TbCrontabTask> updateCrontab(@RequestBody CreateTaskRequest request) {
        ResultDomain<TbCrontabTask> rd = new ResultDomain<>();
        try {
            TbCrontabTask crontabItem = request.getTask();
            String metaId = request.getMetaId();
            
            // 确保id字段正确传递（用于数据库更新）
            if (crontabItem.getTaskId() != null && crontabItem.getID() == null) {
                crontabItem.setID(crontabItem.getTaskId());
            }
            
            // 验证元数据ID
            if (metaId == null || metaId.isEmpty()) {
                rd.fail("任务元数据ID不能为空");
                return rd;
            }
            
            // 从数据库查询任务元数据
            ResultDomain<TbCrontabTaskMeta> metaResult = taskMetaService.getTaskMetaById(metaId);
            if (!metaResult.isSuccess() || metaResult.getData() == null) {
                rd.fail("未找到对应的任务元数据: metaId=" + metaId);
                return rd;
            }
            
            TbCrontabTaskMeta taskMeta = metaResult.getData();
            
            // 填充任务信息
            crontabItem.setTaskGroup(taskMeta.getCategory());
            crontabItem.setBeanName(taskMeta.getBeanName());
            crontabItem.setMethodName(taskMeta.getMethodName());
            crontabItem.setMetaId(metaId); // 保存metaId，执行时从数据库读取scriptPath
            
            logger.info("更新任务 - id: {}, metaId: {}, name: {}, category: {}, defaultRecipient: {}",
                crontabItem.getID(), metaId, taskMeta.getName(), taskMeta.getCategory(),
                crontabItem.getDefaultRecipient());
            
            // 调用带接收人更新的方法
            return crontabService.updateTaskWithRecipients(request);
        } catch (Exception e) {
            logger.error("更新定时任务并更新接收人失败", e);
            rd.fail("更新定时任务并更新接收人失败: " + e.getMessage());
            return rd;
        }
    }

    /**
     * 删除定时任务
     * @param crontabItem
     * @return
     */
    @DeleteMapping("/crontabTask")
    public ResultDomain<TbCrontabTask> deleteCrontab(@RequestBody TbCrontabTask crontabItem) {
        ResultDomain<TbCrontabTask> rd = new ResultDomain<>();
        try {
            if (crontabItem.getTaskId() == null || crontabItem.getTaskId().isEmpty()) {
                rd.fail("任务ID不能为空");
                return rd;
            }
            return crontabService.deleteTask(crontabItem.getTaskId());
        } catch (Exception e) {
            logger.error("删除定时任务失败", e);
            rd.fail("删除定时任务失败: " + e.getMessage());
            return rd;
        }
    }

    /**
     * 获取定时任务分页列表
     * @param pageParam
     * @return
     */
    @PostMapping("/crontabTaskPage")
    public ResultDomain<TbCrontabTask> getCrontabTask(@RequestBody PageRequest<TbCrontabTask> pageRequest) {
        ResultDomain<TbCrontabTask> rd = new ResultDomain<>();
        try {
            TbCrontabTask filter = pageRequest.getFilter();
            PageParam pageParam = pageRequest.getPageParam();
            return crontabService.getTaskPage(filter, pageParam);
        } catch (Exception e) {
            logger.error("获取定时任务分页列表失败", e);
            rd.fail("获取定时任务分页列表失败: " + e.getMessage());
            return rd;
        }
    }

    /**
     * 获取定时任务日志分页列表
     * @param pageRequest
     * @return
     */
    @PostMapping("/crontabTaskLogPage")
    public ResultDomain<TbCrontabLog> getCrontabTaskLog(@RequestBody PageRequest<TbCrontabLog> pageRequest) {
        ResultDomain<TbCrontabLog> rd = new ResultDomain<>();
        try {
            TbCrontabLog filter = pageRequest.getFilter();
            PageParam pageParam = pageRequest.getPageParam();
            return crontabService.getLogPage(filter, pageParam);
        } catch (Exception e) {
            logger.error("获取定时任务日志分页列表失败", e);
            rd.fail("获取定时任务日志分页列表失败: " + e.getMessage());
            return rd;
        }
    }

    /**
     * 根据ID查询日志详情
     * @param logId 日志ID
     * @return ResultDomain<TbCrontabLog>
     */
    @GetMapping("/log/{logId}")
    public ResultDomain<TbCrontabLog> getLogById(@PathVariable(required = true, name="logId") String logId) {
        ResultDomain<TbCrontabLog> rd = new ResultDomain<>();
        try {
            return crontabService.getLogById(logId);
        } catch (Exception e) {
            logger.error("获取日志详情失败", e);
            rd.fail("获取日志详情失败: " + e.getMessage());
            return rd;
        }
    }

    @GetMapping("/task/validate")
    public ResultDomain<String> validateCronExpression(@RequestParam(required = true, name="cronExpression") String cronExpression) {
        ResultDomain<String> rd = new ResultDomain<>();
        try {
            return crontabService.validateCronExpression(cronExpression);
        } catch (Exception e) {
            logger.error("验证Cron表达式失败", e);
            rd.fail("验证Cron表达式失败: " + e.getMessage());
            return rd;
        }
    }
    

    /**
     * @description    启动定时任务
     * @param    
     * @author    yslg
     * @since 2025-11-11
     */
    @PostMapping("/task/start/{taskId}")
    public ResultDomain<TbCrontabTask> startTask(@PathVariable(required = true, name="taskId") String taskId) {
        ResultDomain<TbCrontabTask> rd = new ResultDomain<>();
        try {
            return crontabService.startTask(taskId);
        } catch (Exception e) {
            logger.error("启动定时任务失败", e);
            rd.fail("启动定时任务失败: " + e.getMessage());
            return rd;
        }
    }

    /**
     * @description    暂停定时任务
     * @param    
     * @author    yslg
     * @since 2025-11-11
     */
    @PostMapping("/task/pause/{taskId}")
    public ResultDomain<TbCrontabTask> pauseTask(@PathVariable(required = true, name="taskId") String taskId) {
        ResultDomain<TbCrontabTask> rd = new ResultDomain<>();
        try {
            return crontabService.pauseTask(taskId);
        } catch (Exception e) {
            logger.error("暂停定时任务失败", e);
            rd.fail("暂停定时任务失败: " + e.getMessage());
            return rd;
        }
    }

    /**
     * @description    立即执行一次任务
     * @param    
     * @author    yslg
     * @since 2025-11-11
     */
    @PostMapping("/task/execute/{taskId}")
    public ResultDomain<TbCrontabTask> executeTaskOnce(@PathVariable(required = true, name="taskId") String taskId) {
        ResultDomain<TbCrontabTask> rd = new ResultDomain<>();
        try {
            return crontabService.executeTaskOnce(taskId);
        } catch (Exception e) {
            logger.error("执行定时任务失败", e);
            rd.fail("执行定时任务失败: " + e.getMessage());
            return rd;
        }
    }
}
