import { Injectable, Logger, OnModuleDestroy } from '@nestjs/common';
import { EventEmitter } from 'events';
import {
  createClient,
  LiveTranscriptionEvents,
  LiveClient,
  DeepgramClient,
} from '@deepgram/sdk';
import { Buffer } from 'buffer';
import { config } from 'dotenv';

config();

export class TranscriptionService extends EventEmitter {
  private readonly logger = new Logger(TranscriptionService.name);
  private deepgramClient: DeepgramClient;
  private dgConnection: any;
  private finalResult = '';
  private speechFinal = false;

  constructor() {
    super();
    this.initializeDeepgramConnection();
  }

  private async initializeDeepgramConnection() {
    this.deepgramClient = createClient(process.env.DEEPGRAM_API_KEY);
    // this.deepgramClient = createClient(process.env.DEEPGRAM_API_KEY, {
    //   global: { url: process.env.SERVER },
    // });

    this.dgConnection = this.deepgramClient.listen.live({
      encoding: 'mulaw',
      sample_rate: 8000,
      model: 'nova-2',
      punctuate: true,
      interim_results: true,
      endpointing: 200,
      utterance_end_ms: 1000,
    });

    this.dgConnection.on(LiveTranscriptionEvents.Open, () => {
      this.logger.log('Deepgram connection opened');
      this.dgConnection.on(
        LiveTranscriptionEvents.Transcript,
        (transcriptionEvent: any) => {
          // console.log('transcriptionEvent',transcriptionEvent);

          const alternatives = transcriptionEvent.channel?.alternatives;
          let text = '';
          if (alternatives) {
            text = alternatives[0]?.transcript;
          }

          if (transcriptionEvent.type === 'UtteranceEnd') {
            if (!this.speechFinal) {
              this.logger.log(
                `UtteranceEnd received before speechFinal. Emitting collected text: ${this.finalResult}`
              );
              this.emit('transcription', this.finalResult);
              return;
            } else {
              this.logger.log(
                'Speech was already final when UtteranceEnd received'
              );
              return;
            }
          }

          if (transcriptionEvent.is_final === true && text.trim().length > 0) {
            this.finalResult += ` ${text}`;
            if (transcriptionEvent.speech_final === true) {
              this.speechFinal = true;
              this.emit('transcription', this.finalResult);
              this.finalResult = '';
            } else {
              this.speechFinal = false;
            }
          } else {
            console.log('utterance-', text);

            this.emit('utterance', text);
          }
        }
      );

      // this.handleTranscriptionEvents();
    });

    this.dgConnection.on(LiveTranscriptionEvents.Error, (error: any) => {
      this.logger.error('Deepgram error', error);
      console.log('Deepgram error', error);
    });

    this.dgConnection.on(LiveTranscriptionEvents.Close, () => {
      this.logger.warn('Deepgram connection closed');
    });

    this.dgConnection.on(LiveTranscriptionEvents.Metadata, (metadata: any) => {
      this.logger.debug('Deepgram metadata', metadata);
    });
  }

  /**
   * Send the payload to Deepgram
   * @param payload A base64 MULAW/8000 audio stream
   */
  async send(payload: string) {
    // await this.initializeDeepgramConnection();
    // console.log("this.dgConnection && this.dgConnection.getReadyState() === 1",this.dgConnection && this.dgConnection.getReadyState() === 1);
    // console.log("payload", payload);

    if (this.dgConnection && this.dgConnection.getReadyState() === 1) {
      // console.log("inside_send");

      this.dgConnection.send(Buffer.from(payload, 'base64'));
    } else {
      // this.logger.error('Connection to Deepgram is not open');
    }
  }

  // onModuleDestroy() {
  //   this.dgConnection.requestClose();
  //   this.logger.log('Deepgram connection closed on module destroy');
  // }
}
