package com.qnfhq.interceptor.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.qnfhq.annotation.RepeatSubmit;
import com.qnfhq.common.redis.RedisUtils;
import com.qnfhq.common.utils.IpUtils;
import com.qnfhq.constant.CacheConstants;
import com.qnfhq.interceptor.RepeatSubmitInterceptor;
import com.qnfhq.utils.http.HttpHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;

import jakarta.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

/**
 * 判断请求url和数据是否和上一次相同，
 * 如果和上次相同，则是重复提交表单。 有效时间为10秒内。
 *
 * @author Table
 */
@Component
public class SameUrlDataInterceptor extends RepeatSubmitInterceptor {

    // 令牌自定义标识
    @Value("${token.header}")
    private String header;

    @Autowired
    private RedisUtils redisUtils;

    private static final Logger log = LoggerFactory.getLogger(SameUrlDataInterceptor.class);

    @Override
    public boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation) {
        try {
        String nowParams = "";
        if (request instanceof RepeatedlyRequestWrapper) {
            RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request;
            nowParams = HttpHelper.getBodyString(repeatedlyRequest);
        }

        // body参数为空，获取Parameter的数据
        if (StrUtil.isEmpty(nowParams)) {
            nowParams = JSON.toJSONString(request.getParameterMap());
        }

        // 请求地址（作为存放cache的key值）
        String url = request.getRequestURI();

        // 唯一值（没有消息头则使用请求地址）
        String submitKey = StrUtil.trimToEmpty(request.getHeader(header));

        // 如果 submitKey 为空，使用 IP + User-Agent 生成唯一标识
        if (StrUtil.isEmpty(submitKey)) {
            String ip = IpUtils.getIpAddr();
            String ua = request.getHeader("User-Agent");
            submitKey = DigestUtils.md5DigestAsHex((ip + ua).getBytes());
        }

        // 构造唯一 Key（使用 MD5 避免特殊字符问题）
        String uniqueKey = url + submitKey + nowParams;

        long userId = StpUtil.getLoginIdAsLong();
        String tokenValue = StpUtil.getTokenValue();
        // 唯一标识（指定key + url + 消息头）
        String cacheRepeatKey = CacheConstants.REPEAT_SUBMIT_KEY + userId + ":" + tokenValue + DigestUtils.md5DigestAsHex(uniqueKey.getBytes());

        // 获取上次提交时间
        Long lastTime = (Long)redisUtils.get(cacheRepeatKey);
        long interval = Math.max(annotation.interval(), 1000L);

        if (lastTime != null) {
            long diff = System.currentTimeMillis() - lastTime;
            if (diff < interval) {
                return true; // 重复提交
            }
        }

        // 设置缓存，有效期为 interval 毫秒
        redisUtils.set(cacheRepeatKey, System.currentTimeMillis(), interval/1000);
        return false;
        } catch (Exception e) {
            log.error("防重复提交判断异常", e);
            return false; // 异常不拦截请求
        }
    }

}