// src/components/PermissionStatusDisplay.tsx

import React, { useEffect, useState, useRef } from 'react';
import { useCameraPermission } from '../hooks/useCameraPermission';
import { useMicrophonePermission } from '../hooks/useMicrophonePermission';
import { PermissionStatus } from './PermissionStatus';
import { CameraPermissionButton } from './CameraPermissionButton';
import { MicrophonePermissionButton } from './MicrophonePermissionButton';

export const PermissionStatusDisplay: React.FC = () => {
  const { permissionState: cameraPermissionState } = useCameraPermission();
  const { permissionState: microphonePermissionState } = useMicrophonePermission();

  const [videoDevices, setVideoDevices] = useState<MediaDeviceInfo[]>([]);
  const [audioDevices, setAudioDevices] = useState<MediaDeviceInfo[]>([]);
  const [selectedCamera, setSelectedCamera] = useState<string | null>(null);
  const [selectedMicrophone, setSelectedMicrophone] = useState<string | null>(null);
  const [audioLevel, setAudioLevel] = useState<number>(0);

  const videoRef = useRef<HTMLVideoElement>(null);
  const audioContextRef = useRef<AudioContext | null>(null);
  const analyserRef = useRef<AnalyserNode | null>(null);
  const dataArrayRef = useRef<Uint8Array | null>(null);
  const animationIdRef = useRef<number | null>(null);
  const mediaStreamRef = useRef<MediaStream | null>(null);

  // Fetch available devices on mount
  useEffect(() => {
    const fetchDevices = async () => {
      try {
        const devices = await navigator.mediaDevices.enumerateDevices();
        const videoInputDevices = devices.filter(device => device.kind === 'videoinput');
        const audioInputDevices = devices.filter(device => device.kind === 'audioinput');

        setVideoDevices(videoInputDevices);
        setAudioDevices(audioInputDevices);

        // Set default selections
        if (videoInputDevices.length > 0) {
          setSelectedCamera(videoInputDevices[0].deviceId);
          handleStartVideo(videoInputDevices[0].deviceId);
        }

        if (audioInputDevices.length > 0) {
          setSelectedMicrophone(audioInputDevices[0].deviceId);
          handleStartAudio(audioInputDevices[0].deviceId);
        }
      } catch (error) {
        console.error('Error fetching media devices:', error);
      }
    };

    fetchDevices();

    // Listen for device changes
    navigator.mediaDevices.addEventListener('devicechange', fetchDevices);

    return () => {
      navigator.mediaDevices.removeEventListener('devicechange', fetchDevices);
      stopAudio();
      stopVideo();
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // Handle camera selection changes
  useEffect(() => {
    if (selectedCamera) {
      handleStartVideo(selectedCamera);
    } else {
      stopVideo();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [selectedCamera]);

  // Handle microphone selection changes
  useEffect(() => {
    if (selectedMicrophone) {
      handleStartAudio(selectedMicrophone);
    } else {
      stopAudio();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [selectedMicrophone]);

  // Function to start video stream
  const handleStartVideo = async (deviceId: string) => {
    stopVideo(); // Stop any existing video streams
    try {
      const stream = await navigator.mediaDevices.getUserMedia({
        video: { deviceId: { exact: deviceId } },
      });
      if (videoRef.current) {
        videoRef.current.srcObject = stream;
      }
      mediaStreamRef.current = stream;
    } catch (error) {
      console.error('Error starting video:', error);
    }
  };

  // Function to stop video stream
  const stopVideo = () => {
    if (mediaStreamRef.current) {
      mediaStreamRef.current.getTracks().forEach(track => track.stop());
      mediaStreamRef.current = null;
    }
    if (videoRef.current) {
      videoRef.current.srcObject = null;
    }
  };

  // Function to start audio analysis
  const handleStartAudio = async (deviceId: string) => {
    stopAudio(); // Stop any existing audio streams

    try {
      const stream = await navigator.mediaDevices.getUserMedia({
        audio: { deviceId: { exact: deviceId } },
      });
      mediaStreamRef.current = stream;

      audioContextRef.current = new (window.AudioContext || (window as any).webkitAudioContext)();
      const source = audioContextRef.current.createMediaStreamSource(stream);

      analyserRef.current = audioContextRef.current.createAnalyser();
      analyserRef.current.fftSize = 256;
      const bufferLength = analyserRef.current.frequencyBinCount;
      dataArrayRef.current = new Uint8Array(bufferLength);

      source.connect(analyserRef.current);

      const analyze = () => {
        if (analyserRef.current && dataArrayRef.current) {
          analyserRef.current.getByteFrequencyData(dataArrayRef.current);
          let sum = 0;
          for (let i = 0; i < dataArrayRef.current.length; i++) {
            sum += dataArrayRef.current[i];
          }
          const avg = sum / dataArrayRef.current.length;
          setAudioLevel(avg);
        }
        animationIdRef.current = requestAnimationFrame(analyze);
      };

      analyze();
    } catch (error) {
      console.error('Error starting audio:', error);
    }
  };

  // Function to stop audio analysis
  const stopAudio = () => {
    if (animationIdRef.current) {
      cancelAnimationFrame(animationIdRef.current);
      animationIdRef.current = null;
    }
    if (audioContextRef.current) {
      audioContextRef.current.close();
      audioContextRef.current = null;
    }
    setAudioLevel(0);
    if (mediaStreamRef.current) {
      mediaStreamRef.current.getTracks().forEach(track => track.stop());
      mediaStreamRef.current = null;
    }
  };

  return (
    <div className="max-w-4xl mx-auto p-6 bg-white shadow-md rounded-lg border-2 border-gray-300">
        <h3 className='font-bold text-lg mb-2'>Préparation de l'entretiens</h3>
      <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
       

        {/* Video Control Section */}
        <div className="p-4 border rounded-lg bg-gray-50"> <div className="mb-4">
              <div className='mb-2'>
              <div className="flex items-center space-x-4">
                <CameraPermissionButton />
              <PermissionStatus
                permissionType="camera"
                state={cameraPermissionState}
                className="text-sm text-gray-600"
              /></div></div>
              <video
                ref={videoRef}
                autoPlay
                playsInline
                muted
                className="w-full h-auto border rounded-md shadow-sm"
                width="100%"
                height="auto"
              />
            </div>
          <div className="space-y-4">
            <div>
              <label htmlFor="cameraSelect" className="block text-sm font-medium text-gray-700 mb-1">
                Select Camera
              </label>
              <select
                id="cameraSelect"
                className="w-full border border-gray-300 rounded-md p-2 focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm"
                value={selectedCamera || ''}
                onChange={e => setSelectedCamera(e.target.value)}
                
              >
                <option value="">-- Select a camera --</option>
                {videoDevices.map(device => (
                  <option key={device.deviceId} value={device.deviceId}>
                    {device.label || `Camera ${device.deviceId}`}
                  </option>
                ))}
              </select>
            </div>
           
          </div>
        </div>

        {/* Audio Control Section */}
        <div className="p-4 border rounded-lg bg-gray-50">
        <div  className='mb-2'>
        <div className="flex items-center space-x-4">
              <MicrophonePermissionButton/>
              <PermissionStatus
                permissionType="microphone"
                state={microphonePermissionState}
                className="text-sm text-gray-600"
              />
            </div>
            </div>
          <div className="space-y-4">
            <div> <label className="block text-sm font-medium text-gray-700 mb-1">Microphone Input Level</label>
              <progress
  value={audioLevel}
  max={255}
  className="w-full h-2 bg-gray-200 rounded"
  style={{ appearance: 'none', WebkitAppearance: 'none', MozAppearance: 'none' }}
>
  <style>
    {`
      progress::-webkit-progress-bar {
        background-color: #e5e7eb; /* bg-gray-200 */
        border-radius: 0.375rem; /* rounded */
      }
      progress::-webkit-progress-value {
        background-color: #10b981; /* green-500 */
        border-radius: 0.375rem;
      }
      progress::-moz-progress-bar {
        background-color: #10b981;
        border-radius: 0.375rem;
      }
    `}
  </style>
</progress>

            </div>
              <label htmlFor="microphoneSelect" className="block text-sm font-medium text-gray-700 mb-1">
                Select Microphone
              </label>
              <select
                id="microphoneSelect"
                className="w-full border border-gray-300 rounded-md p-2 focus:outline-none focus:ring-2 focus:ring-green-500 text-sm"
                value={selectedMicrophone || ''}
                onChange={e => setSelectedMicrophone(e.target.value)}
              >
                <option value="">-- Select a microphone --</option>
                {audioDevices.map(device => (
                  <option key={device.deviceId} value={device.deviceId}>
                    {device.label || `Microphone ${device.deviceId}`}
                  </option>
                ))}
              </select>
            </div>
            <div>
             
          </div>
        </div>
      </div>
      <p className='my-2 p-0 text-sm text-gray-500 font-bold'>
        Pour utiliser nos simulation d'entretiens , vous devez activer les permissions de votre navigateur. </p>
        <p className='my-2 p-0 text-sm text-gray-500'>
        La caméra n'est pas requise pour les simulations mais elle est recommandée pour une meilleure expérience utilisateur.
        </p>

        <p className='my-2 p-0 text-sm text-gray-500'>
        Le microphone est nécessaire pour les simulations et est utilisé pour enregistrer les conversations.
       </p>
       <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
                <button className="w-full px-4 py-2 bg-gray-500 text-white rounded-md hover:bg-blue-600 transition-colors text-sm disabled:bg-blue-300"
              
            >
                COMMENCER  
                </button>
       </div>
    </div>
  );
};
