package cn.com.poc.user.wecom.service;

import cn.com.poc.common.service.RedisService;
import cn.com.poc.common.utils.StringUtils;
import cn.com.poc.user.wecom.api.WecomTokenApi;
import cn.com.poc.user.wecom.constant.WecomConstant;
import cn.com.poc.user.wecom.domain.WecomProviderAccessToken;
import cn.com.poc.user.wecom.domain.WecomSuiteAccessToken;
import cn.com.poc.user.wecom.domain.properties.WecomProperties;
import cn.com.yict.framemax.core.i18n.I18nMessageException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class WecomTokenService {

    private static final Logger logger = LoggerFactory.getLogger(WecomTokenService.class);

    @Resource
    private WecomTokenApi wecomTokenApi;

    @Resource
    private RedisService redisService;

    @Resource
    private WecomProperties wecomProperties;

    public String getProviderToken() {
        String corpId = wecomProperties.getCorpId();
        String providerSecret = wecomProperties.getProviderSecret();
        if (StringUtils.isBlank(corpId) || StringUtils.isBlank(providerSecret)) {
            throw new I18nMessageException("exception/system.error");
        }
        String tokenKey = WecomConstant.RedisKey.PROVIDER_ACCESS_TOKEN + ":" + corpId;
        String cachedToken = redisService.get(tokenKey, String.class);
        if (StringUtils.isNotBlank(cachedToken)) {
            return cachedToken;
        }
        WecomProviderAccessToken token = wecomTokenApi.getProviderToken(corpId, providerSecret);
        if (token != null && token.isSuccess()) {
            redisService.set(tokenKey, token.getProvider_access_token(), token.getExpires_in());
            return token.getProvider_access_token();
        }
        logger.error("wecom provider token error: {}", token == null ? "null response" : token.getErrmsg());
        throw new I18nMessageException("exception/system.error");
    }

    public String getSuiteToken() {
        String suiteId = wecomProperties.getSuiteId();
        String suiteSecret = wecomProperties.getSuiteSecret();
        if (StringUtils.isBlank(suiteId) || StringUtils.isBlank(suiteSecret)) {
            throw new I18nMessageException("exception/system.error");
        }
        String tokenKey = WecomConstant.RedisKey.SUITE_ACCESS_TOKEN + ":" + suiteId;
        String cachedToken = redisService.get(tokenKey, String.class);
        if (StringUtils.isNotBlank(cachedToken)) {
            return cachedToken;
        }
        String ticketKey = WecomConstant.RedisKey.SUITE_TICKET + ":" + suiteId;
        String suiteTicket = redisService.get(ticketKey, String.class);
        if (StringUtils.isBlank(suiteTicket)) {
            logger.error("wecom suite ticket missing for suiteId {}", suiteId);
            throw new I18nMessageException("exception/system.error");
        }
        WecomSuiteAccessToken token = wecomTokenApi.getSuiteToken(suiteId, suiteSecret, suiteTicket);
        if (token != null && token.isSuccess()) {
            redisService.set(tokenKey, token.getSuite_access_token(), token.getExpires_in());
            return token.getSuite_access_token();
        }
        logger.error("wecom suite token error: {}", token == null ? "null response" : token.getErrmsg());
        throw new I18nMessageException("exception/system.error");
    }
}
