package com.qs.mp.framework.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.qs.mp.common.qcloud.QcloudFileUtils;
import com.qs.mp.common.utils.LogUtil;
import com.qs.mp.common.utils.UUIDUtils;
import com.qs.mp.common.utils.http.HttpUtils;
import com.qs.mp.framework.service.IAppTokenService;
import com.qs.mp.framework.service.IWxUrlLinkService;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.entity.ContentType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * 微信小程序链接生成
 *
 * @author zhongcp
 * @Date 2021/9/22
 */
@Service
public class WxUrlLinkServiceImpl implements IWxUrlLinkService {

  protected final Logger logger = LoggerFactory.getLogger(WxUrlLinkServiceImpl.class);

  @Autowired
  private IAppTokenService appTokenService;

  /**
   * 公开
   */
  @Value("${cloud.public-bucket-name}")
  private String publicBucketName;

  @Value("${miniprogram.env_version}")
  private String envVersion;

  @Override
  public String generate(String path, String query, String appId) {
    Map<String, Object> param = new HashMap<String, Object>();
    param.put("path", path);
    param.put("query", query);
    // 有效时间超过31天的 Link 或永久有效的 Link 为长期有效Link，
    // 单个小程序总共可生成长期有效 Link 上限为10万个，请谨慎调用
    param.put("is_expire", false);
//    param.put("expire_type", 1);
//    param.put("expire_interval", 30);
    // 渠道端票赢天下小程序永久短链接https://wxaurl.cn/rNflbUVrTJn
    // 获取access_token
    String accessToken = appTokenService.getAccessToken(appId);
    String res = HttpUtils.sendPost(
        "https://api.weixin.qq.com/wxa/generate_urllink?access_token=" + accessToken,
        JSON.toJSONString(param));
    LogUtil.info(logger, "小程序链接获取,path:{0},query:{1},res:{2}",
        new Object[]{path, query, res});
    JSONObject jsonObject = JSON.parseObject(res);
    if (jsonObject.getIntValue("errcode") != 0) {
      LogUtil.error(logger, "小程序链接获取错误，res:{0}", res);
      return null;
    }
    return jsonObject.getString("url_link");
  }


  @Override
  public String generateUrlSchema(String path, String query, String appId) {
    Map<String, Object> param = new HashMap<String, Object>();
    Map<String, Object> jumpParam = new HashMap<>();
    jumpParam.put("path", path);
    jumpParam.put("query", query);
    jumpParam.put("env_version", envVersion);
    param.put("jump_wxa", jumpParam);
    // 有效时间超过31天的 Link 或永久有效的 Link 为长期有效Link，
    // 单个小程序总共可生成长期有效 Link 上限为10万个，请谨慎调用
    param.put("is_expire", true);
    param.put("expire_type", 1);
    param.put("expire_interval", 2);
    // 云管铺小程序永久短链接https://wxaurl.cn/YL8D48CQbMr
    // 获取access_token
    String accessToken = appTokenService.getAccessToken(appId);
    String res = HttpUtils.sendPost(
        "https://api.weixin.qq.com/wxa/generatescheme?access_token=" + accessToken,
        JSON.toJSONString(param));
    LogUtil.info(logger, "小程序UrlSchema获取,path:{0},query:{1},res:{2},jumpParam:{3}",
        new Object[]{path, query, res, jumpParam});
    JSONObject jsonObject = JSON.parseObject(res);
    if (jsonObject.getIntValue("errcode") != 0) {
      LogUtil.error(logger, "小程序UrlSchema获取错误，res:{0}", res);
      return null;
    }
    return jsonObject.getString("openlink");
  }

  @Override
  public String generateCode(String path, String scene, String appId) {
    Map<String, Object> param = new HashMap<String, Object>();
    param.put("path", path + "?" + scene); // 页面路径
    //param.put("scene", scene); // 参数
//    param.put("check_path", true);// 为 true 时 page 必须是已经发布的小程序存在的页面（否则报错）；为 false 时允许小程序未发布或者 page 不存在
//    param.put("env_version", envVersion);
    // 获取access_token
    String accessToken = appTokenService.getAccessToken(appId);
    InputStream in = HttpUtils.sendImagePost(
        "https://api.weixin.qq.com/wxa/getwxacode?access_token=" + accessToken,
        JSON.toJSONString(param));
    LogUtil.info(logger, "小程序码获取,path:{0},scene:{1}",
        new Object[]{path, scene});
//    JSONObject jsonObject = JSON.parseObject(res);
    if (null == in) {
      LogUtil.error(logger, "小程序码获取错误");
      return null;
    }
    // 上传图片
    String uuid = UUIDUtils.newId();
    try {

      QcloudFileUtils.putStream(in, uuid, publicBucketName, ContentType.IMAGE_JPEG.getMimeType());
    } catch (Exception e) {
      LogUtil.error(logger, e, "小程序码获取错误");
      return null;
    }
    return uuid;
  }

  @Override
  public String generateUnlimitCode(String path, String scene, String appId) {
    Map<String, Object> param = new HashMap<String, Object>();
    param.put("page", path); // 页面路径
    param.put("scene", scene); // 参数
//    param.put("check_path", true);// 为 true 时 page 必须是已经发布的小程序存在的页面（否则报错）；为 false 时允许小程序未发布或者 page 不存在
    param.put("env_version", envVersion);
    // 获取access_token
    String accessToken = appTokenService.getAccessToken(appId);
    InputStream in = HttpUtils.sendImagePost(
        "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken,
        JSON.toJSONString(param));
    LogUtil.info(logger, "小程序码生成,path:{0},scene:{1}",
        new Object[]{path, scene});
//    JSONObject jsonObject = JSON.parseObject(res);
    if (null == in) {
      LogUtil.error(logger, "小程序码生成错误");
      return null;
    }
    /*byte[] data = null;
    // 读取图片字节数组
    ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
    byte[] buff = new byte[100];
    int rc = 0;
    while (true) {
      try {
        if (!((rc = in.read(buff, 0, 100)) > 0))
          break;
      } catch (IOException e) {
        e.printStackTrace();
      }
      swapStream.write(buff, 0, rc);
    }
    data = swapStream.toByteArray();
    LogUtil.info(logger, "image:" + new String(data));
*/
    // 上传图片
    String fileName = "s/" + UUIDUtils.newId();
    try {
      QcloudFileUtils.putStream(in, fileName, publicBucketName, ContentType.IMAGE_JPEG.getMimeType());
    } catch (Exception e) {
      LogUtil.error(logger, e, "小程序码获取错误");
      return null;
    }
    return fileName;
  }
}
