"""Event handlers for external integrations."""

from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from portal.core.events.event_bus import Event, EventBus
    from portal.core.services.config_service import ConfigService
    from portal.infrastructure.ai.claude_context import ClaudeContextProvider
    from portal.infrastructure.editors.cursor_adapter import CursorAdapter
    from portal.infrastructure.editors.vscode_adapter import VSCodeAdapter
    from portal.infrastructure.terminals.iterm_adapter import ITermAdapter
    from portal.infrastructure.terminals.terminal_adapter import TerminalAdapter


class IntegrationEventHandler:
    """Handle events for external integrations."""

    def __init__(
        self,
        event_bus: EventBus,
        config_service: ConfigService,
        iterm_adapter: ITermAdapter,
        terminal_adapter: TerminalAdapter,
        cursor_adapter: CursorAdapter,
        vscode_adapter: VSCodeAdapter,
        claude_context: ClaudeContextProvider,
    ) -> None:
        """Initialize integration event handler.

        Args:
            event_bus: Event bus for subscribing to events
            config_service: Configuration service
            iterm_adapter: iTerm integration adapter
            terminal_adapter: Terminal.app integration adapter
            cursor_adapter: Cursor IDE integration adapter
            vscode_adapter: VSCode integration adapter
            claude_context: Claude context provider
        """
        self.config_service = config_service
        self.iterm_adapter = iterm_adapter
        self.terminal_adapter = terminal_adapter
        self.cursor_adapter = cursor_adapter
        self.vscode_adapter = vscode_adapter
        self.claude_context = claude_context

        # Subscribe to events
        event_bus.subscribe("worktree.created", self.on_worktree_created)
        event_bus.subscribe("worktree.switched", self.on_worktree_switched)
        event_bus.subscribe("worktree.deleted", self.on_worktree_deleted)

    async def on_worktree_created(self, event: Event) -> None:
        """Handle worktree creation."""
        worktree_data = event.data["worktree"]
        color_data = event.data["color"]

        # Convert dictionaries to proper objects
        from portal.core.domain.models import Worktree, WorktreeColor

        # Create Worktree object from dictionary
        worktree = Worktree(**worktree_data)

        # Create WorktreeColor object from dictionary if color exists
        color = WorktreeColor(**color_data) if color_data else None

        # Get configuration (use defaults if config fails)
        try:
            config = await self.config_service.get_config()
            colors_config = config.colors if hasattr(config, "colors") else None
            editor_config = config.editor if hasattr(config, "editor") else None
        except Exception:
            colors_config = None
            editor_config = None

        # Configure editor integration with safety checks
        try:
            # Check if color syncing is enabled (defaults to True)
            sync_enabled = colors_config is None or (
                getattr(colors_config, "sync_cursor", True)
                or getattr(colors_config, "sync_vscode", True)
            )

            if sync_enabled and color is not None:
                # Try Cursor first
                if self.cursor_adapter.is_available():
                    await self.cursor_adapter.configure_workspace_colors(worktree.path, color)

                    # Open in Cursor if auto-open enabled and Cursor is default
                    if (
                        editor_config
                        and getattr(editor_config, "auto_open", False)
                        and getattr(editor_config, "default", "cursor") == "cursor"
                    ):
                        await self.cursor_adapter.open_worktree(worktree.path)

                # Try VSCode as fallback or if it's the default
                elif self.vscode_adapter.is_available():
                    await self.vscode_adapter.configure_workspace_colors(worktree.path, color)

                    # Open in VSCode if auto-open enabled and VSCode is default
                    if (
                        editor_config
                        and getattr(editor_config, "auto_open", False)
                        and getattr(editor_config, "default", "vscode") == "vscode"
                    ):
                        await self.vscode_adapter.open_worktree(worktree.path)
        except Exception:
            # Silently fail editor integration to not break worktree creation
            pass

        # Create Claude context file if enabled
        if (
            colors_config is None or getattr(colors_config, "sync_claude", True)
        ) and color is not None:
            context = self.claude_context.generate_context(worktree, color)
            self.claude_context.create_context_file(worktree.path, context)

    async def on_worktree_switched(self, event: Event) -> None:
        """Handle worktree switch."""
        worktree_data = event.data["worktree"]

        # Convert dictionary to proper object if needed
        from portal.core.domain.models import Worktree

        worktree = Worktree(**worktree_data) if isinstance(worktree_data, dict) else worktree_data

        # Update terminal title/badge
        if self.iterm_adapter.is_available():
            await self.iterm_adapter.set_badge(worktree.name)
        elif self.terminal_adapter.is_available():
            await self.terminal_adapter.set_title(f"Portal: {worktree.name}")

        # Open in editor if requested
        if event.data.get("open_editor", False):
            editor = event.data.get("editor", "cursor")

            if editor == "cursor" and self.cursor_adapter.is_available():
                await self.cursor_adapter.open_worktree(worktree.path)
            elif editor == "vscode" and self.vscode_adapter.is_available():
                await self.vscode_adapter.open_worktree(worktree.path)

    async def on_worktree_deleted(self, event: Event) -> None:
        """Handle worktree deletion."""
        worktree_data = event.data["worktree"]

        # Convert dictionary to proper object if needed
        from portal.core.domain.models import Worktree

        _worktree = Worktree(**worktree_data) if isinstance(worktree_data, dict) else worktree_data

        # For now, just a placeholder for cleanup tasks
        # Could add cleanup of dynamic profiles, context files, etc.
        # _worktree will be used when we implement cleanup logic
        pass

    def _is_iterm_available(self) -> bool:
        """Check if running in iTerm."""
        return self.iterm_adapter.is_available()

    def _is_terminal_available(self) -> bool:
        """Check if running in Terminal.app."""
        return self.terminal_adapter.is_available()
