/**
 * 统一API客户端
 * 基于fetch方法的API调用工具，确保所有数据都从数据库动态获取
 */

import { createSuccessResponse, createErrorResponse, extractData } from './apiResponseFormat.js';

/**
 * API客户端配置
 */
const API_CONFIG = {
  baseURL: import.meta.env.VITE_API_BASE_URL || '/api',
  timeout: 30000,
  retryCount: 3,
  retryDelay: 1000
};

/**
 * 创建请求头
 * @param {Object} customHeaders - 自定义请求头
 * @returns {Object} 请求头对象
 */
const createHeaders = (customHeaders = {}) => {
  const token = localStorage.getItem('token');
  const defaultHeaders = {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  };
  
  if (token) {
    defaultHeaders['Authorization'] = `Bearer ${token}`;
  }
  
  return { ...defaultHeaders, ...customHeaders };
};

/**
 * 处理API响应
 * @param {Response} response - Fetch响应对象
 * @returns {Promise} 处理后的响应数据
 */
const handleResponse = async (response) => {
  // 检查HTTP状态
  if (!response.ok) {
    let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
    
    try {
      const errorData = await response.json();
      errorMessage = errorData.message || errorMessage;
    } catch (e) {
      // 如果无法解析错误响应，使用默认错误消息
    }
    
    // 处理认证错误
    if (response.status === 401) {
      localStorage.removeItem('token');
      localStorage.removeItem('user');
      window.location.href = '/login';
      throw new Error('认证已过期，请重新登录');
    }
    
    throw new Error(errorMessage);
  }
  
  // 检查响应类型
  const contentType = response.headers.get('content-type');
  
  // 如果是文件下载，返回blob
  if (contentType && (
    contentType.includes('application/octet-stream') ||
    contentType.includes('application/vnd.ms-excel') ||
    contentType.includes('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') ||
    contentType.includes('text/csv')
  )) {
    return await response.blob();
  }
  
  // 返回JSON数据
  const result = await response.json();
  
  // 兼容数组响应
  if (Array.isArray(result)) {
    return result;
  }
  
  return result;
};

/**
 * 重试机制
 * @param {Function} requestFn - 请求函数
 * @param {number} retryCount - 重试次数
 * @param {number} delay - 重试延迟
 * @returns {Promise} 请求结果
 */
const retryRequest = async (requestFn, retryCount = API_CONFIG.retryCount, delay = API_CONFIG.retryDelay) => {
  try {
    return await requestFn();
  } catch (error) {
    if (retryCount > 0 && !error.message.includes('认证')) {
      console.warn(`请求失败，${delay}ms后重试，剩余重试次数: ${retryCount - 1}`, error.message);
      await new Promise(resolve => setTimeout(resolve, delay));
      return retryRequest(requestFn, retryCount - 1, delay * 2);
    }
    throw error;
  }
};

/**
 * 创建完整URL
 * @param {string} endpoint - API端点
 * @returns {string} 完整URL
 */
const createURL = (endpoint) => {
  const baseURL = API_CONFIG.baseURL.replace(/\/$/, '');
  const cleanEndpoint = endpoint.startsWith('/') ? endpoint : `/${endpoint}`;
  return `${baseURL}${cleanEndpoint}`;
};

/**
 * 构建查询参数
 * @param {Object} params - 查询参数对象
 * @returns {string} 查询字符串
 */
const buildQueryString = (params) => {
  const searchParams = new URLSearchParams();
  
  Object.keys(params).forEach(key => {
    const value = params[key];
    if (value !== null && value !== undefined && value !== '') {
      if (Array.isArray(value)) {
        value.forEach(item => {
          if (item !== null && item !== undefined && item !== '') {
            searchParams.append(key, item);
          }
        });
      } else if (typeof value === 'object' && value !== null) {
        // 处理对象类型的参数（如日期范围）
        if (value.start && value.end) {
          searchParams.append(`${key}Start`, value.start);
          searchParams.append(`${key}End`, value.end);
        }
      } else {
        searchParams.append(key, value);
      }
    }
  });
  
  // 添加时间戳防止缓存
  searchParams.append('_t', Date.now().toString());
  
  return searchParams.toString();
};

/**
 * 基础请求方法
 * @param {string} method - HTTP方法
 * @param {string} endpoint - API端点
 * @param {Object} options - 请求选项
 * @returns {Promise} 请求结果
 */
const request = async (method, endpoint, options = {}) => {
  const { data, params, headers = {}, responseType = 'json' } = options;
  
  // 构建URL
  let url = createURL(endpoint);
  if (params && Object.keys(params).length > 0) {
    const queryString = buildQueryString(params);
    url += `?${queryString}`;
  }
  
  // 构建请求配置
  const requestConfig = {
    method: method.toUpperCase(),
    headers: createHeaders(headers),
    ...options
  };
  
  // 添加请求体
  if (data && method.toUpperCase() !== 'GET') {
    if (data instanceof FormData) {
      // 文件上传
      requestConfig.body = data;
      delete requestConfig.headers['Content-Type']; // 让浏览器自动设置
    } else {
      requestConfig.body = JSON.stringify(data);
    }
  }
  
  // 执行请求
  const requestFn = async () => {
    const response = await fetch(url, requestConfig);
    return await handleResponse(response);
  };
  
  // 使用重试机制
  return await retryRequest(requestFn);
};

/**
 * API客户端类
 */
