"""Camera capture and management functionality."""

import cv2
import numpy as np
from typing import Optional, Tuple
import time


class CameraCapture:
    """Handles webcam capture and frame management."""
    
    def __init__(self, camera_index: int = 0):
        """
        Initialize camera capture.
        
        Args:
            camera_index: Camera device index (usually 0 for default camera)
        """
        self.camera_index = camera_index
        self.cap: Optional[cv2.VideoCapture] = None
        self.is_opened = False
        
    def open(self) -> bool:
        """
        Open the camera connection.
        
        Returns:
            True if camera opened successfully, False otherwise
        """
        try:
            self.cap = cv2.VideoCapture(self.camera_index)
            
            if not self.cap.isOpened():
                return False
                
            # Set some optimal capture properties
            self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
            self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) 
            self.cap.set(cv2.CAP_PROP_FPS, 30)
            
            # Test capture
            ret, _ = self.cap.read()
            if not ret:
                self.cap.release()
                return False
                
            self.is_opened = True
            return True
            
        except Exception as e:
            print(f"Error opening camera: {e}")
            return False
    
    def close(self) -> None:
        """Close the camera connection."""
        if self.cap:
            self.cap.release()
            self.is_opened = False
    
    def read_frame(self) -> Optional[np.ndarray]:
        """
        Read a frame from the camera.
        
        Returns:
            Frame as numpy array if successful, None otherwise
        """
        if not self.is_opened or not self.cap:
            return None
            
        ret, frame = self.cap.read()
        if not ret:
            return None
            
        return frame
    
    def get_camera_info(self) -> dict:
        """Get information about the current camera."""
        if not self.is_opened or not self.cap:
            return {}
            
        return {
            "width": int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
            "height": int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT)),
            "fps": self.cap.get(cv2.CAP_PROP_FPS),
            "backend": self.cap.getBackendName(),
        }
    
    def __enter__(self):
        """Context manager entry."""
        if self.open():
            return self
        else:
            raise RuntimeError(f"Failed to open camera {self.camera_index}")
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        """Context manager exit."""
        self.close()


class FrameRateController:
    """Controls frame rate for smooth video playback."""
    
    def __init__(self, target_fps: float = 12.0):
        """
        Initialize frame rate controller.
        
        Args:
            target_fps: Target frames per second
        """
        self.target_fps = target_fps
        self.frame_time = 1.0 / target_fps
        self.last_frame_time = time.time()
        
    def wait(self) -> None:
        """Wait to maintain target frame rate."""
        current_time = time.time()
        elapsed = current_time - self.last_frame_time
        
        if elapsed < self.frame_time:
            time.sleep(self.frame_time - elapsed)
            
        self.last_frame_time = time.time()
    
    def set_fps(self, fps: float) -> None:
        """Update target FPS."""
        self.target_fps = fps
        self.frame_time = 1.0 / fps
