package com.slodon.bbc.starter.thirdParty.client;

import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.slodon.b2b2c.core.exception.MallException;
import com.slodon.bbc.starter.thirdParty.constant.ThirdPartyConst;
import com.slodon.bbc.starter.thirdParty.entity.SlodonThirdPartyQrCodeRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.util.concurrent.TimeUnit;

/**
 * 百度
 *
 */
@Slf4j
public class BaiduClient implements ThirdPartyBaseClient {

    /**
     * 获取二维码
     * https://smartprogram.baidu.com/docs/develop/serverapi/getunlimited/
     *
     * @param stringRedisTemplate redis操作工具
     * @param qrCodeRequest       业务参数
     * @return 二维码图片
     */
    @Override
    public BufferedImage getQrCode(StringRedisTemplate stringRedisTemplate, SlodonThirdPartyQrCodeRequest qrCodeRequest) throws Exception{
        //获取凭证，优先使用缓存
        String access_token = stringRedisTemplate.opsForValue().get(ThirdPartyConst.REDIS_ACCESS_TOKEN_KEY_BAIDU);
        if (StringUtils.isEmpty(access_token)){
            //缓存不存在或已过期，重新获取并缓存
            access_token = this.getAccessToken(stringRedisTemplate);
            //缓存15天
            stringRedisTemplate.opsForValue().set(ThirdPartyConst.REDIS_ACCESS_TOKEN_KEY_BAIDU,access_token,15, TimeUnit.DAYS);
        }

        String qrUrl = "https://openapi.baidu.com/rest/2.0/smartapp/qrcode/getunlimited";
        StringBuilder path = new StringBuilder(qrCodeRequest.getPage());//扫码跳转地址
        path.append("?");
        qrCodeRequest.getParams().forEach((k,v) -> {
            path.append(k).append("=").append(v).append("&");
        });

        //构造json参数
        ModelMap modelMap = new ModelMap();
        modelMap.put("access_token", access_token);
        modelMap.put("width", 430);
        modelMap.put("path", path.toString().substring(0,path.length()-1));//发布后才可以添加

        HttpResponse execute = HttpUtil.createPost(qrUrl).form(modelMap).execute();

        if (!execute.isOk()){
            //请求失败
            log.error("生成抖音二维码失败：" + execute.body());
            throw new MallException("小程序维护中，请稍后再试");
        }

        return ImageIO.read(execute.bodyStream());
    }

    /**
     * 获取access_token，失效时间为1个月
     *
     * @param stringRedisTemplate redis操作工具
     * @return access_token
     */
    private String getAccessToken(StringRedisTemplate stringRedisTemplate){
        String ACCESS_TOKEN_URL = "https://openapi.baidu.com/oauth/2.0/token";//获取access_token地址
        String appKey = stringRedisTemplate.opsForValue().get("third_party_baidu_appkey");
        String secret = stringRedisTemplate.opsForValue().get("third_party_baidu_secret");
        ModelMap modelMap = new ModelMap();
        modelMap.put("client_id", appKey);
        modelMap.put("client_secret", secret);
        modelMap.put("grant_type", "client_credentials");
        modelMap.put("scope", "smartapp_snsapi_base");
        String resp = HttpUtil.get(ACCESS_TOKEN_URL,modelMap);
        JSONObject respJson = JSON.parseObject(resp);

        //请求失败格式 {"error_description":"unknown client id","error":"invalid_client"}
        //成功格式 {"expires_in":2592000,"access_token":"24.1bfc0d42a70db0c03bad26202641d4bb.2592000.1637321075.282335-24979140"}
        if (!StringUtils.isEmpty(respJson.getInteger("error"))){
            //请求失败
            log.error("获取百度小程序二维码失败：" + respJson.getString("error_description"));
            throw new MallException("小程序维护中，请稍后再试");
        }
        //请求成功
        return respJson.getString("access_token");
    }
}
