import type { UrlKey, MethodKey, Param, Response } from './index';
// import { message } from 'ant-design-vue';
// import { LocalStorageKey } from '@/utils/useLocalStorage';
// import { getAppEnvConfig } from '@/utils/env';
import { reactive, ref } from 'vue';
import { defHttp } from '/@/utils/http/axios';
// const { VITE_BASE_API, VITE_PREFIX_API } = getAppEnvConfig();
export type FetchOptions = Omit<RequestInit, 'body' | 'method'> & {
  type?: 'arrayBuffer' | 'blob' | 'formData' | 'json' | 'text';
  payloadType?: 'json' | 'text' | 'formData' | 'form-urlencoded';
  successMsg?: string;
  noMsg?: boolean;
  apiType?: 'BOOK';
};

// const payloadMapping = {
//   json: 'application/json;charset=UTF-8',
//   text: 'text/plain;charset=UTF-8',
//   formData: 'multipart/form-data',
//   'form-urlencoded': 'application/x-www-form-urlencoded',
// };

// // const noAuthUrl: UrlKey[] = ['/activity/bbs/login', '/activity/bbs/randomImage', '/activity/bbs/bbsSection/all', '/activity/bbs/bbsPost/list', '/activity/bbs/bbsPost/queryById'];
// const noAuthUrl: UrlKey[] = ['/activity/bbs/login', '/activity/bbs/randomImage'];
// function useAuthToken() {
//   // const _token = localStorage.getItem(LocalStorageKey.tokenKey);
//   return {
//     token: '',
//     // token: _token && _token.trim().length > 0 ? _token : null,
//   };
// }

/**
 * 请求header
 * @description:  contentTyp
 */
export enum ConfigEnum {
  // TOKEN
  TOKEN = 'Authorization',
  XTOKEN = 'X-Access-Token',
  // TIMESTAMP
  TIMESTAMP = 'X-TIMESTAMP',
  // Sign
  Sign = 'X-Sign',
  // 租户id
  TENANT_ID = 'X-Tenant-Id',
  // 版本
  VERSION = 'X-Version',
  // 低代码应用ID
  X_LOW_APP_ID = 'X-Low-App-ID',
}

// export const baseToken = ref<string | null>(useAuthToken().token);
// export function getHeaders() {
//   const defaultHeaders = {
//     // "Content-Type": payloadMapping[payloadType]
//   };

//   let authHeaders = {
//     Authorization: `Bearer ${baseToken.value}`,
//   };
//   return Object.assign(defaultHeaders, authHeaders);
// }

type MethodType = 'OPTIONS' | 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'TRACE' | 'CONNECT';
/**
 *
 * @param url 路径，直接从swagger上拷贝下来的路径，包括{id}这类的动态路径
 * @param param FetchParams 请求参数，分为 path query body 分别对应 路径参数（类似/delete/{id}）、查询参数（类似/query？id=123）、body（post body参数，将会JSON.stringfiy为字符串）
 * @param options FetchOptions fetch 去除body、method的原生参数，增加 type 用于格式化掉用res.json()类型的功能。
 * @returns fetch
 */
