package com.cyksj.service.user.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.common.util.SmsUtil;
import com.cyksj.redis.RedisService;
import com.cyksj.service.user.BadIntentionOpService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@Service
@RequiredArgsConstructor
@Slf4j
public class BadIntentionOpServiceImpl implements BadIntentionOpService {

    @Value("${smsVerify.apikey}")
    String apiKey;

    @Value("${smsVerify.shoppingApikey}")
    String shoppingApikey;

    private final RedisService redisService;

    private static final int PHONE_CODE_GET_NUM_DAY_LIMIT = 30;
    private static final int PHONE_CODE_GET_NUM_DAY_MAX_BLACK = 50;

    private static final int PHONE_LOGIN_CODE_RETRY = 10;

    private static final String VERIFY_URL =  "https://captcha.luosimao.com/api/site_verify";

    @Override
    public void checkHandleBadUserOp(String phone, String verifyCode, String ticket, String randStr, HttpServletRequest request) {
        if ("13662979985".equals(phone)) {
            throw BusinessRuntimeException.getInstance("异常手机号");
        }
//        if (StringUtils.isBlank(verifyCode)) {
//            throw BusinessRuntimeException.getInstance("人机校验不通过");
//        } else {
//            //银河官网
//            JSONObject res = checkVerifyCode(apiKey, verifyCode);
//            if (!res.getStr("res").equals("success")) {
//                //小店域名
//                res = checkVerifyCode(shoppingApikey, verifyCode);
//                if (!res.getStr("res").equals("success")) {
//                    log.error("手机号:{}验证码校验不通过 res:{}", phone, res);
//                    throw BusinessRuntimeException.getInstance("人机校验不通过");
//                }
//            }
//        }
        if (ObjectUtil.hasEmpty(ticket, randStr)) {
            throw BusinessRuntimeException.getInstance("请先完成图形认证");
        } else {
            //腾讯云图形验证
            String ip = ServletUtil.getClientIP(request);
            SmsUtil.checkTencentCaptcha(ticket, ip, randStr);
        }
        String dayKey = RedisService.key.PHONE_CODE_USER_NUM_KEY_DAY.getName() + phone;
        if (redisService.hasKey(RedisService.key.PHONE_CODE_BALCK_KEY.getName() + phone)) {
            throw BusinessRuntimeException.getInstance("异常手机号");
        }
        if (redisService.hasKey(dayKey)) {
            Long incr = redisService.incr(dayKey, 1l);
            if (incr.intValue() >= PHONE_CODE_GET_NUM_DAY_MAX_BLACK) {
                log.error("近一天内手机号:{}获取验证码超过50次,移入黑名单", phone);
                redisService.set(RedisService.key.PHONE_CODE_BALCK_KEY.getName() + phone, phone);
            }

            if (incr.intValue() > PHONE_CODE_GET_NUM_DAY_LIMIT) {
                log.error("手机号:{}频繁获取短信验证码", phone);
                throw BusinessRuntimeException.getInstance("请勿频繁获取短信验证码");
            }
            return;
        }
        redisService.set(dayKey, 1, RedisService.key.PHONE_CODE_USER_NUM_KEY_DAY.getTimeout());

    }

    @Override
    public void isBadOpLoginPhone(HttpServletRequest request, String phone) {
        String ip = ServletUtil.getClientIP(request);
        log.info("--------------校验ip 是否黑名单------- ip:{}", ip);
        String blackIpKey = RedisService.key.BALCK_USER_IP_KEY + ip;
        if (redisService.hasKey(blackIpKey)) {
            throw BusinessRuntimeException.getInstance("检测到您操作异常，请联系客服");
        }
        String RetryTimeKey = RedisService.key.PHONE_CODE_RETRY_TIME_KEY.getName() + phone;
        if (redisService.hasKey(RetryTimeKey)) {
            int i = Integer.parseInt(redisService.get(RetryTimeKey).toString());
            if (i >= PHONE_LOGIN_CODE_RETRY) {
                //锁住他的ip
                redisService.setNx(blackIpKey, ip, RedisService.key.BALCK_USER_IP_KEY.getTimeout());
                throw BusinessRuntimeException.getInstance("检测到您操作异常，请联系客服");
            } else {
                redisService.incr(RetryTimeKey, 1l);
            }
        } else {
            redisService.setNx(RetryTimeKey, 1, RedisService.key.PHONE_CODE_RETRY_TIME_KEY.getTimeout());
        }
    }

    public JSONObject checkVerifyCode(String apiKey, String verifyCode) {
        Map<String, Object> parmas = new HashMap<>();
        parmas.put("api_key", apiKey);
        parmas.put("response", verifyCode);
        String post = HttpUtil.post(VERIFY_URL, parmas);
        JSONObject res = new JSONObject(post);
        return res;
    }
}
