/**
 * API 数据源实现
 * 封装所有 API 调用，统一错误处理和请求拦截
 */

import { api, ApiResponse, ApiError } from '../../services/api';
import { IApiDataSource, DataSourceError } from './interfaces';

export class ApiDataSource implements IApiDataSource {
  private baseUrl: string;

  constructor(baseUrl?: string) {
    this.baseUrl = baseUrl || '';
  }

  private buildUrl(url: string): string {
    if (url.startsWith('http')) {
      return url;
    }
    return `${this.baseUrl}${url}`;
  }

  private handleError(error: unknown, operation: string): never {
    if (error instanceof ApiError) {
      throw new DataSourceError(
        error.message,
        String(error.code),
        'ApiDataSource',
        error
      );
    }
    
    const message = error instanceof Error ? error.message : 'Unknown error';
    throw new DataSourceError(
      `API ${operation} failed: ${message}`,
      'API_ERROR',
      'ApiDataSource',
      error instanceof Error ? error : undefined
    );
  }

  async get<T>(url: string, params?: any): Promise<T> {
    try {
      const fullUrl = this.buildUrl(url);
      const response = await api.get<T>(fullUrl, params);
      return response.data;
    } catch (error) {
      this.handleError(error, 'GET');
    }
  }

  async post<T>(url: string, data?: any): Promise<T> {
    try {
      const fullUrl = this.buildUrl(url);
      const response = await api.post<T>(fullUrl, data);
      return response.data;
    } catch (error) {
      this.handleError(error, 'POST');
    }
  }

  async put<T>(url: string, data?: any): Promise<T> {
    try {
      const fullUrl = this.buildUrl(url);
      const response = await api.put<T>(fullUrl, data);
      return response.data;
    } catch (error) {
      this.handleError(error, 'PUT');
    }
  }

  async delete<T>(url: string, data?: any): Promise<T> {
    try {
      const fullUrl = this.buildUrl(url);
      const response = await api.delete<T>(fullUrl, data);
      return response.data;
    } catch (error) {
      this.handleError(error, 'DELETE');
    }
  }

  async upload<T>(
    url: string,
    file: { uri: string; name: string; type: string },
    additionalData?: Record<string, string>
  ): Promise<T> {
    try {
      const fullUrl = this.buildUrl(url);
      const response = await api.upload<T>(fullUrl, file, additionalData);
      return response.data;
    } catch (error) {
      this.handleError(error, 'UPLOAD');
    }
  }
}

// 导出单例实例
export const apiDataSource = new ApiDataSource();
