package xyz.wbsite.action.ajax.wframe;

import org.springframework.beans.factory.annotation.Autowired;
import xyz.wbsite.config.CacheConfig;
import xyz.wbsite.frame.base.ErrorType;
import xyz.wbsite.frame.base.LocalData;
import xyz.wbsite.frame.base.LoginRequest;
import xyz.wbsite.frame.base.LoginResponse;
import xyz.wbsite.frame.base.LogoutRequest;
import xyz.wbsite.frame.base.LogoutResponse;
import xyz.wbsite.frame.base.Token;
import xyz.wbsite.frame.base.UserEntity;
import xyz.wbsite.frame.base.VerifyCodeRequest;
import xyz.wbsite.frame.base.VerifyCodeResponse;
import xyz.wbsite.frame.provider.FrameProvider;
import xyz.wbsite.frame.provider.TokenProvider;
import xyz.wbsite.frame.provider.UserProvider;
import xyz.wbsite.frame.utils.CookieUtil;
import xyz.wbsite.frame.utils.IDgenerator;
import xyz.wbsite.frame.utils.MD5Util;
import xyz.wbsite.frame.utils.ValidationUtil;
import xyz.wbsite.frame.utils.VerifyCodeUtil;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

public class AuthAjax {

    @Autowired
    private CacheConfig cacheConfig;

    public VerifyCodeResponse verifyCode(VerifyCodeRequest request) {
        VerifyCodeResponse response = new VerifyCodeResponse();
        VerifyCodeUtil.Builder builder = new VerifyCodeUtil.Builder().build();
        response.setVerifyCodeId(IDgenerator.nextId());
        response.setVerifyCodeBase64(builder.toBase64());
        cacheConfig.put(response.getVerifyCodeId(), builder.toCode(), 3 * 60 * 1000);
        return response;
    }

    public LoginResponse login(LoginRequest request, HttpServletResponse httpServletResponse) {
        LoginResponse response = new LoginResponse();

        ValidationUtil.validate(request, response);
        if (response.hasError()) {
            return response;
        }

        // 获取验证码
        String o = cacheConfig.remove(request.getVerifyCodeId(), String.class);
        if (o == null) {
            response.addError(ErrorType.BUSINESS_ERROR, "验证码已过期!");
            return response;
        }

        // 验证验证码
        if (!request.getVerifyCodeCode().toLowerCase().equals(o.toLowerCase())) {
            response.addError(ErrorType.BUSINESS_ERROR, "验证码错误!");
            cacheConfig.remove(request.getVerifyCodeId());
            return response;
        }

        // 获取用户提供者
        UserProvider userProvider = FrameProvider.getInstance().getUserProvider();
        if (userProvider == null) {
            response.addError(ErrorType.BUSINESS_ERROR, "用户提供者未实现!");
            return response;
        }

        // 获取用户信息
        UserEntity userEntity = userProvider.getUser(request.getUsername());
        if (userEntity == null) {
            response.addError(ErrorType.BUSINESS_ERROR, "用户名或密码错误!");
            return response;
        }

        // 验证密码
        String generatePwd = MD5Util.generatePwd(request.getPassword());
        if (!generatePwd.equals(userEntity.getPassword())) {
            response.addError(ErrorType.BUSINESS_ERROR, "用户名或密码错误!");
            return response;
        }

        // 获取通行证提供者
        TokenProvider tokenProvider = FrameProvider.getInstance().getTokenProvider();
        if (tokenProvider == null) {
            response.addError(ErrorType.BUSINESS_ERROR, "通行证提供者未实现!");
            return response;
        }

        // 构建通行证
        Token token = tokenProvider.build(userEntity);
        if (token == null) {
            response.addError(ErrorType.BUSINESS_ERROR, "通行证构建失败!");
            return response;
        }
        response.setToken(token.getToken());
        Cookie cookie = CookieUtil.newCookie("token", response.getToken());
        httpServletResponse.addCookie(cookie);
        return response;
    }

    public LogoutResponse logout(LogoutRequest request) {
        LogoutResponse response = new LogoutResponse();

        Token token = LocalData.getToken();
        if (token != null) {
            cacheConfig.clear(token.getToken());
        }
        CookieUtil.clearCookie("token");
        return response;
    }

    public LogoutResponse changePwd(LogoutRequest request) {
        LogoutResponse response = new LogoutResponse();

        Token token = LocalData.getToken();
        if (token != null) {
            cacheConfig.clear(token.getToken());
        }
        CookieUtil.clearCookie("token");
        return response;
    }
}