export default async function request<U extends UrlKey, M extends MethodKey<U>>(
  url: U,
  method: M,
  params?: Param<U, M> | undefined,
  { apiType, type = 'json', payloadType = 'json', successMsg, noMsg, headers, ...restOptions }: FetchOptions = {}
): Promise<Response<U, M>> {
  const requestMethod = (method as string).toLowerCase() as MethodType;

  const { path, query, data } = (params || {}) as {
    path?: string[] | string;
    query?: any;
    data?: any;
  };
  // let iUrl = `${VITE_BASE_API}${VITE_PREFIX_API}${url}`;
  let iUrl = `${url}`;

  if (path) {
    if (Array.isArray(path)) {
      iUrl = `${iUrl}/${path.join('/')}`;
    } else {
      iUrl = `${iUrl}/${path}`;
    }
  }
  iUrl = getQuery(iUrl, filterEmpty(query));

  return defHttp.request({
    method: requestMethod,
    url: iUrl,
    data: filterEmpty(data),
  });

  // const defaultHeaders = {
  //   'Content-Type': payloadMapping[payloadType],
  // };

  // // 将token加入进去
  // let authHeaders: any = {
  //   // 'Content-Type': 'application/json'
  // };
  // if (!noAuthUrl.includes(url)) {
  //   // const { token } = useAuthToken();
  //   authHeaders[ConfigEnum.TOKEN] = baseToken.value ? `Bearer ${baseToken.value}` : '';
  //   // authHeaders[ConfigEnum.XTOKEN] = token;
  // }
  // const param: any = {
  //   ...restOptions,
  //   method: requestMethod,
  //   // body: JSON.stringify(filterEmpty(data)),
  //   headers: Object.assign(defaultHeaders, headers, authHeaders),
  // };
  // if (requestMethod.toLowerCase() !== 'get') {
  //   param.body = JSON.stringify(filterEmpty(data));
  // }
  // return fetch(iUrl, param)
  //   .then((response) => response.json())
  //   .then((res: any) => {
  //     if (res.code === 200 || res.code === 0) {
  //       if (requestMethod.toLowerCase() != 'get' || successMsg) {
  //         if (!noMsg) {
  //           showToast(successMsg || '操作成功', 'success');
  //         }
  //       }
  //       return res.result;
  //     } else if (res.code === 401) {
  //       baseToken.value = null;
  //       showToast('登录已过期', 'error');
  //     } else {
  //       let msg = res.message;
  //       if (res.code === 402) {
  //       } else if (res.code === 403) {
  //       } else {
  //       }
  //       showToast(msg, 'error');
  //     }

  //     throw new Error(JSON.stringify(res));
  //   })
  //   .catch((err) => {
  //     console.error('fetch Error', err);

  //     throw err;
  //   });
}
function filterEmpty(obj: any = {}): any {
  const _obj: any = {};
  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      const element = obj[key];
      if (!(element === null || element === undefined || String(element).trim().length < 1)) {
        _obj[key] = element;
      }
    }
  }
  return _obj;
}

function getQuery(iUrl: string, query: { [key: string]: string }): string {
  if (!query) {
    return iUrl;
  }
  const keys: string[] = [];
  for (const key in query) {
    keys.push(`${key}=${query[key]}`);
  }
  return `${iUrl}?${keys.join('&')}`;
}

// type MsgType = 'error' | 'success' | 'loading' | 'info' | 'warning';
// function showToast(msg: string, type: MsgType) {
//   message[type](msg);
// }

type CallbackObjs = {
  loading: boolean;
  callback: Function[][];
};
type Requests = {
  userOpenid: CallbackObjs;
};
type RequestsName = keyof Requests;
const requests = reactive<Requests>({
  userOpenid: {
    loading: false,
    callback: [],
  },
});
/**
 *
 * 请求节流封装
 * @param name 求节nameKey
 * @param requestCallback
 * @returns
 */
export async function getRequests(name: RequestsName, requestCallback: Function) {
  // const requestInfo = requests[name];
  //
  if (requests[name].loading) {
    return new Promise<[]>((resolve, reject) => {
      requests[name].callback.push([resolve, reject]);
    });
  }
  requests[name].loading = true;

  try {
    const data = await requestCallback();
    requests[name].callback.forEach((callbacks) => {
      const [resolve, reject] = callbacks;
      !!resolve && resolve(data);
    });
    requests[name].loading = false;
    requests[name].callback = [];
    return data;
  } catch (error) {
    requests[name].callback.forEach((callbacks) => {
      const [resolve, reject] = callbacks;
      reject([]);
    });
  } finally {
    requests[name].loading = false;
    requests[name].callback = [];
  }
}
