// import CryptoJS from "crypto-js";


import GameData from '../GameData';
import CryptoJS = require('./crypto-js.min.js');  //引用AES源码js

// import axios from 'axios'
const {ccclass, property} = cc._decorator;

@ccclass
export default class HttpUtil extends cc.Component {
   static async  getShareInfo(shareUrl: string): Promise<any> {
    console.log("设置分享链接:",shareUrl);
    const time = Math.floor((new Date().getTime()) / 1000)
    const url = HttpUtil.apiSign(`/api/share/cfg?gameId=${config.gameId}&time=${time}&url=${shareUrl}`,{})
    return this.httpPost(url,null,null);
  }
  //排行榜type2为获取，type1为上传
  static async rankData(type,callback,data): Promise<any> {
    data.gameId = GameData._instance.GM_INFO.gameId;
    data.userId = GameData._instance.GM_INFO.userId;
    const time = Math.floor((new Date().getTime()) / 1000)
    const url = HttpUtil.apiSign(`/api/get/rank/data?gameId=${config.gameId}&dataType=${type}&time=${time}`, data)

    this.httpPost(url,data,callback);
  }
  
  static async uploadUserLogData(data,callback): Promise<any> {
    data.gameId = GameData._instance.GM_INFO.gameId;
    data.userId = GameData._instance.GM_INFO.userId;
    const url = '/log/collect/data';
    this.httpPost(url,data,callback);
  }
  //暂时用不到
  static async getUserRecord(data,callback): Promise<any> {
    data.gameId = GameData._instance.GM_INFO.gameId;
    data.userId = GameData._instance.GM_INFO.userId;
    const time = Math.floor((new Date().getTime()) / 1000)
    const url = HttpUtil.apiSign(`/api/get/user/data?gameId=${config.gameId}&time=${time}`, data)
    this.httpPost(url,data,callback);
  }

  static httpPost(url,data,callBack){
      if(data){
        data.gameId = GameData._instance.GM_INFO.gameId;
        data.userId = GameData._instance.GM_INFO.userId;
      }

      var urlData = "https://api.sparkus.cn" + url;
      // console.log("params:",JSON.stringify(data));
      let xhr = new XMLHttpRequest();
      xhr.open('POST', urlData);
      xhr.setRequestHeader('Content-Type', 'application/json');
      xhr.onreadystatechange = function () {
          if (xhr.readyState == 4 && xhr.status == 200) {
              var data = xhr.responseText;
              if(!data){
                  console.log("初始化失败");
                  return;
              }
              console.log(data);
              var json = JSON.parse(data);
              console.log('http success:' + json);
              if(callBack)callBack(json);
          }
          else{
            //  var json = JSON.parse(data);
              // console.log('http fail:' + url);
              if(callBack)callBack(json);
          }
      };
      xhr.send(JSON.stringify(data));
  }

  static httpGet(url,callBack){
      var urlData = "https://api.sparkus.cn" + url;
      console.log(urlData);
      let xhr = new XMLHttpRequest();
      xhr.open('GET', urlData);
      xhr.setRequestHeader('Content-Type', 'text/plain');
      
      xhr.onreadystatechange = function () {
          if (xhr.readyState == 4 && xhr.status == 200) {
              var data = xhr.responseText;
              if(data){
                  var json = JSON.parse(data);
                  console.info('http success:' + json);
                  if(callBack)callBack(json);
              }
              else{
                if(callBack)callBack(json);
              }   
           
          }
          else{
              console.info('http fail:' + url);
              if(callBack)callBack(null);;
          }
      };
      xhr.send();
  }

  /**
 * 
 * @param url {string} 接口地址
 * @param params {object} 需要加密的参数对象
 */
    static apiSign(url: string, params = {}) {

    let convertUrl = url.trim()
    if (convertUrl.indexOf('?') === -1) {
      convertUrl += '?'
    }

    // 传入参数转换拼接字符串
    let postStr =  getQueryString(params)

    const signedStr = genSignStr(convertUrl, postStr)
    const encryptStr = `sign=${signedStr}`

    let encryptSignStr = fxCry.encryptByDES(encryptStr, config.secretKey)
    encryptSignStr = encodeURIComponent(encryptSignStr)

    return `${urlencode(convertUrl)}&_p=${encryptSignStr}`
    }
}

