// API 基础配置
import { getApiBaseUrl, getServerBaseUrl } from './config';
import { debugApiRequest, debugApiResponse, debugApiError } from './debug';

// 获取不同平台的 API 地址
const BASE_URL = getApiBaseUrl();

// 开发环境使用本地 API，生产环境使用线上 API
const isDev = typeof process !== 'undefined' && process.env && process.env.NODE_ENV === 'development';

// 请求配置
interface RequestConfig {
  retry?: number;        // 重试次数
  retryDelay?: number;   // 重试延迟（ms）
  timeout?: number;      // 超时时间（ms）
  cache?: boolean;       // 是否缓存
  cacheTTL?: number;     // 缓存时间（ms）
}

// 请求缓存
const requestCache = new Map<string, { data: any; timestamp: number }>();

// 获取完整的后端 URL（用于音频文件等静态资源）
export function getFullUrl(path: string): string {
  // 如果已经是完整 URL，直接返回
  if (path.startsWith('http://') || path.startsWith('https://')) {
    return path;
  }
  // 使用 config 中的 getServerBaseUrl 获取后端地址
  const backendUrl = getServerBaseUrl();
  // 确保服务器地址是完整的 https URL，避免浏览器认为是相对路径
  if (!backendUrl.startsWith('http')) {
    // 如果 backendUrl 是相对路径（如 '/' 或 ''），使用生产环境域名
    console.warn('[Request] backendUrl 是相对路径，使用生产环境域名:', backendUrl);
    return 'https://book.rrbrr.com' + path;
  }
  return backendUrl + path;
}

// 请求封装
export async function request<T = unknown>(
  url: string,
  options: {
    method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
    data?: Record<string, unknown>;
    header?: Record<string, string>;
    showLoading?: boolean;
    config?: RequestConfig;
  } = {}
): Promise<T> {
  const { method = 'GET', data, header = {}, showLoading = false, config = {} } = options;
  const { retry = 0, retryDelay = 1000, timeout = 30000, cache = false, cacheTTL = 300000 } = config;

  // 检查缓存（仅 GET 请求）
  if (cache && method === 'GET') {
    const cacheKey = url + JSON.stringify(data);
    const cached = requestCache.get(cacheKey);
    if (cached && Date.now() - cached.timestamp < cacheTTL) {
      return cached.data as T;
    }
  }

  // 获取 token
  const token = uni.getStorageSync('token');
  if (token) {
    header['Authorization'] = `Bearer ${token}`;
  }
  header['Content-Type'] = 'application/json';

  if (showLoading) {
    uni.showLoading({ title: '加载中...', mask: true });
  }

  // 重试机制
  let lastError: any;
  for (let attempt = 0; attempt <= retry; attempt++) {
    try {
      const result = await makeRequest<T>(url, method, data, header, timeout);
      
      // 缓存成功结果
      if (cache && method === 'GET') {
        const cacheKey = url + JSON.stringify(data);
        requestCache.set(cacheKey, { data: result, timestamp: Date.now() });
      }
      
      if (showLoading) {
        uni.hideLoading();
      }
      
      return result;
    } catch (error) {
      lastError = error;
      if (attempt < retry) {
        console.log(`[Request] 请求失败，${retryDelay}ms 后重试 (${attempt + 1}/${retry})`);
        await new Promise(resolve => setTimeout(resolve, retryDelay));
      }
    }
  }

  if (showLoading) {
    uni.hideLoading();
  }
  
  throw lastError;
}

