
import React, { useEffect, useRef, useState } from 'react';
import { useFaceTracking } from '../hooks/useFaceTracking';
import { removeBackground } from '../services/visionService';
import { AvatarConfig, Rect } from '../types';
import LoadingSpinner from './LoadingSpinner';

interface StudioProps {
  avatar: AvatarConfig;
  onBack: () => void;
}

/**
 * Sprite Component
 * Renders a specific crop of the source image into a target container.
 */
const Sprite: React.FC<{
  imageSrc: string;
  sourceRect: Rect;
  style?: React.CSSProperties;
  className?: string;
}> = ({ imageSrc, sourceRect, style, className }) => {
  // To display a cropped region (sourceRect) of the image, we use an inner <img>
  // positioned negatively and scaled up.
  // Example: If sourceRect.w is 0.1 (10%), the image must be scaled to 10x (1000%) size.
  const widthScale = 100 / (sourceRect.w * 100);
  const heightScale = 100 / (sourceRect.h * 100);
  
  return (
    <div 
      className={`overflow-hidden relative ${className}`}
      style={style}
    >
      <img 
        src={imageSrc} 
        alt=""
        style={{
          position: 'absolute',
          top: `-${sourceRect.y * 100 * heightScale}%`,
          left: `-${sourceRect.x * 100 * widthScale}%`,
          width: `${widthScale * 100}%`,
          height: `${heightScale * 100}%`,
          maxWidth: 'none',
          maxHeight: 'none',
          pointerEvents: 'none'
        }}
      />
    </div>
  );
};

