/**
 * RapidOCR Provider
 * 特点：速度快、准确率高、免费、本地运行
 * 基于 PaddleOCR，中文识别效果优秀
 *
 * 部署方式：
 * 1. 安装 Python 服务: pip install rapidocr-onnxruntime
 * 2. 启动服务 (参考 rapidocr_server 项目)
 * 3. 或使用 Docker: docker run -p 8080:8080 cshgg/rapidocr
 *
 * GitHub: https://github.com/RapidAI/RapidOCR
 */

import { BaseOCRProvider, IImageSource, OCRRecognitionResult, OCRProviderConfig } from './base.provider';
import fs from 'fs';

interface RapidOCRResponse {
  code: number;
  msg: string;
  data: Array<{
    text: string;
    score: number;
    box: number[][];
  }>;
}

export class RapidOCRProvider extends BaseOCRProvider {
  private apiUrl: string;

  constructor(config: OCRProviderConfig & { apiUrl?: string } = {}) {
    super(config);
    this.apiUrl = config.apiUrl || process.env.RAPIDOCR_API_URL || 'http://localhost:13058';
  }

  getName(): string {
    return 'RapidOCR';
  }

  getType(): 'local' | 'cloud' {
    return 'local';
  }

  /**
   * 检查 RapidOCR 服务是否可用
   */
  async isAvailable(): Promise<boolean> {
    try {
      const response = await fetch(`${this.apiUrl}/`, {
        signal: AbortSignal.timeout(2000),
      });
      // RapidOCR 返回 {"message":"Welcome to RapidOCR Server!"}
      return response.ok;
    } catch {
      return false;
    }
  }

  /**
   * 执行 OCR 识别
   */
  async recognize(
    source: IImageSource,
    options?: OCRProviderConfig
  ): Promise<OCRRecognitionResult> {
    const startTime = Date.now();

    // 获取图片 Buffer
    const imageBuffer = await this.getImageBuffer(source);

    // 使用 FormData 发送图片
    const formData = new FormData();
    formData.append('file', new Blob([imageBuffer]), 'image.png');

    // 调用 RapidOCR API
    const response = await this.withTimeout(
      fetch(`${this.apiUrl}/ocr`, {
        method: 'POST',
        body: formData,
      }),
      options?.timeout || this.config.timeout || 15000
    );

    const data = (await response.json()) as RapidOCRResponse;
    const duration = Date.now() - startTime;

    // 检查错误
    if (data.code !== 200) {
      throw new Error(`RapidOCR 错误: ${data.msg} (${data.code})`);
    }

    // 提取文本和置信度
    const ocrResults = Array.isArray(data.data) ? data.data : [];
    const text = ocrResults.map((r) => r.text).join('\n');

    // 计算平均置信度
    const confidence = ocrResults.length > 0
      ? ocrResults.reduce((acc, r) => acc + (r.score || 0), 0) / ocrResults.length
      : 0;

    return {
      text: text.trim(),
      confidence,
      duration,
      extra: {
        provider: 'rapidocr',
        textCount: ocrResults.length,
      },
    };
  }

  getRecommendations() {
    return {
      maxImageSize: 10 * 1024 * 1024,
      supportedFormats: ['jpg', 'jpeg', 'png', 'webp', 'bmp'],
      notes: 'RapidOCR 是基于 PaddleOCR 的本地服务，速度快且准确率高。需要先启动 RapidOCR 服务。',
    };
  }

  /**
   * 获取图片 Buffer
   */
  private async getImageBuffer(source: IImageSource): Promise<Buffer> {
    if (source.buffer) {
      return source.buffer;
    }

    if (source.path) {
      // 使用基类的路径解析方法
      const fullPath = this.resolveImagePath(source.path);
      return fs.readFileSync(fullPath);
    }

    if (source.base64) {
      // 移除 data URL 前缀并转换为 Buffer
      const base64 = source.base64.replace(/^data:image\/\w+;base64,/, '');
      return Buffer.from(base64, 'base64');
    }

    throw new Error('无效的图片来源');
  }

  /**
   * 超时包装
   */
  private async withTimeout<T>(promise: Promise<T>, timeout: number): Promise<T> {
    return Promise.race([
      promise,
      new Promise<never>((_, reject) =>
        setTimeout(() => reject(new Error('timeout')), timeout)
      ),
    ]);
  }
}

// 导出单例实例
export const rapidocrProvider = new RapidOCRProvider();
