import numpy as np

from PyQt6.QtWidgets import QGridLayout

from Model.ESP32Cam import ESP32Cam
from View.CameraViewer import CameraViewer


class CameraGrid(QGridLayout):
    """
    A grid layout for displaying multiple camera views.
    """

    def __init__(self, cameras_list: list[ESP32Cam] = []):
        super().__init__()
        self._cameras_list = cameras_list
        self._camera_viewers : dict[str, CameraViewer] = {}  

        # << -- Setup the camera grid layout -- >>
        coordinates = self._get_coordinates(len(self._cameras_list))
        for i, camera in enumerate(self._cameras_list):
            row, col = coordinates[i]
            camera_viewer = CameraViewer(camera)
            self._camera_viewers[camera.id] = camera_viewer
            self.addWidget(camera_viewer, row, col)
    
    
    def _get_coordinates(self, camera_num: int) -> list[tuple[int, int]]:
        """Get the coordinates for the camera layout based on the number of cameras."""
        if camera_num == 0:
            return []
        
        rows = int(np.ceil(np.sqrt(camera_num)))
        coordinates = [(i // rows, i % rows) for i in range(camera_num)]
        return coordinates

        
    def delete(self):
        """Delete the camera layout and all its widgets."""
        for camera_viewer in self._camera_viewers.values():
            camera_viewer.delete()
        self._camera_viewers.clear()
        self._cameras_list.clear()
        self.deleteLater()


    def update_frames(self):
        """Update the frames from the cameras."""
        for camera in self._cameras_list:
            if camera.id in self._camera_viewers:
                self._camera_viewers[camera.id].update_frame()


    def get_scene_by_camera_id(self, camera_id: str):
        """Get the scene by camera id."""
        if camera_id in self._camera_viewers:
            return self._camera_viewers[camera_id].get_scene()
        return None
    
    def set_default_images(self) -> None:
        """Set the default images for the cameras."""
        for camera_viewer in self._camera_viewers.values():
            camera_viewer.set_default_image()
        

        