const Studio: React.FC<StudioProps> = ({ avatar, onBack }) => {
  const videoRef = useRef<HTMLVideoElement>(null);
  const [cameraReady, setCameraReady] = useState(false);
  const [processedImageUrl, setProcessedImageUrl] = useState<string | null>(null);
  
  // We use the custom hook to get tracking data
  const { trackingData, isLoading: isModelLoading, startTracking } = useFaceTracking(videoRef.current);

  // Initialize Camera
  useEffect(() => {
    const startCamera = async () => {
      try {
        const stream = await navigator.mediaDevices.getUserMedia({ 
          video: { width: 640, height: 480 }, // Lower res is fine for tracking
          audio: false 
        });
        if (videoRef.current) {
          videoRef.current.srcObject = stream;
          videoRef.current.onloadeddata = () => {
            setCameraReady(true);
          };
        }
      } catch (err) {
        console.error("Error accessing camera:", err);
        alert("Could not access camera. Please ensure permissions are granted.");
      }
    };

    startCamera();

    return () => {
      // Cleanup stream
      if (videoRef.current && videoRef.current.srcObject) {
        const stream = videoRef.current.srcObject as MediaStream;
        stream.getTracks().forEach(track => track.stop());
      }
    };
  }, []);

  // Process Image for Background Removal (AI Segmentation)
  useEffect(() => {
    if (!avatar.chromaKeyColor) {
      setProcessedImageUrl(avatar.imageUrl);
      return;
    }

    const process = async () => {
      // If chromaKeyColor is set (to anything, now treated as a flag), we run AI removal
      const result = await removeBackground(avatar.imageUrl);
      setProcessedImageUrl(result);
    };

    process();
  }, [avatar.imageUrl, avatar.chromaKeyColor]);

  // Start tracking when both camera and model are ready
  useEffect(() => {
    if (cameraReady && !isModelLoading) {
      startTracking();
    }
  }, [cameraReady, isModelLoading, startTracking]);

  // Calculate styles based on tracking data
  const getAvatarStyle = () => {
    // Deadzone for jitter reduction
    const smooth = (val: number) => Math.abs(val) < 0.02 ? 0 : val;
    
    const rX = smooth(trackingData.rotationX); // Pitch
    const rY = smooth(trackingData.rotationY); // Yaw
    const rZ = smooth(trackingData.rotationZ); // Roll
    const tX = smooth(trackingData.translationX);
    const tY = smooth(trackingData.translationY);

    // Bounce effect on mouth open (Speaking emulation)
    const bounce = trackingData.mouthOpen > 0.1 ? -5 * trackingData.mouthOpen : 0;

    return {
      transform: `
        translate(${tX * 150}px, ${tY * 100 + bounce}px)
        rotate(${rZ * 1}rad)
        perspective(500px)
        rotateX(${rX * 15}deg)
        rotateY(${rY * -25}deg)
        scale(${1 + trackingData.mouthOpen * 0.02}) 
      `,
      filter: `brightness(${1 + trackingData.mouthOpen * 0.05})`, // Slight flash when speaking
      transition: 'transform 0.1s ease-out, filter 0.1s ease'
    };
  };

  return (
    <div className="h-screen w-full flex flex-col bg-slate-900 overflow-hidden relative">
      {/* Hidden Video Element for Tracking */}
      <video 
        ref={videoRef}
        autoPlay 
        playsInline
        muted 
        className="absolute opacity-0 pointer-events-none w-1 h-1"
      />

      {/* Top Bar */}
      <div className="absolute top-0 left-0 right-0 z-20 p-4 flex justify-between items-center bg-gradient-to-b from-slate-900 to-transparent">
        <button 
          onClick={onBack}
          className="px-4 py-2 bg-slate-800/80 hover:bg-slate-700 backdrop-blur rounded-lg text-white font-medium transition-colors border border-slate-600"
        >
          ← Exit Studio
        </button>
        <div className="flex gap-2">
          <div className={`px-3 py-1 rounded-full text-xs font-bold flex items-center gap-2 ${isModelLoading ? 'bg-yellow-500/20 text-yellow-400' : 'bg-green-500/20 text-green-400'}`}>
            <span className={`w-2 h-2 rounded-full ${isModelLoading ? 'bg-yellow-400 animate-pulse' : 'bg-green-400'}`}></span>
            {isModelLoading ? 'Loading Vision Model...' : 'Tracking Active'}
          </div>
          <div className="px-3 py-1 rounded-full text-xs font-bold bg-purple-500/20 text-purple-400 border border-purple-500/30">
            {avatar.name}
          </div>
        </div>
      </div>

      {/* Main Stage */}
      <div className="flex-1 relative flex items-center justify-center overflow-hidden">
        {/* Background Grid/Effect */}
        <div className="absolute inset-0 opacity-20" 
             style={{ 
               backgroundImage: 'radial-gradient(#4f46e5 1px, transparent 1px)', 
               backgroundSize: '30px 30px' 
             }}>
        </div>
        
        <div className="absolute inset-0 bg-gradient-to-t from-slate-900 via-transparent to-slate-900 pointer-events-none"></div>

        {/* Avatar Container */}
        <div className="relative w-[600px] h-[600px] flex items-center justify-center z-10">
          {!processedImageUrl ? (
            <div className="flex flex-col items-center justify-center gap-4">
               <LoadingSpinner />
               <span className="text-cyan-400 font-mono text-sm">REMOVING BACKGROUND...</span>
            </div>
          ) : (
            <div 
              className="relative w-full h-full flex items-center justify-center"
              style={getAvatarStyle()}
            >
              {/* Main Character Body (Cropped using Sprite) */}
              {avatar.mainBody ? (
                  <Sprite 
                    imageSrc={processedImageUrl}
                    sourceRect={avatar.mainBody}
                    className="w-full h-full object-contain drop-shadow-[0_0_15px_rgba(168,85,247,0.5)]"
                  />
              ) : (
                  /* Fallback to full image if mainBody is missing */
                  <img 
                    src={processedImageUrl} 
                    alt="Avatar"
                    className="w-full h-full object-contain drop-shadow-[0_0_15px_rgba(168,85,247,0.5)]"
                  />
              )}

              {/* Dynamic Eyelids (High Fidelity Sprites) */}
              {avatar.leftEye && avatar.textureClosedEye && (
                <Sprite 
                  imageSrc={processedImageUrl}
                  sourceRect={avatar.textureClosedEye}
                  className="absolute pointer-events-none z-20"
                  style={{
                    left: `${avatar.leftEye.x * 100}%`,
                    top: `${avatar.leftEye.y * 100}%`,
                    width: `${avatar.leftEye.w * 100}%`,
                    height: `${avatar.leftEye.h * 100}%`,
                    opacity: trackingData.isBlinkingLeft ? 1 : 0,
                    transition: 'opacity 0.05s linear',
                  }}
                />
              )}
              
              {avatar.rightEye && avatar.textureClosedEye && (
                <Sprite 
                  imageSrc={processedImageUrl}
                  sourceRect={avatar.textureClosedEye}
                  className="absolute pointer-events-none z-20"
                  style={{
                    left: `${avatar.rightEye.x * 100}%`,
                    top: `${avatar.rightEye.y * 100}%`,
                    width: `${avatar.rightEye.w * 100}%`,
                    height: `${avatar.rightEye.h * 100}%`,
                    opacity: trackingData.isBlinkingRight ? 1 : 0,
                    transition: 'opacity 0.05s linear',
                  }}
                />
              )}

              {/* Dynamic Mouth Animation */}
              {avatar.mouth && avatar.textureOpenMouth && (
                <div 
                  className="absolute pointer-events-none flex items-center justify-center z-10"
                  style={{
                    left: `${avatar.mouth.x * 100}%`,
                    top: `${avatar.mouth.y * 100}%`,
                    width: `${avatar.mouth.w * 100}%`,
                    height: `${avatar.mouth.h * 100}%`,
                  }}
                >
                    {/* Skin Patch - Hides the static closed mouth when speaking */}
                    <div 
                      className="absolute w-[120%] h-[120%] transition-opacity duration-75"
                      style={{
                        backgroundColor: avatar.skinColor || '#fcd3bf',
                        opacity: trackingData.mouthOpen > 0.1 ? 1 : 0,
                        filter: 'blur(4px)', // Blends edges
                        borderRadius: '50%'
                      }}
                    />

                    {/* Mouth Sprite - Scales based on mouth openness */}
                    <Sprite 
                      imageSrc={processedImageUrl}
                      sourceRect={avatar.textureOpenMouth}
                      className="w-full h-full"
                      style={{
                        opacity: trackingData.mouthOpen > 0.05 ? 1 : 0,
                        // Scale open mouth based on volume
                        transform: `scaleY(${0.8 + trackingData.mouthOpen * 0.5})`,
                      }}
                    />
                </div>
              )}
            </div>
          )}
             
             {/* Status Indicator overlay if tracking is lost */}
             {(!cameraReady) && (
               <div className="absolute inset-0 flex items-center justify-center bg-slate-900/80 z-20 rounded-xl backdrop-blur-sm">
                 <div className="text-cyan-400 animate-pulse font-mono">INITIALIZING CAMERA LINK...</div>
               </div>
             )}
        </div>
      </div>

      {/* Control Deck */}
      <div className="h-24 bg-slate-800 border-t border-slate-700 p-4 flex justify-center items-center gap-6 z-20">
         <div className="flex flex-col items-center">
            <span className="text-xs text-slate-400 mb-1 font-mono">MOUTH</span>
            <div className="w-24 h-2 bg-slate-700 rounded-full overflow-hidden">
              <div className="h-full bg-cyan-400 transition-all duration-75" style={{ width: `${Math.min(trackingData.mouthOpen * 100, 100)}%` }}></div>
            </div>
         </div>

         <div className="flex flex-col items-center">
            <span className="text-xs text-slate-400 mb-1 font-mono">HEAD ROLL</span>
            <div className="w-24 h-2 bg-slate-700 rounded-full overflow-hidden flex justify-center relative">
               {/* Center marker */}
               <div className="absolute w-[1px] h-full bg-slate-500 left-1/2"></div>
               <div 
                className="h-full bg-purple-500 transition-all duration-75 absolute" 
                style={{ 
                  width: `${Math.abs(trackingData.rotationZ * 50)}%`,
                  left: trackingData.rotationZ < 0 ? 'auto' : '50%',
                  right: trackingData.rotationZ < 0 ? '50%' : 'auto'
                }}
               ></div>
            </div>
         </div>

         <div className="flex flex-col items-center">
            <span className="text-xs text-slate-400 mb-1 font-mono">BLINK</span>
            <div className="flex gap-2">
               <div className={`w-8 h-2 rounded-full ${trackingData.isBlinkingLeft ? 'bg-pink-500' : 'bg-slate-700'}`}></div>
               <div className={`w-8 h-2 rounded-full ${trackingData.isBlinkingRight ? 'bg-pink-500' : 'bg-slate-700'}`}></div>
            </div>
         </div>
      </div>
    </div>
  );
};

export default Studio;