export class ApiClient {
  /**
   * GET请求
   * @param {string} endpoint - API端点
   * @param {Object} options - 请求选项
   * @returns {Promise} 响应数据
   */
  static async get(endpoint, options = {}) {
    return await request('GET', endpoint, options);
  }
  
  /**
   * POST请求
   * @param {string} endpoint - API端点
   * @param {Object} data - 请求数据
   * @param {Object} options - 请求选项
   * @returns {Promise} 响应数据
   */
  static async post(endpoint, data = null, options = {}) {
    return await request('POST', endpoint, { ...options, data });
  }
  
  /**
   * PUT请求
   * @param {string} endpoint - API端点
   * @param {Object} data - 请求数据
   * @param {Object} options - 请求选项
   * @returns {Promise} 响应数据
   */
  static async put(endpoint, data = null, options = {}) {
    return await request('PUT', endpoint, { ...options, data });
  }
  
  /**
   * DELETE请求
   * @param {string} endpoint - API端点
   * @param {Object} options - 请求选项
   * @returns {Promise} 响应数据
   */
  static async delete(endpoint, options = {}) {
    return await request('DELETE', endpoint, options);
  }
  
  /**
   * PATCH请求
   * @param {string} endpoint - API端点
   * @param {Object} data - 请求数据
   * @param {Object} options - 请求选项
   * @returns {Promise} 响应数据
   */
  static async patch(endpoint, data = null, options = {}) {
    return await request('PATCH', endpoint, { ...options, data });
  }
  
  /**
   * 文件上传
   * @param {string} endpoint - API端点
   * @param {FormData} formData - 表单数据
   * @param {Object} options - 请求选项
   * @returns {Promise} 响应数据
   */
  static async upload(endpoint, formData, options = {}) {
    return await request('POST', endpoint, {
      ...options,
      data: formData,
      headers: {} // 让浏览器自动设置Content-Type
    });
  }
  
  /**
   * 文件下载
   * @param {string} endpoint - API端点
   * @param {Object} params - 查询参数
   * @param {string} filename - 文件名
   * @returns {Promise} 下载结果
   */
  static async download(endpoint, params = {}, filename = 'download') {
    const response = await this.get(endpoint, { 
      params, 
      responseType: 'blob' 
    });
    
    // 创建下载链接
    const url = window.URL.createObjectURL(response);
    const link = document.createElement('a');
    link.href = url;
    link.download = filename;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    window.URL.revokeObjectURL(url);
    
    return response;
  }
}

/**
 * 便捷的API调用方法
 */
export const api = {
  // 基础CRUD操作
  get: ApiClient.get,
  post: ApiClient.post,
  put: ApiClient.put,
  delete: ApiClient.delete,
  patch: ApiClient.patch,
  upload: ApiClient.upload,
  download: ApiClient.download,
  
  // 智能设备相关API
  smartDevices: {
    // 智能耳标
    async getEartags(params = {}) {
      return await ApiClient.get('/smart-devices/public/eartags', { params });
    },
    
    async getEartagById(id) {
      return await ApiClient.get(`/smart-devices/public/eartags/${id}`);
    },
    
    async exportEartags(params = {}) {
      return await ApiClient.download('/smart-devices/public/eartags/export', params, '智能耳标数据.xlsx');
    },
    
    // 智能项圈
    async getCollars(params = {}) {
      return await ApiClient.get('/smart-devices/public/collars', { params });
    },
    
    async getCollarById(id) {
      return await ApiClient.get(`/smart-devices/public/collars/${id}`);
    },
    
    // 智能脚环
    async getAnklets(params = {}) {
      return await ApiClient.get('/smart-devices/public/anklets', { params });
    },
    
    async getAnkletById(id) {
      return await ApiClient.get(`/smart-devices/public/anklets/${id}`);
    },
    
    // 智能主机
    async getHosts(params = {}) {
      return await ApiClient.get('/smart-devices/public/hosts', { params });
    },
    
    async getHostById(id) {
      return await ApiClient.get(`/smart-devices/public/hosts/${id}`);
    }
  },
  
  // 预警相关API
  smartAlerts: {
    async getEartagAlerts(params = {}) {
      return await ApiClient.get('/smart-alerts/public/eartag', { params });
    },
    
    async getCollarAlerts(params = {}) {
      return await ApiClient.get('/smart-alerts/public/collar', { params });
    },
    
    async getAnkletAlerts(params = {}) {
      return await ApiClient.get('/smart-alerts/public/anklet', { params });
    },
    
    async getAlertStats() {
      return await ApiClient.get('/smart-alerts/public/stats');
    }
  },
  
  // 养殖场相关API
  farms: {
    async getFarms(params = {}) {
      return await ApiClient.get('/farms/public', { params });
    },
    
    async getFarmById(id) {
      return await ApiClient.get(`/farms/public/${id}`);
    },
    
    async createFarm(data) {
      return await ApiClient.post('/farms', data);
    },
    
    async updateFarm(id, data) {
      return await ApiClient.put(`/farms/${id}`, data);
    },
    
    async deleteFarm(id) {
      return await ApiClient.delete(`/farms/${id}`);
    }
  },
  
  // 统计数据相关API
  stats: {
    async getDashboardStats() {
      return await ApiClient.get('/stats/public/dashboard');
    },
    
    async getFarmStats() {
      return await ApiClient.get('/stats/public/farms');
    },
    
    async getDeviceStats() {
      return await ApiClient.get('/stats/public/devices');
    },
    
    async getAlertStats() {
      return await ApiClient.get('/stats/public/alerts');
    }
  }
};

export default api;
