package com.backendsys.modules.common.config.security.utils;

import cn.hutool.core.convert.Convert;
import com.backendsys.modules.common.config.redis.utils.RedisUtil;
import com.google.code.kaptcha.Producer;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Component
public class CaptchaUtil {

    @Autowired
    private Environment env;

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private HttpRequestUtil httpRequestUtil;
    @Autowired
    private Producer captchaProducer;
    @Value("${CAPTCHA_DURATION}")
    private Integer CAPTCHA_DURATION;

    /**
     * 判断是否需要 验证码 (errCount: 错误次数)
     */
    public Boolean isCaptchaRequired(String captchaRedisKey, Integer errCount) {
        Object captchaValue = redisUtil.getCacheObject(captchaRedisKey);
        if (captchaValue != null) {
            Integer captchaValueToInt = Convert.toInt(captchaValue);
            if (captchaValueToInt >= errCount) {
                return true;
            }
        }
        return false;
    }

    /**
     * 校验 验证码
     */
    public Boolean isCaptchaValid(String captcha, String captchaRedisKey) {
        String captchaRedisValue = redisUtil.getCacheObject(captchaRedisKey);
        if (captchaRedisValue == null || !captchaRedisValue.equalsIgnoreCase(captcha)) {
            return false;
        }
        return true;
    }

    /**
     * 生成 验证码
     */
    public void renderCaptcha(HttpServletResponse response) throws IOException {
        byte[] captchaChallengeAsJpeg;
        ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
        try {
            String createText = captchaProducer.createText();
            // 获得当前 (UA + IP) 生成的 Key
            String captchaRedisKey = httpRequestUtil.getKaptchaKey();
            // 保存 验证码字符串 到 redis 中
            redisUtil.setCacheObject(captchaRedisKey, createText, this.CAPTCHA_DURATION, TimeUnit.MILLISECONDS);
            // 返回 BufferedImage 对象并转为 byte 写入到 byte 数组中
            BufferedImage challenge = captchaProducer.createImage(createText);
            ImageIO.write(challenge, "jpg", jpegOutputStream);
        } catch (Exception e) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
        }
        // 定义response输出类型为image/jpeg类型，使用response输出流输出图片的byte数组
        captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
        response.setHeader("Cache-Control", "no-store");
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");
        ServletOutputStream responseOutputStream = response.getOutputStream();
        responseOutputStream.write(captchaChallengeAsJpeg);
        responseOutputStream.flush();
        responseOutputStream.close();
    }

}