function responseHandler(response: { data: any }) {
  return response.data
}
// 响应拦截器
// Rq.interceptors.response.use(responseHandler)
const config = {
  gameId: "100001",
  secretKey: "zDLsruVI",
  EK:"hui231%1"
};

interface CrypotoType {
  encryptByDES: any
  decryptByDES: any
  hmacSha256: any
}
 
class Crypoto implements CrypotoType {
    // 加密的向明值，自己根据项目实际情况定，需要跟后端开发保持一致
    private keyHex = this.getHetKey()
 
    private getHetKey() {
        return CryptoJS.enc.Utf8.parse(config.EK);
    }

    /** DES加密 */
    encryptByDES(message: string, secret?: string) {
      if(!message) {
        return message
      }
      const key = secret? CryptoJS.enc.Utf8.parse(secret): this.keyHex
      const encrypted = CryptoJS.DES.encrypt(message, key, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
      });
      return encrypted.toString()
    }

    /** DES解密 */
    decryptByDES(message: string, secret?: string) {
      const key = secret? CryptoJS.enc.Utf8.parse(secret): this.keyHex

      const decrypted = CryptoJS.DES.decrypt({
        ciphertext: CryptoJS.enc.Base64.parse(message)
      }, key, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
      })

      return decrypted.toString(CryptoJS.enc.Utf8)
    }

    /** hmacSHA256加密 */
    hmacSha256(message: string, secret?: string) {
      const keyHex = secret? CryptoJS.enc.Utf8.parse(secret): this.keyHex
      
      const hash = CryptoJS.HmacSHA256(message, keyHex);
      return hash.toString()
    }

    /** hmacSHA256验证 */
    verifyHmacSha256(message: string, signature: string) {
      const hash = CryptoJS.HmacSHA256(message, this.keyHex);
      return hash.toString() === signature
    }
 
    /** CBC加密 */
    encryptCBC(word: string) {
        if (!word) {
            return word;
        }
        const srcs = CryptoJS.enc.Utf8.parse(word);
        const encrypted = CryptoJS.AES.encrypt(srcs, this.keyHex, {
            iv: this.keyHex,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.ZeroPadding
        });
        return encrypted.toString(); 
    }
 
    /** CBC解密 */
    decryptCBC(word: string) {
        if (!word) {
            return word;
        }
        const encryptedHexStr = CryptoJS.enc.Hex.parse(word);
        const srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
        const decrypt = CryptoJS.AES.decrypt(srcs, this.keyHex, {
            iv: this.keyHex,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.ZeroPadding
        });
        const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
        return decryptedStr.toString();
    }
}
const fxCry = new Crypoto();

function isEmpty(data) {
  return data === "" || data === null || data === undefined || data.length === 0 || JSON.stringify(data) == "{}"
}

function getQueryString(obj) {
  // 首先对对象的键进行排序并过滤空值
  const sortedKeys = Object.keys(obj).sort();
  const sortedObj = {};
  for (let i = 0; i < sortedKeys.length; i++) {
    if (isEmpty(obj[sortedKeys[i]])) {
      continue;
    }
    sortedObj[sortedKeys[i]] = obj[sortedKeys[i]];
  }
  
  // 然后将排序后的对象转换为查询字符串
  const params = [];
  for (const key in sortedObj) {
    params.push(`${encodeURIComponent(key)}=${encodeURIComponent(sortedObj[key])}`);
  }
  return params.join('&');
}


/**
 * 组装签名字符串
 * @param string url: 请求地址 
 * @param string postStr: post参数的a=1&b=2 
 * @returns 
 */

function genSignStr(url: string, postStr: string): string {
  let lessUrl = url.replace('?', '')
  lessUrl = lessUrl + "&" + postStr
  return encodeURIComponent(fxCry.hmacSha256(lessUrl))
}
// 对参数进行统一urlencode
function urlencode(url: string): string {
  const [baseUrl, queryString] = url.split("?", 2);
  const params = new URLSearchParams(queryString);
  return `${baseUrl}?${params.toString()}`;
}



