const BASE_URL = import.meta.env.VITE_API_BASE;

const MOCK_DELAY = 300;

const mock = (data, delay = MOCK_DELAY) =>
  new Promise((resolve) => setTimeout(() => resolve(data), delay));

function parseJsonPreserveLongIds(text) {
  if (!text) return null;
  let result = "";
  let inString = false;
  let escaped = false;

  for (let i = 0; i < text.length; i += 1) {
    const char = text[i];

    if (inString) {
      result += char;
      if (escaped) {
        escaped = false;
      } else if (char === "\\") {
        escaped = true;
      } else if (char === "\"") {
        inString = false;
      }
      continue;
    }

    if (char === "\"") {
      inString = true;
      result += char;
      continue;
    }

    const startsNumber = char === "-" || (char >= "0" && char <= "9");
    if (!startsNumber) {
      result += char;
      continue;
    }

    const start = i;
    if (char === "-") i += 1;
    while (i < text.length && text[i] >= "0" && text[i] <= "9") i += 1;

    const numberText = text.slice(start, i);
    const nextChar = text[i];
    const isInteger = nextChar !== "." && nextChar !== "e" && nextChar !== "E";
    const digitCount = numberText.startsWith("-") ? numberText.length - 1 : numberText.length;
    result += isInteger && digitCount >= 16 ? `"${numberText}"` : numberText;
    i -= 1;
  }

  return JSON.parse(result);
}

export const fetchApi = async (url, options = {}) => {
  const fullUrl = url.startsWith("http") ? url : BASE_URL + url;
  const token = localStorage.getItem("token");
  const isFormData = options.body instanceof FormData;

  const config = {
    headers: {
      ...(isFormData ? {} : { "Content-Type": "application/json" }),
      ...(token ? { Authorization: `Bearer ${token}` } : {}),
      ...options.headers,
    },
    ...options,
  };

  try {
    const res = await fetch(fullUrl, config);
    const raw = await res.text();
    const data = parseJsonPreserveLongIds(raw);
    if (!res.ok) {
      throw new Error(data.message || `请求失败: ${res.status}`);
    }
    return data;
  } catch (error) {
    console.error(`[API] ${options.method || "GET"} ${fullUrl}`, error);
    throw error;
  }
};

export const get = (url, params, options = {}) => {
  const query = params
    ? "?" + new URLSearchParams(params).toString()
    : "";
  return fetchApi(url + query, { ...options, method: "GET" });
};

export const post = (url, data, options = {}) =>
  fetchApi(url, {
    ...options,
    method: "POST",
    body: JSON.stringify(data),
  });

export const postForm = (url, formData, options = {}) =>
  fetchApi(url, {
    ...options,
    method: "POST",
    body: formData,
  });

export const put = (url, data, options = {}) =>
  fetchApi(url, {
    ...options,
    method: "PUT",
    body: JSON.stringify(data),
  });

export const del = (url, data, options = {}) => {
  const config = { ...options, method: "DELETE" };
  if (data) config.body = JSON.stringify(data);
  return fetchApi(url, config);
};

export { mock };
