import axios from "axios";
import CryptoJS from "crypto-js";
import NProgress from "nprogress";
import "nprogress/nprogress.css";
import { ElMessage } from "element-plus";
import { encodeParam, decodeParam } from "./editorParams";
import appUtils from "./appUtils";
import appConfig from "./appConfig";

const service = axios.create({
  baseURL: "/",
  timeout: 15000,
});

service.interceptors.response.use(
  (response) => response,
  (error) => {
    const res = {
      code: error.response?.status || 500,
      message: error.message || "网络请求异常",
      data: {},
    };
    return res;
  }
);

const domainUrl = (serveUrl, path) => {
  let url = serveUrl + path;
  return url;
};

const setheader = (dataType) => {
  let header = {};
  if (dataType === "json") {
    header["Content-Type"] = "application/json;charset=UTF-8";
  } else {
    header["Content-Type"] = "application/x-www-form-urlencoded;charset=UTF-8";
  }
  header["x-channel"] = "official";
  header["x-version"] = "1.0.0";
  header["x-platform"] = "web";
  header["x-app-id"] = "10037"; // 添加 appid 以满足微信鉴权后端要求
  let deviceId = localStorage.getItem("device_id");
  if (!deviceId) {
    deviceId = appUtils.generateUUID();
    localStorage.setItem("device_id", deviceId);
  }
  header["x-device-id"] = deviceId;
  header["x-mobile-brand"] = "pc";
  header["x-mobile-model"] = "pc";
  header["x-package"] = "com.devcon.flaunt";
  const token = localStorage.getItem("token");
  if (token) {
    header["x-token"] = token;
  }
  return header;
};

const ENCRYPT_KEY = "xn08hYoizXhZ1zHP8DVqfCm2yHxPmhil";
const DECRYPT_KEY = "e4rOtnF8tJjtHO7ecZeJHN1rapED5ImB";

const deCode = (str) => {
  if (!str) return str;
  const keys = [
    DECRYPT_KEY,
    ENCRYPT_KEY,
    "0b0d7962d67a76f00cf9fe0eec0061c2"
  ];
  for (let kStr of keys) {
    try {
      let key = CryptoJS.enc.Utf8.parse(kStr);
      let iv = key.clone();
      iv.sigBytes = 16;
      iv.clamp();
      let decrypted = CryptoJS.AES.decrypt(str, key, {
        iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7,
      }).toString(CryptoJS.enc.Utf8);
      if (decrypted) {
        let res = JSON.parse(decrypted);
        return res;
      }
    } catch (e) {
      // 捕获单个 key 解密失败异常，继续尝试下一个候选 Key
    }
  }
  console.error("AES 解密异常: 无法完成响应数据解密", str);
  return null;
};

const parseResp = (data) => {
  if (typeof data === "string") {
    try {
      return JSON.parse(data)
    } catch {
      return data
    }
  }
  return data
}

const request = (method = "GET", serverUrl, pathUrl, params = {}, dataType) => {
  NProgress.start();
  params = appUtils.deepClone(params) || {};
  let keyStr = ENCRYPT_KEY;
  let url = domainUrl(serverUrl, pathUrl);
  let data = {
    ...{
      url,
      method,
      headers: setheader(dataType)
    },
    ...method === "GET" || method === "DELETE" ? { params } : { data: params }
  };

  // if (method === "GET" || method === "DELETE") {
  //   params.timestamp = Math.floor(new Date().getTime() / 1000);
  //   params.nonce = appUtils.generateUUID();
  //   let keys = Object.keys(params);
  //   keys.sort();
  //   for (let i in keys) {
  //     keys[i] = keys[i] + "=" + encodeURIComponent(params[keys[i]]);
  //   }
  //   let temp = keys.join("&") + "&" + CryptoJS.MD5(keyStr).toString();
  //   params.signature = CryptoJS.MD5(temp).toString();
  //   data = {
  //     url,
  //     method,
  //     headers: setheader(dataType),
  //     params: params,
  //   };
  // } else if (method === "POST" || method === "PUT") {
  //   let temp = decodeParam(url);
  //   temp.timestamp = Math.floor(new Date().getTime() / 1000);
  //   temp.nonce = appUtils.generateUUID();
  //   let keys = Object.keys(temp);
  //   keys.sort();
  //   for (let i in keys) {
  //     keys[i] = keys[i] + "=" + encodeURIComponent(temp[keys[i]]);
  //   }
  //   let s = keys.join("&");
  //   s += "&" + JSON.stringify(params);
  //   s += "&" + CryptoJS.MD5(keyStr).toString();
  //   temp.signature = CryptoJS.MD5(s).toString();
  //   url = url.split("?")[0] + "?" + encodeParam(temp);
  //   data = {
  //     url,
  //     method,
  //     headers: setheader(dataType),
  //     data: params,
  //   };
  // }

  return new Promise((resolve, reject) => {
    service(data)
      .then((res) => {
        NProgress.done();
        if (res.status === 200) {
          let resData = parseResp(res.data);

          // if (resData && resData.encrypt) {
          //   const decoded = deCode(resData.data);
          //   if (decoded) {
          //     resData = decoded;
          //   } else {
          //     resData = { code: -1, message: "数据解密失败" };
          //   }
          // }
          if (resData.code !== 0) {
            if (resData.code === 1001003 || resData.code === 1001004) {
              localStorage.removeItem("token");
              // window.location.reload();
              reject(resData);
            } else if (!appConfig.ignoreCodeErrorList.includes(`${method}&${pathUrl}`)) {
              const errMsg = resData.message ? resData.message.split(",")[0] : "请求失败";
              ElMessage.error(errMsg);
              reject(resData);
            }
            return;
          }
          resolve(resData);
        } else {
          resolve(res);
        }
      })
      .catch((err) => {
        NProgress.done();
        ElMessage.error("网络错误");
        reject(err);
      });
  });
};

export const get = (serverUrl, url, params = {}) => request("GET", serverUrl, url, params);
export const post = (serverUrl, url, params = {}) => request("POST", serverUrl, url, params);
export const postJson = (serverUrl, url, params = {}) => request("POST", serverUrl, url, params, "json");
export const put = (serverUrl, url, params = {}) => request("PUT", serverUrl, url, params);
export const putJson = (serverUrl, url, params = {}) => request("PUT", serverUrl, url, params, "json");
export const del = (serverUrl, url, params = {}) => request("DELETE", serverUrl, url, params);
export const delJson = (serverUrl, url, params = {}) => request("DELETE", serverUrl, url, params, "json");

export default {
  get,
  post,
  postJson,
  put,
  putJson,
  del,
  delJson,
};
