import { useState, useRef, useCallback } from 'react';

// Extended type for newer getDisplayMedia options
interface DisplayMediaStreamOptions extends MediaStreamConstraints {
  preferCurrentTab?: boolean;
  selfBrowserSurface?: 'include' | 'exclude';
  surfaceSwitching?: 'include' | 'exclude';
  systemAudio?: 'include' | 'exclude';
}

export type ScreenRecordingState = 'idle' | 'recording' | 'recorded';

export interface UseScreenRecorderReturn {
  recordingState: ScreenRecordingState;
  recordedVideoUrl: string | null;
  startRecording: (targetElement?: HTMLIFrameElement) => Promise<void>;
  stopRecording: () => void;
  clearRecording: () => void;
  error: string | null;
}

export function useScreenRecorder(): UseScreenRecorderReturn {
  const [recordingState, setRecordingState] = useState<ScreenRecordingState>('idle');
  const [recordedVideoUrl, setRecordedVideoUrl] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);

  const mediaRecorderRef = useRef<MediaRecorder | null>(null);
  const chunksRef = useRef<Blob[]>([]);
  const streamRef = useRef<MediaStream | null>(null);

  const startRecording = useCallback(async (targetElement?: HTMLIFrameElement) => {
    try {
      setError(null);

      if (!targetElement) {
        setError('No iframe element provided');
        return;
      }

      console.log('📐 Starting capture for iframe');

      // Request screen capture with audio
      const displayStream = await navigator.mediaDevices.getDisplayMedia({
        video: {
          displaySurface: 'browser',
          width: { ideal: 1920 },
          height: { ideal: 1080 },
        } as MediaTrackConstraints,
        audio: {
          echoCancellation: false,
          noiseSuppression: false,
          autoGainControl: false,
        },
        preferCurrentTab: true,
        selfBrowserSurface: 'include',
        systemAudio: 'include',
      } as DisplayMediaStreamOptions);

      console.log('📹 Display stream tracks:', {
        video: displayStream.getVideoTracks().map(t => ({ id: t.id, label: t.label, enabled: t.enabled })),
        audio: displayStream.getAudioTracks().map(t => ({ id: t.id, label: t.label, enabled: t.enabled })),
      });

      // Try to use Region Capture API to crop to iframe
      const videoTrack = displayStream.getVideoTracks()[0];

      if ('CropTarget' in window && 'cropTo' in videoTrack) {
        try {
          console.log('🎯 Attempting to use Region Capture API');
          const CropTarget = (window as any).CropTarget;
          const cropTarget = await CropTarget.fromElement(targetElement);
          await (videoTrack as any).cropTo(cropTarget);
          console.log('✅ Successfully cropped to iframe element');
        } catch (err) {
          console.warn('⚠️ Region Capture not available, will record full tab:', err);
        }
      } else {
        console.warn('⚠️ Region Capture API not supported in this browser');
      }

      streamRef.current = displayStream;
      chunksRef.current = [];

      // Determine supported mime type
      let mimeType = 'video/webm;codecs=vp9,opus';
      if (!MediaRecorder.isTypeSupported(mimeType)) {
        mimeType = 'video/webm;codecs=vp8,opus';
        if (!MediaRecorder.isTypeSupported(mimeType)) {
          mimeType = 'video/webm';
        }
      }
      console.log('🎬 Using mimeType:', mimeType);

      // Create MediaRecorder with display stream
      const mediaRecorder = new MediaRecorder(displayStream, {
        mimeType,
        videoBitsPerSecond: 2500000,
        audioBitsPerSecond: 128000,
      });

      mediaRecorderRef.current = mediaRecorder;

      // Collect data chunks
      mediaRecorder.ondataavailable = (event) => {
        console.log('📦 Data chunk received:', event.data.size, 'bytes');
        if (event.data.size > 0) {
          chunksRef.current.push(event.data);
        }
      };

      // Handle recording stop
      mediaRecorder.onstop = () => {
        console.log('⏹ Recording stopped. Total chunks:', chunksRef.current.length);
        const totalSize = chunksRef.current.reduce((sum, chunk) => sum + chunk.size, 0);
        console.log('📊 Total recorded size:', totalSize, 'bytes');

        const blob = new Blob(chunksRef.current, { type: mimeType });
        console.log('🎥 Created blob:', blob.size, 'bytes, type:', blob.type);

        const url = URL.createObjectURL(blob);
        setRecordedVideoUrl(url);
        setRecordingState('recorded');

        // Stop all tracks
        if (streamRef.current) {
          streamRef.current.getTracks().forEach(track => {
            console.log('Stopping track:', track.kind, track.label);
            track.stop();
          });
          streamRef.current = null;
        }
      };

      // Handle errors
      mediaRecorder.onerror = (event) => {
        console.error('MediaRecorder error:', event);
        setError('Recording error occurred');
        setRecordingState('idle');
      };

      // Handle when user stops sharing via browser UI
      displayStream.getTracks().forEach(track => {
        track.addEventListener('ended', () => {
          console.log('📺 User stopped sharing:', track.kind);
          if (mediaRecorderRef.current && mediaRecorderRef.current.state !== 'inactive') {
            mediaRecorderRef.current.stop();
          }
        });
      });

      // Start recording - request data every 1 second
      mediaRecorder.start(1000);
      console.log('▶️ Recording started');
      setRecordingState('recording');
    } catch (err) {
      console.error('Error starting screen recording:', err);
      if (err instanceof Error) {
        if (err.name === 'NotAllowedError') {
          setError('Screen recording permission denied');
        } else if (err.name === 'NotFoundError') {
          setError('No screen to record');
        } else {
          setError(`Failed to start recording: ${err.message}`);
        }
      } else {
        setError('Failed to start recording');
      }
      setRecordingState('idle');
    }
  }, []);

  const stopRecording = useCallback(() => {
    if (mediaRecorderRef.current && mediaRecorderRef.current.state !== 'inactive') {
      mediaRecorderRef.current.stop();
    }
  }, []);

  const clearRecording = useCallback(() => {
    if (recordedVideoUrl) {
      URL.revokeObjectURL(recordedVideoUrl);
    }
    setRecordedVideoUrl(null);
    setRecordingState('idle');
    setError(null);
    chunksRef.current = [];
  }, [recordedVideoUrl]);

  return {
    recordingState,
    recordedVideoUrl,
    startRecording,
    stopRecording,
    clearRecording,
    error,
  };
}
