package cn.com.ctop.common.module.service.impl;

import cn.com.ctop.common.module.entity.CtopOauthToken;
import cn.com.ctop.common.module.entity.OauthAgentToken;
import cn.com.ctop.common.module.mapper.CtopOauthTokenMapper;
import cn.com.ctop.common.module.mapper.OauthAgentTokenMapper;
import cn.com.ctop.common.module.service.ICtopOauthTokenService;
import cn.com.ctop.common.module.utils.Check;
import cn.com.ctop.common.module.utils.HttpUtils;
import cn.com.ctop.common.module.utils.PropertiesUtils;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xxl.job.core.context.XxlJobHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @Description: oauth授权码
 * @Author: jeecg-boot
 * @Date: 2019-07-09
 * @Version: V1.0
 */
@Slf4j
@Service
public class CtopOauthTokenServiceImpl extends ServiceImpl<CtopOauthTokenMapper, CtopOauthToken> implements ICtopOauthTokenService {
    @Value("${bytedance.appId}")
    private String bytedanceAppId;
    @Value("${bytedance.secret}")
    private String bytedanceSecret;
    @Value("${bytedance.url.api-prefix}")
    private String bytedanceUrlApiPrefix;
    @Value("${bytedance.url.refresh-token}")
    private String bytedanceUrlRefreshToken;
    @Autowired
    private CtopOauthTokenMapper ctopOauthTokenMapper;
    @Autowired
    private OauthAgentTokenMapper agentTokenMapper;

    @Override
    public CtopOauthToken getOauthTokenByAccountId(String accountId) {
        QueryWrapper<CtopOauthToken> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account_id", accountId).orderByDesc("create_time");
        queryWrapper.last("limit 1");
        return this.getOne(queryWrapper);
    }


    @Override
    public CtopOauthToken getTokenByAccountId(Long accountId) {
        QueryWrapper<CtopOauthToken> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account_id", accountId).orderByDesc("create_time");
        queryWrapper.last("limit 1");
        return this.getOne(queryWrapper);
    }

    /**
     * 刷新token
     *
     * @return
     */
    @Override
    public Map<String, Object> getByteDanceAccessToken(CtopOauthToken token) {
        Map<String, Object> resultMap = new HashMap<>();
        String url = bytedanceUrlApiPrefix + bytedanceUrlRefreshToken;
        Map<String, Object> param = new HashMap<>();
        param.put("app_id", bytedanceAppId);
        param.put("secret", bytedanceSecret);
        param.put("grant_type", "refresh_token");
        param.put("refresh_token", token.getRefreshToken());
        String result = HttpUtils.httpPostRequest(url, param, new HashMap<>());
        System.err.println(JSONObject.parseObject(result));
        XxlJobHelper.log("头条刷新token;accountId:{},返回信息：{}", token.getAccountId(), result);
        if (null == result || "".equals(result.trim()) || "null".equalsIgnoreCase(result)) {
            XxlJobHelper.log("头条刷新token失败;accountId:{},返回信息：{}", token.getAccountId(), result);
            resultMap.put("message", "token刷新失败");
            resultMap.put("token", token);
            resultMap.put("code", 0);
            return resultMap;
        }
        JSONObject resultObject = JSONObject.parseObject(result);
        Integer code = resultObject.getInteger("code");
        String message = resultObject.getString("message");
        if (code == 0) {
            JSONObject data = resultObject.getJSONObject("data");
            CtopOauthToken updateRefreshToken = new CtopOauthToken();
            updateRefreshToken.setAccessToken(data.getString("access_token"));
            updateRefreshToken.setRefreshToken(data.getString("refresh_token"));
            Date now = new Date();
            Integer refreshTokenExpiresIn = data.getInteger("refresh_token_expires_in");
            Integer expiresIn = data.getInteger("expires_in");
            updateRefreshToken.setRefreshTokenExpiresIn(addSecond(now, refreshTokenExpiresIn));
            updateRefreshToken.setAccessTokenExpiresIn(addSecond(now, expiresIn));
            QueryWrapper<CtopOauthToken> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("access_token", token.getAccessToken());
            queryWrapper.eq("media_id", 1);
            int i = ctopOauthTokenMapper.update(updateRefreshToken, queryWrapper);
            if (i > 0) {
                XxlJobHelper.log("头条刷新token成功:accountId:{}", token.getAccountId());
            }
            resultMap.put("message", "token刷新成功");
            resultMap.put("code", 0);
        } else {
            XxlJobHelper.log("头条刷新token失败;accountId:{},返回信息：{}", token.getAccountId(), message);
            resultMap.put("message", message);
            resultMap.put("token", token);
            resultMap.put("code", 0);
        }
        return resultMap;
    }

