import { ENV, STORAGE_KEYS } from './env';
import { md5 } from './md5';

const DEFAULT_TIMEOUT = ENV.REQUEST_TIMEOUT || 15000;

function buildQuery(params = {}) {
  const entries = Object.entries(params).filter(([, value]) => value !== undefined && value !== null);
  if (!entries.length) return '';
  return entries
    .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)
    .join('&');
}

function combineUrl(base, path) {
  if (/^https?:\/\//i.test(path)) return path;
  const normalizedBase = (base || '').replace(/\/$/, '');
  const normalizedPath = (path || '').replace(/^\//, '');
  return `${normalizedBase}/${normalizedPath}`;
}

function request(method, url, data = {}, options = {}) {
  const isQuery = method === 'GET' || method === 'DELETE';
  const params = isQuery ? data : (options.params || {});
  let finalUrl = combineUrl(ENV.API_BASE_URL, url);
  const queryString = buildQuery(params);
  if (queryString) {
    finalUrl += (finalUrl.includes('?') ? '&' : '?') + queryString;
  }

  const header = Object.assign(
    { 'content-type': 'application/json' },
    options.header || {}
  );

  if (ENV.SECURITY_ENABLE && ENV.SECURITY_SECRET_KEY) {
    const timestamp = Date.now().toString();
    header['X-App-Timestamp'] = timestamp;
    header['X-App-Sign'] = md5(timestamp + ENV.SECURITY_SECRET_KEY);
  }

  const token = uni.getStorageSync(STORAGE_KEYS.TOKEN);
  if (token) {
    header.Authorization = `Bearer ${token}`;
  } else if (!options.allowGuest) {
    uni.showModal({
      title: '提示',
      content: '未登录，请先登录',
      showCancel: false,
      success: () => {
        uni.navigateTo({ url: '/pages/login/login' });
      }
    });
    return Promise.reject({ message: '未登录' });
  }

  return new Promise((resolve, reject) => {
    uni.request({
      url: finalUrl,
      method,
      data: isQuery ? {} : data,
      header,
      timeout: options.timeout || DEFAULT_TIMEOUT,
      success: (res) => {
        const { statusCode, data: resData } = res;
        const businessCode = resData && typeof resData.code !== 'undefined' ? resData.code : null;
        if (statusCode === 401 || businessCode === 401) {
          uni.showModal({
            title: '提示',
            content: '登录已失效，请重新登录',
            showCancel: false,
            success: () => {
              uni.removeStorageSync(STORAGE_KEYS.TOKEN);
              uni.removeStorageSync(STORAGE_KEYS.USER_INFO);
              uni.navigateTo({ url: '/pages/login/login' });
            }
          });
          reject({ message: '登录失效', statusCode, data: resData });
          return;
        }
        if (statusCode >= 200 && statusCode < 300) {
          resolve(options.raw ? res : resData);
          return;
        }
        reject({
          message: resData && (resData.msg || resData.message) ? (resData.msg || resData.message) : '请求失败',
          statusCode,
          data: resData
        });
      },
      fail: (err) => {
        reject(err);
      }
    });
  });
}

export const get = (url, params, options) => request('GET', url, params, options);
export const post = (url, data, options) => request('POST', url, data, options);
export const put = (url, data, options) => request('PUT', url, data, options);
export const del = (url, params, options) => request('DELETE', url, params, options);

export default request;
