import qs from "../lib/qs/shim.js";
import { isLogin } from "../api/user.js";
import { useAppStore } from "../store/index.js";
import { getFileName } from "../utils/index.js";
import settings from "../config/settings.js";
import { ElMessageBox } from "element-plus";

// const requestSettings = {
//   baseURL: "/api",
// };

const addToken = async (options) => {
  if (await isLogin()) {
    const appStore = useAppStore();
    options.headers ??= {};
    options.headers.Authorization = `Bearer ${appStore.token}`;
  }
};

const getUrl = (url) => {
  if (url.startsWith("http")) {
    return url;
  }
  let result = settings.baseURL;
  return (result += `/${url}`);
  // let result = requestSettings.baseURL;
  // if (withoutCulture) {
  //   result += `/${url}`;
  // } else {
  //   const appStore = useAppStore();
  //   result += withoutCulture ? "/" : `/${appStore.localization.locale}/`;
  //   result += url;
  // }
  // return result;
};

const getResult = async (response) => {
  const messages = new Map([
    [200, "操作成功"],
    [201, "已创建"],
    [204, "无返回值"],
    [400, "请求参数错误"],
    [401, "未登录"],
    [403, "权限不足"],
    [500, "服务器异常"],
    [503, "服务不可用"],
  ]);
  const result = {
    status: response.status,
    message: messages.get(response.status),
  };
  if (response.status === 200 || response.status === 201 || response.status === 204) {
    const contentType = response.headers.get("Content-Type");
    if (contentType.indexOf("application/json") > -1) {
      result.data = await response.json();
    } else if (contentType.indexOf("text/plain") > -1) {
      result.data = await response.text();
    } else if (contentType === "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") {
      result.data = await response.blob();
      result.filename = getFileName(response.headers.get("Content-Disposition"));
    }
  } else {
    try {
      result.errors = await response.json();
    } catch (error) {
      console.log(error);
    }
    ElMessageBox.alert(
      `${result.errors?.error?.message ?? messages.get(response.status) ?? result.status}`,
      `${result.errors?.error?.code ?? result.status}`
    );
  }
  return result;
};

const get = async (url, data, options, withoutToken = false) => {
  url = getUrl(url);
  if (data) {
    url = `${url}?${qs.stringify(data)}`;
  }
  const defaultOptions = {
    headers: { "Accept-Language": "zh-Hans" },
  };
  if (options) {
    Object.assign(defaultOptions, options);
  }
  if (!withoutToken) {
    await addToken(defaultOptions);
  }
  const response = await fetch(url, defaultOptions);
  return getResult(response);
};

const post = async (url, data, options, withoutToken = false) => {
  url = getUrl(url);
  let defaultOptions = {
    method: "POST",
    headers: { "Accept-Language": "zh-Hans" },
  };
  if (!(data instanceof FormData)) {
    defaultOptions.headers["Content-Type"] = "application/json";
  }
  if (options) {
    Object.assign(defaultOptions, options);
  }
  if (data && !defaultOptions.body) {
    if (defaultOptions.headers["Content-Type"]?.startsWith("application/x-www-form-urlencoded")) {
      defaultOptions.body = qs.stringify(data);
    } else if (defaultOptions.headers["Content-Type"]?.startsWith("application/json")) {
      defaultOptions.body = JSON.stringify(data);
    } else {
      defaultOptions.body = data;
    }
  }
  if (!withoutToken) {
    await addToken(defaultOptions);
  }
  const response = await fetch(url, defaultOptions);
  return getResult(response);
};

async function request(url, data, options, withoutToken = false) {
  url = getUrl(url);
  let defaultOptions = {
    method: "POST",
    headers: {
      "Accept-Language": "zh-Hans",
    },
  };
  if (options) {
    Object.assign(defaultOptions, options);
  }
  if (defaultOptions.method === "GET" && data) {
    url = `${url}?${qs.stringify(data)}`;
  } else {
    if (defaultOptions.headers["Content-Type"]?.startsWith("application/x-www-form-urlencoded")) {
      defaultOptions.body = qs.stringify(data);
    } else if (defaultOptions.headers["Content-Type"]?.startsWith("application/json")) {
      defaultOptions.body = JSON.stringify(data);
    } else if (data instanceof FormData) {
      delete defaultOptions.headers["Content-Type"];
      defaultOptions.body = data;
    } else if (data) {
      defaultOptions.headers["Content-Type"] = "application/json";
      defaultOptions.body = JSON.stringify(data);
    }
  }
  if (!withoutToken) {
    await addToken(defaultOptions);
  }
  const response = await fetch(url, defaultOptions);
  return getResult(response);
}

export default request;
export { get, post, getUrl };