"""Main controller interface - equivalent to C++ IMainCtrl."""

from __future__ import annotations

from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, Protocol

if TYPE_CHECKING:
    from .icomponent import IComponent


class IMainCtrl(ABC):
    """Abstract base class for main controller.

    This interface defines the main control center that manages all components,
    equivalent to the C++ IMainCtrl interface.
    """

    @abstractmethod
    def init(self) -> None:
        """Initialize the main controller.

        Sets up the component management system and registers core components.
        """

    @abstractmethod
    def get_component(self, component_id: str) -> IComponent | None:
        """Get component by ID.

        Args:
            component_id: Component identifier

        Returns
        -------
            IComponent: Component instance or None if not found
        """

    @abstractmethod
    def execute_command(self, command_id: str, in_param: object = None, out_param: object = None) -> bool:
        """Execute a command.

        Routes commands to appropriate components for execution.

        Args:
            command_id: Command identifier
            in_param: Input parameters
            out_param: Output parameters (mutable)

        Returns
        -------
            bool: True if command executed successfully
        """

    @abstractmethod
    def send_message(self, message: str, value: int = 0, param: object = None) -> None:
        """Send message to components.

        Broadcasts messages to registered message handlers.

        Args:
            message: Message identifier
            value: Integer value associated with message
            param: Additional parameter data
        """

    @abstractmethod
    def send_message_to_main(self, message: str, value: int = 0, param: object = None) -> None:
        """Send message specifically to main window.

        Args:
            message: Message identifier
            value: Integer value
            param: Parameter data
        """

    @abstractmethod
    def get_interface_ptr(self, interface_id: str) -> object | None:
        """Get interface pointer by ID.

        Provides access to specialized interfaces from components.

        Args:
            interface_id: Interface identifier

        Returns
        -------
            object | None: Interface implementation or None
        """

    @abstractmethod
    def set_window_handle(self, handle_id: object) -> None:
        """Set main window handle.

        Args:
            handle_id: Window handle/reference
        """

    @abstractmethod
    def quit(self) -> None:
        """Quit the application.

        Performs cleanup and shuts down the system gracefully.
        """

    @abstractmethod
    def get_window_handle(self) -> int:
        """Get main window handle.

        Returns
        -------
            int: Window handle identifier
        """

    @abstractmethod
    def add_hit_info(self, hit_info: str) -> None:
        """Add hint/information message.

        Args:
            hit_info: Information message to display
        """


# Protocol version for type checking
class MainCtrlProtocol(Protocol):
    """Protocol for main controller type checking."""

    def init(self) -> None:
        """Initialize the main controller.

        Sets up the component management system and registers core components.
        """

    def get_component(self, component_id: str) -> IComponent | None:
        """Get component by ID.

        Args:
            component_id: Component identifier

        Returns
        -------
            IComponent: Component instance or None if not found
        """

    def execute_command(self, command_id: str, in_param: object, out_param: object) -> bool:
        """Execute a command.

        Args:
            command_id: Command identifier
            in_param: Input parameters
            out_param: Output parameters (mutable)

        Returns
        -------
            bool: True if command executed successfully
        """

    def send_message(self, message: str, value: int, param: object) -> None:
        """Send message to components.

        Broadcasts messages to registered message handlers.

        Args:
            message: Message identifier
            value: Integer value associated with message
            param: Additional parameter data
        """

    def send_message_to_main(self, message: str, value: int, param: object) -> None:
        """Send message specifically to main window.

        Args:
            message: Message identifier
            value: Integer value
            param: Parameter data
        """

    def get_interface_ptr(self, interface_id: str) -> object | None:
        """Get interface pointer by ID.

        Provides access to specialized interfaces from components.

        Args:
            interface_id: Interface identifier

        Returns
        -------
            object | None: Interface implementation or None
        """

    def set_window_handle(self, handle_id: object) -> None:
        """Set main window handle.

        Args:
            handle_id: Window handle/reference
        """

    def quit(self) -> None:
        """Quit the application.

        Performs cleanup and shuts down the system gracefully.
        """

    def get_window_handle(self) -> int:
        """Get main window handle.

        Returns
        -------
            int: Window handle identifier
        """

    def add_hit_info(self, hit_info: str) -> None:
        """Add hint/information message.

        Args:
            hit_info: Information message to display
        """
