package com.gameplatform.server.mapper.agent;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gameplatform.server.model.entity.agent.LinkTask;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.time.LocalDateTime;
import java.util.List;

@Mapper
public interface LinkTaskMapper extends BaseMapper<LinkTask> {
    LinkTask findById(@Param("id") Long id);
    
    LinkTask findByCodeNo(@Param("codeNo") String codeNo);
    
    LinkTask findByTokenHash(@Param("tokenHash") String tokenHash);
    
    int insert(LinkTask linkTask);
    
    int update(LinkTask linkTask);
    
    int updateStatus(@Param("id") Long id, @Param("status") String status);
    
    int updateStatusAndMachine(@Param("id") Long id, 
                              @Param("status") String status,
                              @Param("region") String region,
                              @Param("machineId") String machineId,
                              @Param("loginAt") LocalDateTime loginAt);

    /**
     * 仅当新的点数更大时才更新 completed_points，避免不必要写锁
     */
    int updatePointsIfGreater(@Param("id") Long id,
                              @Param("newPoints") Integer newPoints);

    /**
     * 将指定设备上所有 LOGGED_IN 的任务标记为 COMPLETED，并写入原因与可选的完成点数。
     * 返回受影响的行数。
     */
    int completeLoggedInTasksByMachine(@Param("machineId") String machineId,
                                       @Param("reason") String reason,
                                       @Param("completedPoints") Integer completedPoints);
    
    List<LinkTask> findByAgentId(@Param("agentId") Long agentId,
                                @Param("size") int size,
                                @Param("offset") int offset);
    
    long countByAgentId(@Param("agentId") Long agentId);
    
    List<LinkTask> findByAgentIdAndStatus(@Param("agentId") Long agentId,
                                         @Param("status") String status,
                                         @Param("size") int size,
                                         @Param("offset") int offset);
    
    long countByAgentIdAndStatus(@Param("agentId") Long agentId,
                                @Param("status") String status);
    
    List<LinkTask> findByBatchId(@Param("batchId") Long batchId,
                                @Param("size") int size,
                                @Param("offset") int offset);
    
    long countByBatchId(@Param("batchId") Long batchId);
    
    List<LinkTask> findExpiredTasks(@Param("expireTime") LocalDateTime expireTime,
                                   @Param("size") int size);
    
    /**
     * 分页查询代理的链接任务（支持条件过滤和排序）
     */
    List<LinkTask> findLinkTasksWithConditions(@Param("agentId") Long agentId,
                                             @Param("status") String status,
                                             @Param("batchId") Long batchId,
                                             @Param("isExpired") Boolean isExpired,
                                             @Param("sortBy") String sortBy,
                                             @Param("sortDir") String sortDir,
                                             @Param("offset") int offset,
                                             @Param("size") int size);
    
    /**
     * 统计满足条件的链接任务数量
     */
    long countLinkTasksWithConditions(@Param("agentId") Long agentId,
                                    @Param("status") String status,
                                    @Param("batchId") Long batchId,
                                    @Param("isExpired") Boolean isExpired);
    
    /**
     * 根据链接编号删除链接任务
     */
    int deleteByCodeNo(@Param("codeNo") String codeNo);
    
    /**
     * 根据链接编号和代理ID删除链接任务（确保用户只能删除自己的链接）
     */
    int deleteByCodeNoAndAgentId(@Param("codeNo") String codeNo, @Param("agentId") Long agentId);
    
    /**
     * 批量删除链接任务（根据链接编号列表和代理ID）
     */
    int batchDeleteByCodeNosAndAgentId(@Param("codeNos") List<String> codeNos, @Param("agentId") Long agentId);
    
    /**
     * 根据链接编号列表和代理ID查询链接任务（用于验证权限）
     */
    List<LinkTask> findByCodeNosAndAgentId(@Param("codeNos") List<String> codeNos, @Param("agentId") Long agentId);
    
    /**
     * 根据设备ID和状态查询链接任务
     */
    List<LinkTask> findByMachineIdAndStatus(@Param("machineId") String machineId, @Param("status") String status);
    
    /**
     * 根据状态列表和代理ID查询链接任务（用于验证权限和获取要删除的链接）
     */
    List<LinkTask> findByStatusListAndAgentId(@Param("statusList") List<String> statusList, @Param("agentId") Long agentId);
    
    /**
     * 根据状态列表和代理ID统计链接任务数量
     */
    long countByStatusListAndAgentId(@Param("statusList") List<String> statusList, @Param("agentId") Long agentId);
    
    /**
     * 根据状态列表和代理ID批量删除链接任务
     */
    int batchDeleteByStatusListAndAgentId(@Param("statusList") List<String> statusList, @Param("agentId") Long agentId);
    
    /**
     * 根据状态查询所有链接任务
     */
    List<LinkTask> findByStatus(@Param("status") String status);

    /**
     * 原子方式占用设备：仅当该设备当前未被 USING/LOGGED_IN 占用时，
     * 才将指定任务更新为 USING 并写入设备与时间字段。
     * 返回受影响行数（1=成功，0=设备已被占用）。
     */
    int reserveDeviceIfFree(@Param("id") Long id,
                            @Param("region") String region,
                            @Param("deviceId") String deviceId,
                            @Param("qrExpireSeconds") int qrExpireSeconds);
}
