package com.cnooc.expert.auth.service.impl;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.cnooc.expert.common.cache.RedisKeys;
import com.cnooc.expert.auth.service.*;
import com.cnooc.expert.controller.auth.model.response.SlideCaptchaVO;
import com.cnooc.expert.system.entity.pojo.CaptchaData;
import com.cnooc.expert.system.entity.pojo.SlideImageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import com.cnooc.expert.system.entity.vo.SysCaptchaVO;
import com.wf.captcha.SpecCaptcha;
import com.wf.captcha.base.Captcha;
import org.apache.commons.lang3.StringUtils;

import java.util.concurrent.TimeUnit;

@Service
public class SysCaptchaServiceImpl implements SysCaptchaService {
    private static final int EXPIRE_MINUTES = 5;

    @Autowired
    private SlideCaptchaService slideCaptchaService;

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Override
    public SysCaptchaVO generate() {
        // 生成验证码key
        String key = UUID.randomUUID().toString();

        // 生成验证码
        SpecCaptcha captcha = new SpecCaptcha(150, 40);
        captcha.setLen(4);
        captcha.setCharType(Captcha.TYPE_DEFAULT);
        String image = captcha.toBase64();

        // 保存到缓存
        String redisKey = RedisKeys.getCaptchaKey(key);
        redisTemplate.opsForValue().set(redisKey, captcha.text(), EXPIRE_MINUTES, TimeUnit.MINUTES);

        // 封装返回数据
        SysCaptchaVO captchaVO = new SysCaptchaVO();
        captchaVO.setKey(key);
        captchaVO.setImage(image);

        return captchaVO;
    }

    @Override
    public SlideCaptchaVO generateSlide(){
        try {
            // 1. 生成背景图和滑块图
            SlideImageResult imageResult = slideCaptchaService.generateSlideImages();

            // 2. 生成随机位置
//            int x = ThreadLocalRandom.current().nextInt(50, 250);
//            int y = ThreadLocalRandom.current().nextInt(10, 150);
            int x = imageResult.getSliderX();
            int y = imageResult.getSliderY();

            // 3. 生成唯一标识
            String token = UUID.randomUUID().toString();

            // 4. 存储验证数据到Redis (5分钟过期)
            CaptchaData captchaData = new CaptchaData(x, y, System.currentTimeMillis());
            redisTemplate.opsForValue().set(
                    "captcha:" + token,
                    JSON.toJSONString(captchaData),
                    5, TimeUnit.MINUTES
            );

            // 5. 返回前端所需数据
            SlideCaptchaVO vo = new SlideCaptchaVO();
            vo.setToken(token);
            vo.setBackgroundImage(imageResult.getBackgroundBase64());
            vo.setSlideImage(imageResult.getSlideBase64());
            vo.setStartY(y);

            return vo;
        } catch (Exception e) {
            return null;
        }
    }


    @Override
    public boolean validate(String key, String code) {
        // 如果关闭了验证码，则直接效验通过
        if (!isCaptchaEnabled()) {
            return true;
        }

        if (StrUtil.isBlank(key) || StrUtil.isBlank(code)) {
            return false;
        }

        // 获取验证码
        String captcha = getCache(key);

        // 效验成功
        return code.equalsIgnoreCase(captcha);
    }

    @Override
    public boolean validateSlide(String token, Integer moveX) {
        // 如果关闭了验证码，则直接效验通过
        if (!isCaptchaEnabled()) {
            return true;
        }

        if (StrUtil.isBlank(token)) {
            return false;
        }

        // 1. 从Redis获取验证数据
        String newkey = "captcha:" + token;
        String dataStr = redisTemplate.opsForValue().get(newkey);

        if (StringUtils.isEmpty(dataStr)) {
            return false;
        }

        // 2. 解析数据
        CaptchaData captchaData = JSON.parseObject(dataStr, CaptchaData.class);

        // 3. 验证滑动距离 (允许±3像素的误差)
        int expectedX = captchaData.getX();
        int actualX = moveX;

        if (Math.abs(actualX - expectedX) <= 3) {
            // 验证成功，删除Redis中的key
            redisTemplate.delete(newkey);
            return true;
        } else {
            return false;
        }
    }

    @Override
    public boolean isCaptchaEnabled() {
        return true;
    }

    private String getCache(String key) {
        key = RedisKeys.getCaptchaKey(key);
        String captcha = redisTemplate.opsForValue().get(key);
        // 删除验证码
        if (captcha != null) {
            redisTemplate.delete(key);
        }

        return captcha;
    }

}
