package com.yupi.project.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.yupi.project.model.entity.RobotTask;
import com.yupi.project.model.enums.CommandTypeEnum;

import java.util.Date;
import java.util.List;

/**
* @author Yupi
* @description 针对表【robot_task(机器人指令任务表)】的数据库操作Service
* @createDate 2023-12-02 22:00:00
*/
public interface RobotTaskService extends IService<RobotTask> {

    /**
     * 检查指定机器人是否有正在处理（PENDING 或 SENT）的任务。
     *
     * @param robotId 机器人ID
     * @return 如果有待处理或已发送任务，则返回 true，否则 false
     */
    boolean hasPendingOrSentTask(String robotId);

    /**
     * 检查指定机器人是否有正在处理（PENDING 或 SENT）的任务, 排除指定的任务ID。
     *
     * @param robotId 机器人ID
     * @param taskIdToExclude 要排除的任务ID (可以为 null)
     * @return 如果有其他待处理或已发送任务，则返回 true，否则 false
     */
    boolean hasOtherPendingOrSentTask(String robotId, Long taskIdToExclude);

    /**
     * 创建一个新的机器人指令任务。
     *
     * @param robotId       机器人ID
     * @param commandType   命令类型
     * @param payloadJson   命令参数 (JSON格式)
     * @param sessionId     关联的充电会话ID (可选)
     * @return 创建的任务实体
     */
    RobotTask createTask(String robotId, CommandTypeEnum commandType, String payloadJson, Long sessionId);

    /**
     * 将任务标记为已发送。
     *
     * @param taskId    任务ID
     * @param sentTime  命令发送时间
     * @return 是否成功标记
     */
    boolean markTaskAsSent(Long taskId, Date sentTime);

    /**
     * 根据机器人ID查找最近一个已发送（SENT）但尚未收到响应的任务。
     *
     * @param robotId 机器人ID
     * @return 如果找到，则返回任务实体，否则返回 null
     */
    RobotTask findLatestSentTaskByRobotId(String robotId);

    /**
     * 将任务标记为已确认（成功或失败）。
     * 注意：此方法后续可能被更具体的状态更新方法 (如 markTaskAsCompleted, markTaskAsFailed) 替代或补充。
     *
     * @param taskId        任务ID
     * @param success       是否成功
     * @param errorMessage  失败时的错误信息 (如果 success 为 true，则此参数可为 null)
     * @param ackTime       命令确认时间
     * @return 是否成功标记
     */
    boolean markTaskAsAcknowledged(Long taskId, boolean success, String errorMessage, Date ackTime);

    /**
     * 查找并标记超时的已发送任务。
     * 将状态为 SENT 且发送时间早于 (当前时间 - timeoutSeconds) 的任务标记为 TIMED_OUT。
     *
     * @param timeoutSeconds 超时秒数
     * @return 被标记为超时的任务列表
     */
    List<RobotTask> findAndMarkTimedOutTasks(int timeoutSeconds);

    /**
     * 将任务标记为处理中。
     *
     * @param taskId    任务ID
     * @param ackTime   确认处理中的时间 (可选)
     * @param message   附加信息 (可选)
     * @return 是否成功标记
     */
    boolean markTaskAsProcessing(Long taskId, Date ackTime, String message);

    /**
     * 将任务标记为已完成。
     *
     * @param taskId    任务ID
     * @param ackTime   完成时间 (可选)
     * @param message   附加信息 (可选, 例如成功消息)
     * @return 是否成功标记
     */
    boolean markTaskAsCompleted(Long taskId, Date ackTime, String message);

    /**
     * 标记任务为失败
     *
     * @param taskId 任务ID
     * @param errorMessage 错误信息
     * @param failedTime 失败时间
     * @return 是否成功
     */
    boolean markTaskAsFailed(Long taskId, String errorMessage, Date failedTime);

    /**
     * 根据机器人ID和会话ID查找最新的任务。
     *
     * @param robotId 机器人ID
     * @param sessionId 会话ID
     * @return 如果找到，则返回任务实体，否则返回 null
     */
    RobotTask findLatestTaskByRobotIdAndSessionId(String robotId, Long sessionId);

} 