import traceback
from customtkinter import CTk

from shared.utils import Logger
from shared.contracts import UpdateDoneCallback
from updater.src.controllers.updater_view_controller import UpdaterViewController
from .updater_view import UpdaterView

# =============== Updater Window ===============
class UpdaterWindow(CTk):
    def __init__(self, 
        templates: dict[str, str], images: dict[str, str], 
        update_done_callback: UpdateDoneCallback,
        kit_url: str,
        fg_color = None, **kwargs):
        super().__init__(fg_color, **kwargs)
        # Logger
        self.logger = Logger.create_logger(logger_name = "Updater Window", log_file_name = "update_app")
        # Callback Function
        self.updateDoneCallback: UpdateDoneCallback = update_done_callback
        
        # Templates and images
        self.templates: dict[str, str] = templates
        self.images: dict[str, str] = images
        
        # Class Instances
        self.updaterView: UpdaterView | None = None
        self.updaterViewController: UpdaterViewController | None = None
        
        # Kit URL
        self.kitUrl = kit_url
        
        # Setup Window
        self.setup_window()
        self.show_update_view()
    # ========== Window Functionality ==========
    def setup_window(self) -> None:
        """Sets the window parameters"""
        try:
            # Template and Image
            windowTemplate: dict[str, str] = self.templates["updater_window"]
            logoImage: str = self.images["logo"]
            
            # Sets window attributes
            self.iconbitmap(logoImage)
            self.resizable(width = False, height = False)
            
            width = windowTemplate["window"]["width"]
            height = windowTemplate["window"]["height"]
            
            screenWidth = self.winfo_screenwidth()
            screenHeight = self.winfo_screenheight()
            
            midWidth = (screenWidth - int(width)) // 2
            midHeight = (screenHeight - int(height)) // 2
            
            # Place window
            self.geometry(f"{width}x{height}+{midWidth}+{midHeight}")
        except:
            traceBack = traceback.format_exc()
            self.logger.error(
                f"[{self.__class__.__name__} - {self.setup_window.__name__}] "
                f"Failed to setup the updater window. \n{traceBack}")
    # ==========================================
    
    # ========== Create View ==========
    def create_update_view(self) -> None:
        """Creates the setup view."""
        try:
            self.updaterView = UpdaterView(
                master = self,
                template = self.templates["update_view"])
            self.updaterViewController = UpdaterViewController(
                updater_view_master = self,
                updater_view = self.updaterView,
                update_done_callback = self.updateDoneCallback,
                kit_url = self.kitUrl)
        except:
            traceBack = traceback.format_exc()
            self.logger.error(
                f"[{self.__class__.__name__} - {self.create_update_view.__name__}] "
                f"Failed to create the update view. \n{traceBack}")
    # =================================
    
    # ========== Show View ==========
    def show_update_view(self) -> None:
        """Shows the updater view."""
        try:
            if self.updaterView is None:
                self.create_update_view()
        except:
            traceBack = traceback.format_exc()
            self.logger.error(
                f"[{self.__class__.__name__} - {self.show_update_view.__name__}] "
                f"Failed to show the update view. \n{traceBack}")
    # ===============================
    
    # ========== Delete View ==========
    def delete_update_view(self) -> None:
        """Destroys the updater view."""
        try:
            self.updaterView.destroy()
            self.updaterView = None
            self.updaterViewController = None
        except:
            traceBack = traceback.format_exc()
            self.logger.error(
                f"[{self.__class__.__name__} - {self.delete_update_view.__name__}] "
                f"Failed to delete the update view. \n{traceBack}")
    # ===============================
# ==============================================