package com.zhentao.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhentao.entity.UserVip;
import com.zhentao.service.UserVipService;
import com.zhentao.mapper.UserVipMapper;
import com.zhentao.vo.ResultVo;
import com.zhentao.vo.UserVipVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class UserVipServiceImpl extends ServiceImpl<UserVipMapper, UserVip>
        implements UserVipService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public ResultVo getUserMessageLimit(Long userId, Long targetUserId) {
        // 1. 先查Redis：判断用户是否有有效VIP（缓存中存在即有效）
        String vipRedisKey = "user:vip:" + userId;
        if (redisTemplate.hasKey(vipRedisKey)) {
            UserVipVo vipVo = new UserVipVo();
            vipVo.setVip(true);
            vipVo.setRemainingCount(-1);
            vipVo.setHasMessageLimit(false);
            return ResultVo.success("success", vipVo);
        }

        // 2. Redis无缓存，查数据库：查询用户未过期的VIP
        QueryWrapper<UserVip> queryWrapper = new QueryWrapper<>();
        Date nowDate = new Date(); // 与endTime（Date类型）匹配
        queryWrapper.lambda()
                .eq(UserVip::getUserId, userId)
                .gt(UserVip::getEndTime, nowDate); // 类型匹配，避免SQL错误

        List<UserVip> userVips = baseMapper.selectList(queryWrapper);
        if (!CollUtil.isEmpty(userVips)) {
            for (UserVip vip : userVips) {
                Date endTime = vip.getEndTime();
                if (endTime == null) continue; // 跳过无效数据

                // 计算过期时间（毫秒差）
                long expireMillis = endTime.getTime() - nowDate.getTime();
                if (expireMillis > 0) {
                    // 缓存VIP标记（无需存整个对象），到期自动删除
                    redisTemplate.opsForValue().set(vipRedisKey, Boolean.TRUE, expireMillis, TimeUnit.MILLISECONDS);
                    // 返回VIP权限
                    UserVipVo vipVo = new UserVipVo();
                    vipVo.setVip(true);
                    vipVo.setRemainingCount(-1);
                    vipVo.setHasMessageLimit(false);
                    return ResultVo.success("success", vipVo);
                }
            }
        }

        // 3. 非VIP用户：处理消息次数限制
        UserVipVo normalVo = new UserVipVo();
        normalVo.setVip(false);
        normalVo.setHasMessageLimit(true);

        String msgCountRedisKey = "msg:count:" + userId + ":" + targetUserId;
        // 安全获取缓存（避免类型转换异常）
//        Integer remainingCount = redisTemplate.opsForValue().get(msgCountRedisKey, Integer.class);
        Object value = redisTemplate.opsForValue().get(msgCountRedisKey);
        Integer remainingCount = (value != null) ? (Integer) value : null;

        if (remainingCount == null) {
            // 初始化缓存：当前时间到明天凌晨的秒数
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime midnight = LocalDateTime.of(LocalDate.now().plusDays(1), LocalTime.MIN);
            long expireSeconds = ChronoUnit.SECONDS.between(now, midnight);

            // 时间单位改为SECONDS，与计算结果一致
            redisTemplate.opsForValue().set(msgCountRedisKey, 5, expireSeconds, TimeUnit.SECONDS);
            remainingCount = 5;
        }

        normalVo.setRemainingCount(remainingCount);
        return ResultVo.success("success", normalVo);
    }

    @Override
    public ResultVo updateMessageCount(Long userId, Long targetUserId) {
        // 1. 先判断用户是否为VIP（从Redis缓存获取，与getUserMessageLimit逻辑一致）
        Boolean isVip = (Boolean) redisTemplate.opsForValue().get("user:vip:" + userId);
        if (isVip != null && isVip) {
            // VIP用户无限制，直接返回
            return ResultVo.success("VIP用户无次数限制",
                    new UserVipVo( true,-1,false));
        }

        // 2. 非VIP用户：构造Redis键（与前端一致：msg:count:userId:targetUserId）
        String redisKey = "msg:count:" + userId + ":" + targetUserId;

        // 3. 获取当前剩余次数（不存在则默认5次，防止缓存穿透）
        Integer remainingCount = (Integer) redisTemplate.opsForValue().get(redisKey);
        if (remainingCount == null) {
            remainingCount = 5;
        }

        // 4. 递减次数（最小为0，不能为负数）
        remainingCount = Math.max(remainingCount - 1, 0);

        // 5. 更新Redis缓存（保持与前端一致的过期时间：到次日凌晨）
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime midnight = LocalDateTime.of(LocalDate.now().plusDays(1), LocalTime.MIN);
        long expireSeconds = ChronoUnit.SECONDS.between(now, midnight);
        redisTemplate.opsForValue().set(redisKey, remainingCount, expireSeconds, TimeUnit.SECONDS);

        // 6. 返回更新后的结果
        return ResultVo.success("更新成功",
                new UserVipVo( false,remainingCount, true));
}
}