package com.cyksj.service.wechat.cach.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.dto.RedisKey;
import com.cyksj.mapper.WxAppMapper;
import com.cyksj.model.dto.AccountJsTicket;
import com.cyksj.model.dto.WeChatAccessToken;
import com.cyksj.model.entity.WxApp;
import com.cyksj.service.wechat.cach.AccountCache;
import com.cyksj.redis.RedisService;
import com.cyksj.service.wechat.AccountOps;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

/**
 * @author valor.
 * @date 2019/12/12 13:40
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class AccountCacheImpl implements AccountCache {

    private final RedisService redisService;

    private final WxAppMapper wxAppMapper;

    private final AccountOps accountOps;

    @Override
    public String getAccessToken(String appId) throws Exception {
        String accessToken = redisService.getStr(RedisKey.ACCESS_TOKEN_KEY + appId);
        if (StringUtils.isBlank(accessToken)) {
            return this.flush_access_token(appId);
        }else {
            return accessToken;
        }
    }

    @Override
    public String getJsTicket(String appId) throws Exception {
        String jsTicket = redisService.getStr(RedisKey.JS_TICKET_KEY + appId);
        if (StringUtils.isBlank(jsTicket)) {
            return this.flush_js_ticket(appId);
        }else {
            return jsTicket;
        }
    }

    private String flush_access_token(String appId) throws Exception {
        LambdaQueryWrapper<WxApp> wxAppLambdaQueryWrapper = new QueryWrapper<WxApp>().lambda();
        wxAppLambdaQueryWrapper.eq(WxApp::getAppId,appId);
        WxApp wxApp = wxAppMapper.selectOne(wxAppLambdaQueryWrapper);

        if (null == wxApp) {
            throw BusinessRuntimeException.getInstance("No appId configured.");
        }

        final String secret = wxApp.getAppSecret();
        WeChatAccessToken token = accountOps.accessToken(appId, secret);
        if (!redisService.set(RedisKey.ACCESS_TOKEN_KEY + appId,token.getAccessToken(), (long) (token.getExpiresIn() - 300))) {
            if (!redisService.set(RedisKey.ACCESS_TOKEN_KEY + appId,token.getAccessToken(), (long) (token.getExpiresIn() - 300))) {
                log.error("accessToken 设置错误 appId:{}",appId);
            }
        }

        return token.getAccessToken();
    }

    private String flush_js_ticket(String appId) throws Exception {
        AccountJsTicket ticket = accountOps.jsTicket(this.getAccessToken(appId));

        if (!redisService.set(RedisKey.JS_TICKET_KEY + appId,ticket.getTicket(), (long) (ticket.getExpiresIn() - 300))) {
            if (!redisService.set(RedisKey.JS_TICKET_KEY + appId,ticket.getTicket(), (long) (ticket.getExpiresIn() - 300))) {
                log.error("js_ticket 设置错误 appId:{}",appId);
            }
        }
        return ticket.getTicket();
    }
}
