/**
 * OpenAISttService
 *
 * Calls the OpenAI Whisper transcriptions API to convert audio buffers to text.
 * Supports the self-signed proxy at 67.223.119.33:8443 by disabling TLS verification
 * when OPENAI_BASE_URL points to an https host (same pattern as voice-agent).
 */
import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import * as https from 'https';

@Injectable()
export class OpenAISttService {
  private readonly logger = new Logger(OpenAISttService.name);
  private readonly apiKey: string;
  private readonly baseUrl: string;

  constructor(private readonly configService: ConfigService) {
    this.apiKey = this.configService.get<string>('OPENAI_API_KEY', '');
    this.baseUrl = this.configService.get<string>(
      'OPENAI_BASE_URL',
      'https://api.openai.com',
    ).replace(/\/$/, '');
  }

  /**
   * Transcribe an audio buffer to text using OpenAI Whisper.
   *
   * @param audioBuffer  Raw audio bytes (any format Whisper accepts: m4a, webm, mp3, wav, etc.)
   * @param filename     Original filename including extension — Whisper uses this to detect format
   * @param language     BCP-47 language code hint (default: 'zh')
   */
  async transcribe(
    audioBuffer: Buffer,
    filename: string,
    language = 'zh',
  ): Promise<string> {
    const url = `${this.baseUrl}/v1/audio/transcriptions`;
    this.logger.log(`STT: transcribing ${filename} (${audioBuffer.length} bytes) → ${url}`);

    // Build multipart/form-data manually to avoid external dependencies
    const boundary = `----FormBoundary${Date.now().toString(16)}`;
    const parts: Buffer[] = [];

    const appendField = (name: string, value: string) => {
      parts.push(
        Buffer.from(
          `--${boundary}\r\nContent-Disposition: form-data; name="${name}"\r\n\r\n${value}\r\n`,
        ),
      );
    };

    appendField('model', 'whisper-1');
    appendField('language', language);
    appendField('response_format', 'json');

    // File field
    parts.push(
      Buffer.from(
        `--${boundary}\r\nContent-Disposition: form-data; name="file"; filename="${filename}"\r\nContent-Type: application/octet-stream\r\n\r\n`,
      ),
    );
    parts.push(audioBuffer);
    parts.push(Buffer.from(`\r\n--${boundary}--\r\n`));

    const body = Buffer.concat(parts);

    // Use a custom https agent to allow self-signed certs (proxy at 67.223.119.33:8443)
    const agent = new https.Agent({ rejectUnauthorized: false });

    const response = await fetch(url, {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${this.apiKey}`,
        'Content-Type': `multipart/form-data; boundary=${boundary}`,
        'Content-Length': String(body.length),
      },
      body,
      // @ts-ignore — undici (Node 18+ native fetch) accepts dispatcher via agent option
      agent,
    });

    if (!response.ok) {
      const errText = await response.text().catch(() => '');
      throw new Error(`Whisper STT failed: HTTP ${response.status} — ${errText}`);
    }

    const result = (await response.json()) as { text: string };
    this.logger.log(`STT result: "${result.text?.slice(0, 80)}"`);
    return result.text ?? '';
  }
}