// 发起实际请求
function makeRequest<T>(
  url: string,
  method: 'GET' | 'POST' | 'PUT' | 'DELETE',
  data: any,
  header: any,
  timeout: number
): Promise<T> {
  const startTime = Date.now();
  const fullUrl = BASE_URL + url;

  // 输出 API 请求日志
  debugApiRequest(method, fullUrl, data);

  return new Promise((resolve, reject) => {
    const requestTask = uni.request({
      url: fullUrl,
      method,
      data,
      header,
      timeout,
      success: (res) => {
        const duration = Date.now() - startTime;
        const result = res.data as { code: number; message: string; data?: T };

        // 输出 API 响应日志
        debugApiResponse(method, fullUrl, result, duration);

        // 兼容两种响应格式：{ code: 0, data: ... } 和 { success: true, data: ... }
        const isSuccess = result.code === 0 || result.success === true;
        const responseData = result.data ?? (result as any);

        if (isSuccess) {
          resolve(responseData as T);
        } else if (result.code === 401 || result.success === false && ((result as any).error?.includes('登录') || (result as any).message?.includes('用户不存在'))) {
          // token 过期或用户不存在，跳转登录
          uni.removeStorageSync('token');
          uni.removeStorageSync('userInfo');
          // 如果不是登录页，则跳转
          const pages = getCurrentPages();
          const currentPage = pages[pages.length - 1] as any;
          if (currentPage && !currentPage.route.includes('login')) {
            uni.reLaunch({ url: '/pages/login/index' });
          }
          reject(new Error('请先登录'));
        } else if (result.code === 429) {
          // 请求过于频繁
          const retryAfter = (result as any).retryAfter || 1;
          reject(new Error(`请求过于频繁，请${retryAfter}秒后再试`));
        } else if (result.code >= 500) {
          // 服务器错误
          uni.showToast({ title: result.message || '服务器错误', icon: 'none' });
          reject(new Error(result.message));
        } else {
          // 处理 { success: false, error: "..." } 格式
          const errorMsg = result.message || (result as any).error || '请求失败';
          uni.showToast({ title: errorMsg, icon: 'none' });
          reject(new Error(errorMsg));
        }
      },
      fail: (err) => {
        const duration = Date.now() - startTime;
        debugApiError(method, fullUrl, err, duration);
        reject(new Error('网络请求失败'));
      },
    });
  });
}

// 清除缓存
export function clearRequestCache(pattern?: string) {
  if (pattern) {
    for (const key of requestCache.keys()) {
      if (key.includes(pattern)) {
        requestCache.delete(key);
      }
    }
  } else {
    requestCache.clear();
  }
}

// 文件上传
export function uploadFile<T = any>(
  url: string,
  filePath: string,
  formData?: Record<string, string>
): Promise<T> {
  const token = uni.getStorageSync('token');
  const header: Record<string, string> = {};
  if (token) {
    header['Authorization'] = `Bearer ${token}`;
  }

  const fullUrl = BASE_URL + url;

  return new Promise((resolve, reject) => {
    uni.uploadFile({
      url: fullUrl,
      filePath,
      name: 'file',
      header,
      formData,
      success: (res) => {
        try {
          const result = JSON.parse(res.data) as { code: number; message: string; data?: T };
          debugApiResponse('UPLOAD', fullUrl, result, 0);

          if (result.code === 0 || (result as any).success === true) {
            resolve((result.data ?? result) as T);
          } else if (result.code === 401) {
            uni.removeStorageSync('token');
            const pages = getCurrentPages();
            const currentPage = pages[pages.length - 1] as any;
            if (currentPage && !currentPage.route.includes('login')) {
              uni.reLaunch({ url: '/pages/login/index' });
            }
            reject(new Error('请先登录'));
          } else {
            const errorMsg = result.message || (result as any).error || '上传失败';
            uni.showToast({ title: errorMsg, icon: 'none' });
            reject(new Error(errorMsg));
          }
        } catch (parseError) {
          reject(new Error('服务器响应异常'));
        }
      },
      fail: (err) => {
        console.error('[Upload] 上传失败:', err);
        reject(new Error('文件上传失败'));
      },
    });
  });
}

// GET 请求
export function get<T = unknown>(url: string, params?: Record<string, unknown>): Promise<T> {
  const queryString = params
    ? '?' + Object.entries(params)
        .filter(([, v]) => v !== undefined)
        .map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`)
        .join('&')
    : '';
  return request<T>(url + queryString);
}

// POST 请求
export function post<T = unknown>(url: string, data?: Record<string, unknown>): Promise<T> {
  return request<T>(url, { method: 'POST', data });
}

// PUT 请求
export function put<T = unknown>(url: string, data?: Record<string, unknown>): Promise<T> {
  return request<T>(url, { method: 'PUT', data });
}

// DELETE 请求
export function del<T = unknown>(url: string, data?: Record<string, unknown>): Promise<T> {
  return request<T>(url, { method: 'DELETE', data });
}