import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import * as fs from 'fs';
import { I18nService } from '../i18n/i18n.service';

@Injectable()
export class TikaService {
  private readonly logger = new Logger(TikaService.name);
  private readonly tikaHost: string;

  constructor(
    private configService: ConfigService,
    private i18nService: I18nService,
  ) {
    const tikaHost = this.configService.get<string>('TIKA_HOST');
    if (!tikaHost) {
      throw new Error(this.i18nService.getMessage('tikaHostRequired'));
    }
    this.tikaHost = tikaHost;
  }

  async extractText(filePath: string): Promise<string> {
    try {
      // Use stream instead of reading entire file into memory
      const fileStream = fs.createReadStream(filePath);

      // Node.js native fetch supports passing a stream as body, but often requires 'duplex: "half"'
      // and checking if we need to convert to Web Stream (Readable.toWeb) depends on Node version,
      // but usually standard stream works or fs.openAsBlob (Node 20).
      // Let's try passing the stream directly with duplex option.

      const response = await fetch(`${this.tikaHost}/tika`, {
        method: 'PUT',
        headers: {
          Accept: 'text/plain',
        },
        // @ts-expect-error - duplex is present in Node's RequestInit but strictly typed definitions might miss it
        duplex: 'half',
        body: fileStream as any,
      });

      if (!response.ok) {
        const statusText = response.statusText;
        // Ensure stream is closed if request failed
        fileStream.destroy();
        throw new Error(`Tika extraction failed: ${response.status} ${statusText}`);
      }

      return await response.text();
    } catch (error) {
      this.logger.error(`Failed to extract text from ${filePath}`, error);
      throw error;
    }
  }
}
