package com.css.txw.sso.service.auth.impl;


import cn.hutool.crypto.digest.MD5;
import com.css.txw.mhzc.pojo.HtYhxxbDTO;
import com.css.txw.sso.constants.SsoApiConstants;
import com.css.txw.sso.constants.SsoConstants;
import com.css.txw.sso.pojo.domain.oauth2.OAuth2AccessTokenDO;
import com.css.txw.sso.pojo.vo.AuthLoginReqVO;
import com.css.txw.sso.service.auth.AdminAuthService;
import com.css.txw.sso.service.oauth2.OAuth2TokenService;
import com.css.txw.sso.service.verify.VerifyService;
import com.css.txw.sso.service.yhxx.AccountLockService;
import com.css.txw.sso.service.yhxx.YhxxService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import static com.css.txw.sso.constants.ErrorCodeConstants.*;
import static com.css.ggzc.framework.common.exception.util.ServiceExceptionUtil.exception;

@Service
@Slf4j
public class AdminAuthServiceImpl implements AdminAuthService {

    @Resource
    private AccountLockService accountLockService;

    @Resource
    private VerifyService verifyService;

    @Resource
    private OAuth2TokenService oauth2TokenService;

    @Resource
    private YhxxService yhxxService;

    @Override
    public String login(AuthLoginReqVO reqVO) {
        final Boolean checked = verifyService.checkVerifyToken(reqVO.getCaptchaVerification());
        if (!checked){
            throw exception(AUTH_LOGIN_CAPTCHA_CODE_ERROR);
        }
        final HtYhxxbDTO authenticate = authenticate(reqVO.getUsername(), reqVO.getPassword());
        return createTokenAfterLoginSuccess(authenticate.getYhUuid());
    }

    @Override
    public void logout(String accessToken) {
        // 删除访问令牌
        oauth2TokenService.removeAccessToken(SsoConstants.CLIENT_DEFAULT,accessToken);
    }

    private String createTokenAfterLoginSuccess(String userId) {
        // 创建访问令牌
        OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.createAdminAccessToken(userId,"default");
        return accessTokenDO.getAccessToken();
    }

    public HtYhxxbDTO authenticate(String username, String password) {
        HtYhxxbDTO adminInfoByDlzh = yhxxService.getAdminInfoByDlzh(username);

        if (adminInfoByDlzh == null) {
            throw exception(AUTH_LOGIN_BAD_CREDENTIALS);
        }

        if (accountLockService.checkLockStatus(adminInfoByDlzh.getYhUuid())){
            throw exception(AUTH_LOGIN_PASSWORD_ERROR_LOCK);
        }

        if (!isPasswordMatch(password, adminInfoByDlzh.getDlmm())) {
            accountLockService.handlePasswordError(adminInfoByDlzh.getYhUuid());
            throw exception(AUTH_LOGIN_BAD_CREDENTIALS);
        }
        if (!"Y".equals(adminInfoByDlzh.getYxbz())){
            throw exception(AUTH_LOGIN_USER_DISABLED);
        }

        accountLockService.clearCache(adminInfoByDlzh.getYhUuid());

        return adminInfoByDlzh;
    }

    private boolean isPasswordMatch(String rawPassword, String encodedPassword) {
        final String rawPasswordHex = MD5.create().digestHex(rawPassword);
        return rawPasswordHex.equals(encodedPassword);
    }
}
