// src/media/MediaCapture.ts

import { captureRef } from 'react-native-view-shot';
import * as FileSystem from 'expo-file-system';
import { EventEmitter } from 'events';
import { ViewProps } from 'react-native';

export interface MediaCaptureOptions {
  quality?: number; // 0 to 1
  format?: 'jpg' | 'png';
  result?: 'tmpfile' | 'base64' | 'data-uri';
}

export interface RecordingOptions {
  quality?: number; // 0 to 1
  maxDuration?: number; // in seconds
  maxFileSize?: number; // in bytes
}

export class MediaCapture extends EventEmitter {
  private isRecording: boolean = false;
  private recordingStartTime: number = 0;
  private mediaDirectory: string;

  constructor() {
    super();
    this.mediaDirectory = `${FileSystem.documentDirectory}ar_media/`;
    this.ensureMediaDirectory();
  }

  private async ensureMediaDirectory(): Promise<void> {
    const dirInfo = await FileSystem.getInfoAsync(this.mediaDirectory);
    if (!dirInfo.exists) {
      await FileSystem.makeDirectoryAsync(this.mediaDirectory, { intermediates: true });
    }
  }

  /**
   * Captures a screenshot of the AR view
   * @param viewRef React ref to the view to capture
   * @param options Capture options
   * @returns Promise with the path to the saved image
   */
  public async captureScreenshot(
    viewRef: React.RefObject<ViewProps>,
    options: MediaCaptureOptions = {}
  ): Promise<string> {
    try {
      const timestamp = Date.now();
      const fileName = `ar_screenshot_${timestamp}.${options.format || 'jpg'}`;
      const filePath = `${this.mediaDirectory}${fileName}`;

      const uri = await captureRef(viewRef, {
        quality: options.quality || 0.8,
        format: options.format || 'jpg',
        result: 'tmpfile'
      });

      await FileSystem.moveAsync({
        from: uri,
        to: filePath
      });

      this.emit('screenshot-captured', filePath);
      return filePath;
    } catch (error) {
      this.emit('error', error);
      throw error;
    }
  }

  /**
   * Starts recording the AR session
   * @param viewRef React ref to the view to record
   * @param options Recording options
   */
  public startRecording(
    viewRef: React.RefObject<ViewProps>,
    options: RecordingOptions = {}
  ): void {
    if (this.isRecording) {
      throw new Error('Recording is already in progress');
    }

    this.isRecording = true;
    this.recordingStartTime = Date.now();
    this.emit('recording-started');

    // TODO: Implement actual video recording using react-native-view-shot
    // This will require frame-by-frame capture and composition
  }

  /**
   * Stops the current recording
   * @returns Promise with the path to the saved video
   */
  public async stopRecording(): Promise<string> {
    if (!this.isRecording) {
      throw new Error('No recording in progress');
    }

    const timestamp = this.recordingStartTime;
    const fileName = `ar_recording_${timestamp}.mp4`;
    const filePath = `${this.mediaDirectory}${fileName}`;

    this.isRecording = false;
    this.recordingStartTime = 0;

    // TODO: Implement actual video recording stop and save logic

    this.emit('recording-stopped', filePath);
    return filePath;
  }

  /**
   * Cleans up old media files
   * @param maxAge Maximum age of files to keep (in milliseconds)
   */
  public async cleanupOldFiles(maxAge: number): Promise<void> {
    try {
      const files = await FileSystem.readDirectoryAsync(this.mediaDirectory);
      const now = Date.now();

      for (const file of files) {
        const filePath = `${this.mediaDirectory}${file}`;
        const fileInfo = await FileSystem.getInfoAsync(filePath);
        
        const modTime = (fileInfo as any).modificationTime;
        if (modTime && (now - modTime > maxAge)) {
          await FileSystem.deleteAsync(filePath);
        }
      }
    } catch (error) {
      this.emit('error', error);
      throw error;
    }
  }
}