    /**
     * 快手 刷新token
     *
     * @param accountId
     * @param refreshToken
     * @return
     */
    @Override
    public void getKuaiShouRefreshToken(Long accountId, String token, String refreshToken, Long appId, String secret) {
        log.info("快手刷新token入参，accountId:{},token:{},refreshToken:{}", accountId, token, refreshToken);
        String url = PropertiesUtils.getConfig("kuaishou_api_url") + "/rest/openapi/oauth2/authorize/refresh_token";
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", " application/json");
        Map<String, Object> param = new HashMap<>();
        param.put("app_id", appId);
        param.put("secret", secret);
        param.put("refresh_token", refreshToken);
        try {
            CtopOauthToken oauthToken = ctopOauthTokenMapper.selectByAccountId(accountId);
            if (null == oauthToken) {
                log.error("查询token信息返回结果为空,accountId：{}", accountId);
                return;
            }
            XxlJobHelper.log("刷新token,入參:{}，token:{}", param, headers);
            String result = HttpUtils.httpPostRequest(url, param, headers);
            JSONObject resultJson = JSONObject.parseObject(result);
            log.info("快手刷新token返回结果：{}", refreshToken);
            if (Check.isNull(resultJson)) {
                log.error("快手刷新token返回结果为空,accountId：{}", accountId);
                return;
            }
            Integer code = resultJson.getInteger("code");
            if (null == code || code != 0) {
                log.error("快手刷新token失败,accountId:{},result:{}", accountId, resultJson);
                return;
            }
            JSONObject dataJson = resultJson.getJSONObject("data");
            if (null == dataJson) {
                log.error("快手刷新token失败,accountId:{},result:{}", accountId, resultJson);
                return;
            }
            oauthToken.setAccessToken(dataJson.getString("access_token"));
            long accessTokenExpireIn = dataJson.getLong("access_token_expires_in") * 1000L;
            long now = System.currentTimeMillis();
            Date accessTokenExpireInDate = new Date(now + accessTokenExpireIn);
            oauthToken.setAccessTokenExpiresIn(accessTokenExpireInDate);
            oauthToken.setRefreshToken(dataJson.getString("refresh_token"));
            long refreshTokenExpireIn = dataJson.getLong("refresh_token_expires_in") * 1000L;
            Date refreshTokenExpireInDate = new Date(now + refreshTokenExpireIn);
            oauthToken.setRefreshTokenExpiresIn(refreshTokenExpireInDate);
            oauthToken.setUpdateTime(new Date());
            QueryWrapper<CtopOauthToken> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("account_id", accountId);
            queryWrapper.eq("media_id", 2);
            int i = ctopOauthTokenMapper.update(oauthToken, queryWrapper);
            if (i > 0) {
                log.info("快手刷新token成功，accountId:{}", accountId);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            log.error("快手刷新token失败,accountId{}", accountId);
        }
    }

    @Override
    public List<CtopOauthToken> getTokenListByType(String platformType) {
        QueryWrapper<CtopOauthToken> queryWrapper = new QueryWrapper<>();
        if (null != platformType && !"".equals(platformType.trim())) {
            queryWrapper.eq("media_id", platformType);
        }
        queryWrapper.orderByDesc("account_id");
        return this.list(queryWrapper);
    }

    /**
     * 获取快手有效账户列表
     *
     * @return
     */

    @Override
    public List<CtopOauthToken> selectKuaiShouToken() {
        return ctopOauthTokenMapper.selectKuaiShouToken();
    }

    @Override
    public List<CtopOauthToken> selectKuaiShouTokenBefore() {
        return ctopOauthTokenMapper.selectKuaiShouTokenBefore();
    }


    /**
     * 获取toutiao有效账户列表
     *
     * @return
     */

    @Override
    public List<CtopOauthToken> selectToutiaoToken() {
        return ctopOauthTokenMapper.selectToutiaoToken();
    }


    @Override
    public CtopOauthToken getAccessTokenByAccountIdAndMediaId(Integer mediaId, Long accountId) {
        return ctopOauthTokenMapper.getAccessTokenByAccountIdAndMediaId(mediaId, accountId);
    }

    @Override
    public List<CtopOauthToken> getToutiaoTokenByCreateTime(String createTime) {
        return ctopOauthTokenMapper.getToutiaoTokenByCreateTime(createTime);
    }

    @Override
    public List<CtopOauthToken> getByProjectId(Long projectId) {
        QueryWrapper<CtopOauthToken> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("project_id", projectId).eq("account_status", 0);
        return this.list(queryWrapper);
    }

    @Override
    public CtopOauthToken selectOneByMediaId(String platformTypeKuaishou) {
        QueryWrapper<CtopOauthToken> tokenQueryWrapper = new QueryWrapper<>();
        tokenQueryWrapper.eq("media_id", platformTypeKuaishou);
        tokenQueryWrapper.orderByDesc("create_time");
        tokenQueryWrapper.last("limit 1");
        return this.getOne(tokenQueryWrapper);
    }

    @Override
    public void getKuaiShouAgentRefreshToken(Long agentId, String accessToken, String refreshToken) {
        log.info("快手刷新token入参，token:{},refreshToken:{}", accessToken, refreshToken);
        String url = PropertiesUtils.getConfig("kuaishou_api_url") + "/rest/openapi/oauth2/authorize/refresh_token";
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", " application/json");
        Map<String, Object> param = new HashMap<>();

        param.put("app_id", PropertiesUtils.getConfig("kuaishou_appid"));
        param.put("secret", PropertiesUtils.getConfig("kuaishou_secret"));
        param.put("refresh_token", refreshToken);
        try {
            String result = HttpUtils.httpPostRequest(url, param, headers);
            JSONObject resultJson = JSONObject.parseObject(result);
            log.info("快手刷新代理商token返回结果：{}", refreshToken);
            if (Check.isNull(resultJson)) {
                log.error("快手刷新代理商token返回结果为空,token：{}", accessToken);
                return;
            }
            Integer code = resultJson.getInteger("code");
            if (null == code || code != 0) {
                log.error("快手刷新代理商token失败,token:{},result:{}", accessToken, resultJson);
                return;
            }
            JSONObject dataJson = resultJson.getJSONObject("data");
            if (null == dataJson) {
                log.error("快手刷新代理商token失败,token:{},result:{}", accessToken, resultJson);
                return;
            }

            QueryWrapper<OauthAgentToken> agentTokenQueryWrapper = new QueryWrapper<>();
            agentTokenQueryWrapper.eq("agent_id", agentId);
            OauthAgentToken updateAgentToken = new OauthAgentToken();
            updateAgentToken.setAccessToken(dataJson.getString("access_token"));
            updateAgentToken.setRefreshToken(dataJson.getString("refresh_token"));
            long accessTokenExpireIn = dataJson.getLong("access_token_expires_in") * 1000L;
            long now = System.currentTimeMillis();
            Date accessTokenExpireInDate = new Date(now + accessTokenExpireIn);
            updateAgentToken.setAccessTokenExpiresIn(accessTokenExpireInDate);
            long refreshTokenExpireIn = dataJson.getLong("refresh_token_expires_in") * 1000L;
            Date refreshTokenExpireInDate = new Date(now + refreshTokenExpireIn);
            updateAgentToken.setRefreshTokenExpiresIn(refreshTokenExpireInDate);
            updateAgentToken.setUpdateTime(new Date());
            int update = agentTokenMapper.update(updateAgentToken, agentTokenQueryWrapper);
            if (update > 0) {
                log.info("刷新代理商token完成");
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            log.error("快手刷新代理商token失败,token{}", accessToken);
        }


    }

    private Date addSecond(Date date, int seconds) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.SECOND, seconds);
        return calendar.getTime();
    }
}
