/**
 * Provider Adapter — 基类
 *
 * 所有 Provider 适配器共享的基类逻辑：
 * - 请求超时处理
 * - 错误映射到 MetonaError
 * - 流式事件标准化
 */

import type {
  IMetonaProviderAdapter,
  AdapterConfig,
  MetonaRequest,
  MetonaResponse,
  MetonaStreamEvent,
  MetonaError,
} from '../types';
import { MetonaErrorCode } from '../types';

export abstract class BaseAdapter implements IMetonaProviderAdapter {
  abstract readonly provider: string;
  abstract readonly supportedModels: string[];
  abstract readonly supportsToolCalling: boolean;
  abstract readonly supportsThinking: boolean;

  constructor(protected config: AdapterConfig) {}

  abstract chat(request: MetonaRequest): Promise<MetonaResponse>;
  abstract chatStream(request: MetonaRequest): AsyncIterable<MetonaStreamEvent>;

  async healthCheck(): Promise<boolean> {
    try {
      await this.listModels?.();
      return true;
    } catch {
      return false;
    }
  }

  async listModels(): Promise<string[]> {
    return this.supportedModels;
  }

  /**
   * 将原生错误映射为 MetonaError
   */
  protected mapError(error: unknown): MetonaError {
    if (error instanceof Error) {
      const msg = error.message.toLowerCase();

      if (msg.includes('timeout') || msg.includes('ETIMEDOUT')) {
        return {
          code: MetonaErrorCode.NETWORK_TIMEOUT,
          message: error.message,
          provider: this.provider,
          retryable: true,
          retryAfterMs: 3000,
        };
      }

      if (msg.includes('401') || msg.includes('unauthorized')) {
        return {
          code: MetonaErrorCode.AUTH_INVALID,
          message: 'API key 无效或已过期',
          provider: this.provider,
          retryable: false,
        };
      }

      if (msg.includes('429') || msg.includes('rate limit')) {
        return {
          code: MetonaErrorCode.RATE_LIMITED,
          message: '请求过于频繁，请稍后重试',
          provider: this.provider,
          retryable: true,
          retryAfterMs: 5000,
        };
      }
    }

    return {
      code: MetonaErrorCode.UNKNOWN,
      message: error instanceof Error ? error.message : 'Unknown error',
      provider: this.provider,
      retryable: false,
    };
  }
}
