package com.bicloud.service.impl;

import com.bicloud.common.result.Result;
import com.bicloud.common.utils.RegexUtils;
import com.bicloud.service.UserService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;

import static com.bicloud.common.utils.RedisConstants.*;


@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Result sendCode(String phone, HttpSession session, HttpServletRequest request) {
        // 1.校验手机号
        if (RegexUtils.isPhoneInvalid(phone)) {
            // 2.如果不符合，返回错误信息
            return Result.error("手机号格式错误！");
        }

        // 3. 获取客户端IP地址
        String clientIpAddr = request.getRemoteAddr();

        // 4.如果存在锁，直接返回失败
        String phoneGetCodeLock = stringRedisTemplate.opsForValue().get(GET_CODE_LOCK + phone);
        if (phoneGetCodeLock != null) {
            return Result.error("获取验证码过快，请稍后重试！");
        }

        // 5.检查两个黑名单中的次数
        String blacklistPhoneCount = stringRedisTemplate.opsForValue().get(GET_CODE_BLACKLIST_PHONE + phone);
        int getCodePhoneCount = (blacklistPhoneCount != null) ? Integer.parseInt(blacklistPhoneCount) : 0;
        if (getCodePhoneCount >= 400) {
            return Result.error("获取验证码次数过多，您的手机号已被限制！");
        }

        String blacklistIpAddrCount = stringRedisTemplate.opsForValue().get(GET_CODE_BLACKLIST_IP_ADDR + clientIpAddr);
        int getCodeIpAddrCount = (blacklistIpAddrCount != null) ? Integer.parseInt(blacklistIpAddrCount) : 0;
        if (getCodeIpAddrCount >= 300) {
            return Result.error("获取验证码次数过多，您的IP已被限制！");
        }

        // 6.更新锁和黑名单
        stringRedisTemplate.opsForValue().set(GET_CODE_BLACKLIST_PHONE + phone, String.valueOf(getCodePhoneCount + 1), REFRESH_BLACKLIST_TTL, TimeUnit.HOURS);
        stringRedisTemplate.opsForValue().set(GET_CODE_BLACKLIST_IP_ADDR + clientIpAddr, String.valueOf(getCodeIpAddrCount + 1), REFRESH_BLACKLIST_TTL, TimeUnit.HOURS);
        stringRedisTemplate.opsForValue().set(GET_CODE_LOCK + phone, "1", GET_CODE_LOCK_TTL, TimeUnit.MINUTES);

        // 7.校验通过，生成验证码
//        String code = RandomUtil.randomNumbers(6);
        String code = "123123"; //为了方便测试，改成固定值

        // 8.保存验证码到 redis，并上锁
        stringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY + phone, code, LOGIN_CODE_TTL, TimeUnit.MINUTES);

        // 9.发送验证码
        log.debug("发送短信验证码成功，验证码：{}", code);
        // 10.返回ok
        return Result.success("发送短信验证码成功，验证码："+code);
    }


}
