package com.izouma.nineth.service;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.izouma.nineth.config.RedisKeys;
import com.izouma.nineth.dto.CaptchaDTO;
import com.izouma.nineth.enums.CaptchaType;
import com.izouma.nineth.exception.BusinessException;
import com.izouma.nineth.utils.IPUtils;
import com.izouma.nineth.utils.Result;
import com.izouma.nineth.utils.ValidateCodeUtils;
import com.izouma.nineth.utils.VerifyImageUtil;
import com.wf.captcha.ArithmeticCaptcha;
import com.wf.captcha.ChineseCaptcha;
import com.wf.captcha.ChineseGifCaptcha;
import com.wf.captcha.SpecCaptcha;
import com.wf.captcha.base.Captcha;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.ehcache.UserManagedCache;
import org.ehcache.config.builders.ExpiryPolicyBuilder;
import org.ehcache.config.builders.UserManagedCacheBuilder;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
@AllArgsConstructor
public class EasyCaptchaService {
    private static final String IMG_PATH1 = "/static/image/picture1/*.*";
    private static final String IMG_PATH2 = "/static/image/picture2/*.*";
    private static final String IMG_PATH3 = "/static/image/picture3/*.*";
    private static final String TEMP_IMG_PATH = "/static/image/temp/*.*";
    private RedisTemplate<String, Object> redisTemplate;



    public boolean verify(String redisKey,String chenckMoveid, String clientxWidth, boolean clear) {
        if (ObjectUtil.isNull(chenckMoveid) || ObjectUtil.isNull(clientxWidth)) {
            throw new BusinessException("请使用滑块验证码");
        } else {
            // 获取readis缓存的随机数
            Object x_index_orld = redisTemplate.opsForValue().get(redisKey + chenckMoveid);
            if (ObjectUtil.isNull(x_index_orld)) {
                throw new BusinessException("请使用滑块验证码");
            } else {
                Double dMoveLength = Double.valueOf(x_index_orld.toString());
                Double xWidth = Double.valueOf(clientxWidth);
                if (Math.abs(xWidth - dMoveLength) > 10) {
                    //验证不通过，这个地方需要注意一下，不管他是否验证通过，都需要重置一下图片和坐标位置，避免暴力破解
                    redisTemplate.delete(redisKey + chenckMoveid);
                    throw new BusinessException("请拖动到正确的位置");
                }
            }
            //验证通过
            if (clear) {
                redisTemplate.delete(redisKey + chenckMoveid);
            }
            return true;
        }
    }


    public Result gen(String reidskey ,int type ,int expiration_time) throws Exception {
        // 读取图库目录
        String path = type == 1 ? IMG_PATH1 : type == 2 ? IMG_PATH2 : IMG_PATH3;
        InputStream targetFile = VerifyImageUtil.queryFileList(path);
        InputStream tempImgFile = VerifyImageUtil.queryFileList(TEMP_IMG_PATH);
        // 根据模板裁剪图片
        Map<String, Object> resultMap = VerifyImageUtil.pictureTemplatesCut(tempImgFile, targetFile);
        int xWidth = (int) resultMap.get("xWidth");
        String chenckMoveid = UUID.randomUUID().toString();
        BoundValueOperations<String, Object> redisOper = redisTemplate.boundValueOps(reidskey + chenckMoveid);
        redisOper.set(xWidth, expiration_time, TimeUnit.SECONDS);
        // 移除map的滑动距离，不返回给前端
        resultMap.remove("xWidth");
        resultMap.put("chenckMoveid", chenckMoveid);
        return Result.success().put("data", JSONObject.toJSON(resultMap).toString());
    }
}
