/**
 * WebRTC Audio Stream Capture
 * Captures audio from screen/audio sharing using WebRTC APIs
 * Implements 5-second chunks with 1-second overlap for sliding window analysis
 */

interface WebRTCStreamConfig {
  chunkDuration: number;  // 5000ms
  overlapDuration: number; // 1000ms
  sampleRate: number;     // 16000 Hz for voiceprint compatibility
}

const DEFAULT_CONFIG: WebRTCStreamConfig = {
  chunkDuration: 5000,
  overlapDuration: 1000,
  sampleRate: 16000
};

export class WebRTCStreamCapture {
  private stream: MediaStream | null = null;
  private audioContext: AudioContext | null = null;
  private analyser: AnalyserNode | null = null;
  private source: MediaStreamAudioSourceNode | null = null;
  private _isRecording: boolean = false;
  
  private buffer: Float32Array = new Float32Array(0);
  public onChunkReady?: (chunk: Float32Array, timestamp: number) => void;
  public onStreamError?: (error: Error) => void;
  
  constructor(private config: WebRTCStreamConfig = DEFAULT_CONFIG) {}

  /**
   * Check if currently recording
   */
  public isRecording: boolean = false;

  /**
   * Start capturing audio from screen/audio sharing
   */
  async start(): Promise<void> {
    if (this.isRecording) {
      console.log('[WebRTC] Already recording');
      return;
    }

    try {
      // Request screen/audio capture with audio
      this.stream = await navigator.mediaDevices.getDisplayMedia({
        video: true,      // Required for audio capture
        audio: true
      });

      // Stop any existing tracks
      this.stream.getTracks().forEach(track => track.stop());

      // Create audio context and analyser
      this.audioContext = new AudioContext({
        sampleRate: this.config.sampleRate
      });
      this.analyser = this.audioContext.createAnalyser();
      this.analyser.fftSize = 2048;

      // Connect stream to audio graph
      this.source = this.audioContext.createMediaStreamSource(this.stream);
      this.source.connect(this.analyser);

      this.isRecording = true;
      console.log('[WebRTC] Stream capture started');

      // Start processing loop
      this.processAudio();

      // Handle stream termination
      this.stream.getVideoTracks()[0].onended = () => {
        console.log('[WebRTC] User stopped sharing');
        this.stop();
      };

    } catch (error) {
      const err = error instanceof Error ? error : new Error(String(error));
      console.error('[WebRTC] Failed to start stream capture:', err);
      this.onStreamError?.(err);
      throw err;
    }
  }

  /**
   * Process audio in real-time with sliding window
   */
  private processAudio(): void {
    if (!this.audioContext || !this.analyser || !this.isRecording) return;

    if (!this.analyser) return;
    
    const bufferLength = this.analyser.fftSize;
    const buffer = new Float32Array(bufferLength);

    const processFrame = () => {
      if (!this.isRecording) return;

      if (!this.analyser) return;
      
      this.analyser.getFloatTimeDomainData(buffer);

      // Get current timestamp
      const timestamp = this.audioContext?.currentTime ?? 0;

      // Extract audio data for current frame
      // Use first 512 samples for voice analysis (reduced for faster processing)
      const audioData = buffer.slice(0, 512);

      // Prepare chunk for analysis
      if (audioData.length > 0) {
        this.onChunkReady?.(audioData, timestamp);
      }

      // Schedule next frame with overlap
      const frameDuration = this.config.chunkDuration - this.config.overlapDuration;
      setTimeout(processFrame, frameDuration);
    };

    processFrame();
  }

  /**
   * Stop audio capture
   */
  stop(): void {
    this._isRecording = false;

    if (this.stream) {
      this.stream.getTracks().forEach(track => track.stop());
      this.stream = null;
    }

    if (this.source) {
      this.source.disconnect();
      this.source = null;
    }

    if (this.analyser) {
      this.analyser.disconnect();
      this.analyser = null;
    }

    if (this.audioContext) {
      this.audioContext.close();
      this.audioContext = null;
    }

    console.log('[WebRTC] Stream capture stopped');
  }

  /**
   * Get stream metadata
   */
  getMetadata(): {
    isActive: boolean;
    sampleRate: number;
    channels: number;
  } {
    if (!this.stream) {
      return { isActive: false, sampleRate: 0, channels: 0 };
    }

    const audioTrack = this.stream.getAudioTracks()[0];
    if (!audioTrack) {
      return { isActive: true, sampleRate: this.config.sampleRate, channels: 1 };
    }

    return {
      isActive: true,
      sampleRate: this.config.sampleRate,
      channels: audioTrack.getSettings().channelCount || 1
    };
  }
}

/**
 * Factory function for creating stream capture with auto-start
 */
export function createWebRTCCapture(config?: WebRTCStreamConfig): WebRTCStreamCapture {
  return new WebRTCStreamCapture(config || DEFAULT_CONFIG);
}
