import axios from "axios";
import React from "react";
import { message, Modal } from "antd";

const { warning } = Modal;

const instance = axios.create({
  baseURL: SERVER_BASE,
  timeout: 10000,
  // withCredentials: true, // 跨域
});

// 0 无提示
const SILENT_ALL = 0;
// 1 提示失败
const SHOW_FAIL = 1;
// 2 提示成功
const SHOW_SUCCESS = 2;

// 添加请求拦截器
instance.interceptors.request.use(
  function (config) {
    const {
      headers = {},
      method = "get",
      responseType = "json",
      download = false,
      silent = -1,
      params = {},
      data,
    } = config;
    let token = localStorage.getItem("token") || "";
    let silentLevel = silent;

    if (silentLevel === -1) {
      silentLevel =
        method.toLocaleLowerCase() === "get"
          ? SHOW_FAIL
          : SHOW_FAIL | SHOW_SUCCESS;
    }

    const contentType =
      data instanceof FormData
        ? "multipart/form-data"
        : "application/json;charset=utf-8";

    const ticketOrigin = localStorage.getItem("ticket");
    if (params.ticket && params.ticket != ticketOrigin) {
      token = "";
      localStorage.setItem("ticket", params.ticket);
    } else {
      // params.ticket = undefined,
      // params.appid = undefined;
      delete params.ticket;
      delete params.appid;
    }

    // 在发送请求之前做些什么
    return {
      ...config,
      silent: silentLevel,
      headers: {
        "Content-Type": contentType,
        Authorization: token,
        ...headers,
      },
      responseType: download ? "blob" : responseType,
    };
  },
  function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  }
);

// 添加响应拦截器
instance.interceptors.response.use(
  function (response) {
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么

    const { data, config, headers } = response;
    if (config.download) {
      if (headers["content-type"].includes("json")) {
        return data.text().then((jsonStr) => {
          const { msg } = JSON.parse(jsonStr);
          if (config.silent & SHOW_FAIL) {
            message.error(msg);
          }
        });
      } else {
        return downloadBlob(response, "下载文件");
      }
    }

    if (data.code === 1000 || data.code === 200) {
      if (data.data?.token) {
        localStorage.setItem("token", data.data.token);
      }

      if (config.silent & SHOW_SUCCESS) {
        console.log(data.msg);
        message.success(data.msg == "ok" || data.msg == "success" ? "操作成功" : data.msg);
      }

      return data.data;
    } else if (data.code === 1001 || data.code === 401) {
      if (config.silent & SHOW_FAIL) {
        message.error("未登录或者超时, 请重新登录");
      }

      if (data.code === 401) {
        warning({
          title: "登录提示",
          content: "登录超时或异常，请重新登录",
          okText: "重新登录",
          onOk() {
            window.location.href = getLoginPage();
          },
        });
      }
    } else {
      if (config.silent & SHOW_FAIL) {
        const errMsg = data.msg || data.message || "系统错误";
        message.error(errMsg.indexOf("exception") > -1 ? "服务异常" : errMsg);
      }
    }

    return Promise.reject(response);
  },
  function (error) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么

    console.error(error);

    return Promise.reject("网络异常, 请重试...");
  }
);

export default instance;

export function queryTable(apiRequest, options = {}) {
  return function (params, sort, filter) {
    const fullParams = {
      ...params,
      pageNum: params.current,
    };

    if (options.paramsCallback) {
      options.paramsCallback(fullParams);
    }

    return apiRequest(fullParams)
      .then((res) => {
        return {
          data: res.records,
          success: true,
          total: res.total,
        };
      })
      .catch((err) => {
        console.error("网络异常", err.message);
        return {
          success: false,
          error: err.message,
        };
      });
  };
}

export function queryDict(
  apiRequest,
  { labelKey = "name", valueKey = "id", show = false }
) {
  return function (params) {
    const { current, pageSize, ...leftParams } = params || {};
    return apiRequest({
      pageSize: 9999,
      pageNum: 1,
      ...(leftParams || {}),
    })
      .then((res) => {
        return res?.records?.map((x) => ({
          label: show ? x[labelKey] + " " + x.name : x[labelKey],
          value: x[valueKey],
          ...x,
        }));
      })
      .catch((err) => {
        return {
          success: false,
        };
      });
  };
}

export function restful(url) {
  const list = (params) => instance.get(url, { params });
  const get = (id) => instance.get(`${url}/${id}`);
  const add = (data) => instance.post(url, data);
  const update = (id, data) => instance.put(`${url}/${id}`, data);
  const del = (id) => instance.delete(`${url}/${id}`);

  return [list, get, add, update, del];
}

export function useRequest(fn) {
  const [loading, setLoading] = React.useState(false);

  const p = (...args) =>
    new Promise((resolve, reject) => {
      setLoading(true);
      fn(...args)
        .then((res) => {
          setLoading(false);
          resolve(res);
        })
        .catch((e) => {
          setLoading(false);
          reject(e);
        });
    });

  return [loading, p];
}

function downloadBlob(response) {
  let fileName = "未知文件";
  const contentType = response.headers["content-type"];
  const contentDisposition = response.headers["content-disposition"];
  if (contentDisposition) {
    const parts = contentDisposition.split(";filename=");
    if (parts[1]) {
      fileName = decodeURIComponent(parts[1]);
    }
  }

  const url = window.URL.createObjectURL(
    new Blob([response.data], { type: contentType })
  );
  const link = document.createElement("a");
  link.href = url;
  link.setAttribute("download", fileName);
  link.click();
  window.URL.revokeObjectURL(url);
}
