package top.tqx.demo_1.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import top.tqx.demo_1.service.ExamLockService;

import java.time.Duration;

@Slf4j
@Service
public class ExamLockServiceImpl implements ExamLockService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final String EXAM_LOCK_KEY = "exam:lock:%s:%s";
    private static final long LOCK_EXPIRE_HOURS = 2;

    @Override
    public boolean tryAcquireLock(String paperId, Long userId, String sessionId) {
        String lockKey = String.format(EXAM_LOCK_KEY, paperId, userId);
        String existingSession = redisTemplate.opsForValue().get(lockKey);

        if (existingSession != null && !existingSession.equals(sessionId)) {
            log.warn("用户 {} 尝试获取试卷 {} 的锁失败，已有会话 {} 在进行中", userId, paperId, existingSession);
            return false;
        }

        Boolean success = redisTemplate.opsForValue().setIfAbsent(lockKey, sessionId, Duration.ofHours(LOCK_EXPIRE_HOURS));
        boolean result = Boolean.TRUE.equals(success);
        
        if (result) {
            log.info("用户 {} 成功获取试卷 {} 的锁，会话ID: {}", userId, paperId, sessionId);
        } else {
            redisTemplate.opsForValue().set(lockKey, sessionId, Duration.ofHours(LOCK_EXPIRE_HOURS));
            log.info("用户 {} 续期试卷 {} 的锁，会话ID: {}", userId, paperId, sessionId);
        }
        
        return true;
    }

    @Override
    public void releaseLock(String paperId, Long userId) {
        String lockKey = String.format(EXAM_LOCK_KEY, paperId, userId);
        Boolean deleted = redisTemplate.delete(lockKey);
        
        if (Boolean.TRUE.equals(deleted)) {
            log.info("用户 {} 释放试卷 {} 的锁成功", userId, paperId);
        } else {
            log.debug("用户 {} 释放试卷 {} 的锁，锁已不存在", userId, paperId);
        }
    }

    @Override
    public boolean isLocked(String paperId, Long userId) {
        String lockKey = String.format(EXAM_LOCK_KEY, paperId, userId);
        return Boolean.TRUE.equals(redisTemplate.hasKey(lockKey));
    }
}