from PyQt6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QGroupBox
from PyQt6.QtCore import QTimer, pyqtSignal, Qt
from PyQt6.QtGui import QIcon
import sys, os

from View.CameraGrid import CameraGrid
from View.CameraSettingsPanel import CameraSettingsPanel
from Model.ESP32Cam import ESP32Cam

if getattr(sys, 'frozen', False):
    ASSETS_PATH = os.path.join(sys._MEIPASS, "assets")
else:
    ASSETS_PATH = os.path.join(os.path.dirname(__file__), "..", "assets") 

class MainView(QWidget):

    show_signal = pyqtSignal() # Signal to show the main view
    new_camera_added_signal = pyqtSignal(list) # Signal to update the camera 

    def __init__(self) -> None:
        super().__init__()
        self._init_ui()        


    def _init_ui(self) -> None:
        # << -- Window setup -- >>
        self.setWindowTitle("Security System Client")
        self.setMinimumSize(800, 400) # Set minimum size

        # << -- Signal setup -- >>
        self.show_signal.connect(self.show) # Connect the show signal to the show method
        
        # << -- Timer setup -- >>
        self.frame_timer = QTimer() # Timer to update the frames
        self.ping_timer = QTimer()
        self.timout_timer = QTimer()
        
        # << -- Main layout setup -- >>
        self.main_layout = QHBoxLayout()  
        self.left_layout = QVBoxLayout()
        self.right_layout = QVBoxLayout() 
        self.main_layout.addLayout(self.left_layout, 4) # Left layout takes 4/5 of the window
        self.main_layout.addLayout(self.right_layout, 1) # Right layout takes 1/5 of the window
        self.setLayout(self.main_layout) 
        
        # << -- Left layout setup -- >>
        self.camera_grid = CameraGrid()
        self.start_stop_stream_button = QPushButton("Start Stream") # Button for start/stop stream 
        self.start_stop_stream_button.setStyleSheet("background-color: green;")
        self.control_panel_button = QPushButton("Control Panel") # Button for camera control
        self.control_panel_button.setHidden(True) # Hide the button by default
        self.left_layout.addLayout(self.camera_grid) 
        self.left_layout.addWidget(self.control_panel_button)
        self.left_layout.addWidget(self.start_stop_stream_button)

        # << -- Right layout setup -- >>
        self.camera_settings_groupbox = QGroupBox("Configure Camera Settings") 
        self.camera_settings_panel = CameraSettingsPanel()
        self.light_dark_mode_button = QPushButton() # Button for light/dark mode
        self.light_dark_mode_button.setFixedSize(30, 30) 
        icon = QIcon(os.path.join(ASSETS_PATH, "dark-mode.png")) # Load the icon for light/dark mode button
        self.light_dark_mode_button.setIcon(icon) # Set the icon for light/dark mode button
        self.camera_settings_groupbox.setLayout(self.camera_settings_panel)
        self.right_layout.addWidget(self.camera_settings_groupbox)
        self.right_layout.addWidget(self.light_dark_mode_button)
        self.right_layout.setAlignment(self.light_dark_mode_button, Qt.AlignmentFlag.AlignRight) # Align the button to the right

        # << -- Callbacks setup -- >>
        self.light_dark_mode_button.clicked.connect(self._toggle_light_dark_mode) # Connect the light/dark mode button to the callback

        self._set_light_mode() # Set light mode by default
    
    def get_current_camera_id(self) -> str:
        """Get the current camera id from the combobox."""
        return self.camera_settings_panel.get_current_camera_id() # Get the current camera id from the combobox

    def show_camera_settings(self) -> None:
        """Show the camera settings panel."""
        self.camera_settings_panel.show_camera_settings()  
        
    def hide_camera_settings(self) -> None: 
        """Hide the camera settings panel."""
        self.camera_settings_panel.hide_camera_settings()    

    def get_camera_settings(self) -> dict[str, str | int | bool]:
        """Get the camera settings from the camera settings panel."""
        return self.camera_settings_panel.get_camera_settings()
    
    def set_camera_settings(self, camera: ESP32Cam) -> None:
        """Set the camera settings to the camera settings panel."""
        self.camera_settings_panel._set_camera_settings(camera)

    def get_scene_by_camera_id(self, camera_id: str):
        """Get the scene by camera id."""
        return self.camera_grid.get_scene_by_camera_id(camera_id)
    
    def set_default_images(self) -> None:
        """Set the default images for the cameras."""
        self.camera_grid.set_default_images()


    def _update_camera_grid(self, cameras: list[ESP32Cam]) -> None:
        self.camera_grid.delete() # Clear the previous layout
        self.camera_grid = CameraGrid(cameras) # Create a new layout with the new camera 
        self.left_layout.insertLayout(0, self.camera_grid) 
        self.camera_settings_panel.update_camera_id_combobox(cameras) # Update the camera id combobox    

    def update_frames(self) -> None:
        """Update the frames from the cameras."""
        self.camera_grid.update_frames()

    
    def _toggle_light_dark_mode(self) -> None:
        """Toggle between light and dark mode."""
        if self._mode == "light":
            self._set_dark_mode()
        else:
            self._set_light_mode()

    def _set_dark_mode(self) -> None:
        """Set the dark mode for the application."""
        self._mode = "dark"
        icon = QIcon(os.path.join(ASSETS_PATH, "light-mode.png"))
        self.light_dark_mode_button.setIcon(icon)
        self.setStyleSheet("background-color: #222222; color: #ffffff;")

    def _set_light_mode(self) -> None:
        """Set the light mode for the application."""
        self._mode = "light"
        icon = QIcon(os.path.join(ASSETS_PATH, "dark-mode.png"))
        self.light_dark_mode_button.setIcon(icon)
        self.setStyleSheet("background-color: #ffffff; color: #000000;")

    @property
    def mode(self) -> str:
        """Get the current mode of the application."""
        return self._mode
