# FlightMonitor/controller/cleanup_manager.py
"""
Manages the orderly shutdown and cleanup of application resources,
including closing database connections, stopping background threads,
and destroying secondary GUI windows upon application exit or specific events.
"""
from typing import Any, Optional, TYPE_CHECKING

from ..utils.logger import get_logger

# Type checking imports to avoid circular dependencies at runtime
if TYPE_CHECKING:
    from flightmonitor.controller.app_controller import AppController
    from flightmonitor.data.storage import DataStorage
    from flightmonitor.data.aircraft_database_manager import AircraftDatabaseManager
    from flightmonitor.gui.main_window import MainWindow
    from flightmonitor.gui.dialogs.full_flight_details_window import FullFlightDetailsWindow
    from flightmonitor.map.map_canvas_manager import MapCanvasManager


module_logger = get_logger(__name__)


class CleanupManager:
    """
    Handles all application shutdown and resource cleanup operations.
    It orchestrates the closing of various modules and components.
    """

    def __init__(self, app_controller: "AppController"):
        """
        Initializes the CleanupManager.

        Args:
            app_controller: The main AppController instance, providing access
                            to all application components that need cleanup.
        """
        self.app_controller = app_controller
        module_logger.debug("CleanupManager initialized.")

    def on_application_exit(self):
        """
        Performs a coordinated shutdown of all application resources.
        This method is called when the main application window is closing.
        """
        module_logger.info("CleanupManager: Application exit requested. Cleaning up resources.")

        # --- Close active Full Flight Details window (if any) ---
        # Access active_detail_window_ref and active_detail_window_icao via app_controller
        if (
            self.app_controller.active_detail_window_ref
            and self.app_controller.active_detail_window_ref.winfo_exists()
        ):
            try:
                module_logger.info(
                    f"CleanupManager: Closing active detail window for {self.app_controller.active_detail_window_icao} on app exit."
                )
                self.app_controller.active_detail_window_ref.destroy()
            except Exception as e_close_detail:
                module_logger.error(
                    f"CleanupManager: Error closing detail window on app exit: {e_close_detail}"
                )
            finally:
                # Clear references in AppController directly or via a method
                self.app_controller.active_detail_window_ref = None
                self.app_controller.active_detail_window_icao = None

        # --- Shutdown MapCanvasManager worker (if active) ---
        # Access map_manager_instance via app_controller.main_window
        main_window = self.app_controller.main_window
        if (
            main_window
            and hasattr(main_window, "map_manager_instance")
            and main_window.map_manager_instance is not None
        ):
            map_manager: "MapCanvasManager" = main_window.map_manager_instance
            if hasattr(map_manager, "shutdown_worker") and callable(map_manager.shutdown_worker):
                try:
                    map_manager.shutdown_worker()
                    module_logger.info("CleanupManager: Main MapCanvasManager worker shutdown requested.")
                except Exception as e_map_shutdown:
                    module_logger.error(
                        f"CleanupManager: Error during Main MapCanvasManager worker shutdown: {e_map_shutdown}",
                        exc_info=True,
                    )

        # --- Stop live monitoring (adapter thread and data processor) ---
        # Access live_adapter_thread, is_live_monitoring_active via app_controller
        # Access stop_live_monitoring via app_controller
        is_adapter_considered_running = (
            self.app_controller.live_adapter_thread and self.app_controller.live_adapter_thread.is_alive()
        ) or self.app_controller.is_live_monitoring_active
        if is_adapter_considered_running:
            module_logger.info("CleanupManager: Live monitoring is active, requesting AppController to stop it.")
            self.app_controller.stop_live_monitoring(from_error=False)

        # --- Close DataStorage connection ---
        # Access data_storage via app_controller
        if self.app_controller.data_storage:
            try:
                self.app_controller.data_storage.close_connection()
                module_logger.info("CleanupManager: DataStorage connection closed.")
            except Exception as e_db_close:
                module_logger.error(
                    f"CleanupManager: Error closing DataStorage: {e_db_close}", exc_info=True
                )
            finally:
                self.app_controller.data_storage = None # Clear reference in AppController

        # --- Close AircraftDatabaseManager connection ---
        # Access aircraft_db_manager via app_controller
        if self.app_controller.aircraft_db_manager:
            try:
                self.app_controller.aircraft_db_manager.close_connection()
                module_logger.info("CleanupManager: AircraftDatabaseManager connection closed.")
            except Exception as e_ac_db_close:
                module_logger.error(
                    f"CleanupManager: Error closing AircraftDatabaseManager: {e_ac_db_close}",
                    exc_info=True,
                )
            finally:
                self.app_controller.aircraft_db_manager = None # Clear reference in AppController

        module_logger.info("CleanupManager: Cleanup on application exit finished.")

    def details_window_closed(self, closed_icao24: str):
        """
        Handles the event when a full flight details window is closed.
        Clears the AppController's references to the closed window if it was the active one.

        Args:
            closed_icao24: The ICAO24 of the flight whose details window was closed.
        """
        normalized_closed_icao24 = closed_icao24.lower().strip()
        
        # Access active_detail_window_icao and active_detail_window_ref via app_controller
        if self.app_controller.active_detail_window_icao == normalized_closed_icao24:
            module_logger.info(
                f"CleanupManager: Detail window for {normalized_closed_icao24} reported closed. Clearing references in AppController."
            )
            self.app_controller.active_detail_window_ref = None
            self.app_controller.active_detail_window_icao = None
            # Also clear MainWindow's convenience reference if it matches (accessed via app_controller)
            main_window = self.app_controller.main_window
            if (
                main_window
                and hasattr(main_window, "full_flight_details_window")
                and main_window.full_flight_details_window
                and not main_window.full_flight_details_window.winfo_exists()
            ): # Check if already destroyed by Tkinter
                main_window.full_flight_details_window = None
        else:
            module_logger.debug(
                f"CleanupManager: A detail window for {normalized_closed_icao24} closed, but it was not the currently tracked active one ({self.app_controller.active_detail_window_icao}). No action on active_detail references."
            )