import React, { useState, useRef, useEffect } from 'react';
import { motion } from 'framer-motion';
import Webcam from 'react-webcam';
import { Minimize2, Maximize2, X } from 'lucide-react';
import * as facemesh from "@tensorflow-models/face-landmarks-detection";
import * as tf from '@tensorflow/tfjs';
import '@tensorflow/tfjs-backend-webgl';
import { Prediction, ScaledMesh } from '../utils/drawMesh';
import { FaceRecognitionProps } from '../types';

interface returnProps {

  markes: ScaledMesh,
  video: HTMLVideoElement,
  mirrorVideo:HTMLCanvasElement
}

interface FloatingCameraMonitorProps  extends FaceRecognitionProps{
  onClose: () => void;
  onLandmarks:(data: returnProps )=> void
}

export const FloatingCameraMonitor: React.FC<FloatingCameraMonitorProps> = ({
  onClose,
  onLandmarks
}) => {
  const [isMinimized, setIsMinimized] = useState(false);
  const [position, setPosition] = useState({ x: 0, y: 0 });
  const constraintsRef = useRef(null);
  const webcamRef = useRef<Webcam>(null);

  const videoConstraints = {
    width: 320,
    height: 240,
    facingMode: "user"
  };

  async function ActiveBackend(){
    await tf.setBackend('webgl');
    await tf.ready();
  }

  function createVideoMirror(video: HTMLVideoElement): HTMLCanvasElement {
    const canvas = document.createElement('canvas');
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
  
    const ctx = canvas.getContext('2d');
  
    const interval = setInterval(() => {
      if (video.readyState === 4 && ctx) {
        ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
      }
    }, 100);
    (canvas as any).__mirrorInterval = interval;
  
    return canvas;
  }

  async function detect(net: facemesh.FaceLandmarksDetector){


    const video = webcamRef.current?.video;

    if (video && video.readyState === 4) {

      const videoWidth = video.videoWidth;
      const videoHeight = video.videoHeight;

      video.width = videoWidth;
      video.height = videoHeight;


      const face = await net.estimateFaces({ input: video }) as Prediction[]

      if (face.length == 1 ) {
        const landmarks = face[0].scaledMesh;

        if(landmarks){
          onLandmarks({
            markes:landmarks,
            video: video,
            mirrorVideo: createVideoMirror(video)
          })
        }
      }

    }

  }

  useEffect(() => {
    // Initialize position to bottom right corner
    setPosition({
      x: window.innerWidth - 360,
      y: window.innerHeight - 280
    });
  }, []);


  useEffect(() => {
  
      ActiveBackend()
      let animationId: number;
      let net: facemesh.FaceLandmarksDetector;
    
      const startDetection = async () => {
        net = await facemesh.load(facemesh.SupportedPackages.mediapipeFacemesh);
    
        const detectLoop = async () => {
          await detect(net);
          animationId = requestAnimationFrame(detectLoop);
        };
    
        detectLoop();
      };
    
      startDetection();
    
      return () => {
        cancelAnimationFrame(animationId);
      };
    }, []);

  return (
    <motion.div
      drag
      dragConstraints={{
        left: 0,
        right: window.innerWidth - (isMinimized ? 80 : 320),
        top: 0,
        bottom: window.innerHeight - (isMinimized ? 80 : 240)
      }}
      dragMomentum={false}
      initial={position}
      animate={{
        width: isMinimized ? 80 : 320,
        height: isMinimized ? 80 : 240,
      }}
      className="fixed z-50 rounded-lg shadow-xl overflow-hidden bg-white"
    >
      <div className="absolute top-0 right-0 p-2 flex gap-2 z-10 bg-linear-to-b from-black/50 to-transparent">
        <button
          onClick={() => setIsMinimized(!isMinimized)}
          className="p-1 rounded hover:bg-white/20 text-white transition-colors"
        >
          {isMinimized ? <Maximize2 size={16} /> : <Minimize2 size={16} />}
        </button>
        <button
          onClick={onClose}
          className="p-1 rounded hover:bg-white/20 text-white transition-colors"
        >
          <X size={16} />
        </button>
      </div>

      <Webcam
        ref={webcamRef}
        audio={false}
        videoConstraints={videoConstraints}
        className="w-full h-full object-cover"
        
      />
    </motion.div>
  );
};