package com.huiju.estateagents.common;

import com.wf.captcha.SpecCaptcha;
import lombok.Data;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Hashtable;
import java.util.UUID;

@Slf4j
@Component
@EnableScheduling
public class CaptchaUtils {
    Hashtable<String, Captcha> allCaptchas = new Hashtable<>();

    public Captcha generate() {
        SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 5);
        Captcha cap = new Captcha()
                .setKey(UUID.randomUUID().toString())
                .setValue(specCaptcha.text().toLowerCase())
                .setImage(specCaptcha.toBase64())
                .setExpire(LocalDateTime.now().plusMinutes(15));
        allCaptchas.put(cap.getKey(), cap);

        // 返回的内容不包含 value
        return copy(cap).setValue(null);
    }

    public boolean valid(String key, String captcha) {
        if (null == captcha || null == key) {
            return false;
        }

        // 没有对应键值
        Captcha cap = allCaptchas.get(key);
        if (null == cap) {
            return false;
        }

        // 内容不匹配
        if (!cap.getValue().equals(captcha.toLowerCase())) {
            return false;
        }

        boolean res = checkExpire(cap);
        if (res) {
            // 过期清除
            allCaptchas.remove(key);
        }

        return !res;
    }

    private Captcha copy(Captcha captcha) {
        return new Captcha()
                .setKey(captcha.getKey())
                .setValue(captcha.getValue())
                .setImage(captcha.getImage())
                .setExpire(captcha.getExpire());
    }

    private boolean checkExpire(Captcha cap) {
        return LocalDateTime.now().isAfter(cap.getExpire());
    }

    /**
     * 定时任务 每半小时 清除一次不用的缓存
     */
    @Scheduled(fixedRate = 1000 * 60 * 30)
    public void clearUnused() {
        for (Captcha cap: allCaptchas.values()) {
            if (checkExpire(cap)) {
                allCaptchas.remove(cap.getKey());
            }
        }
    }

    @Data
    @Accessors(chain = true)
    public static class Captcha {
        String key;
        String value;
        String image;
        LocalDateTime expire;
    }
}
