"""Robust MCP Bridge Workbench - Initialization.

SPDX-License-Identifier: MIT
Copyright (c) 2025 Sean P. Kane (GitHub: spkane)

This module is executed when FreeCAD starts up. It handles initialization
tasks for the Robust MCP Bridge workbench, including auto-start of the
MCP bridge if configured. Works in both GUI and headless modes.

Note: Status bar updates are handled by InitGui.py since Qt operations
must run on the main thread.
"""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
    from freecad_mcp_bridge.bridge_utils import GuiWaiter

import FreeCAD

FreeCAD.Console.PrintMessage("Robust MCP Bridge: Init loaded\n")

# Global reference to GuiWaiter and auto-start timer to prevent garbage collection
# Type annotations use Any for timer since it could be QTimer from PySide2 or PySide6
_auto_start_timer: Any | None = None
_gui_waiter: GuiWaiter | None = None


def _auto_start_bridge() -> None:
    """Auto-start the MCP bridge if configured in preferences.

    This function is called via a deferred timer (GUI mode) or directly
    (headless mode) after FreeCAD finishes loading. It starts the bridge
    without requiring the workbench to be selected.
    """
    try:
        from preferences import get_auto_start

        if not get_auto_start():
            return

        # Check if bridge is already running
        from commands import _mcp_plugin

        if _mcp_plugin is not None and _mcp_plugin.is_running:
            return

        FreeCAD.Console.PrintMessage(
            "Auto-starting MCP Bridge (configured in preferences)...\n"
        )

        # Import and start the bridge directly
        from freecad_mcp_bridge.server import FreecadMCPPlugin
        from preferences import get_socket_port, get_xmlrpc_port

        xmlrpc_port = get_xmlrpc_port()
        socket_port = get_socket_port()

        plugin = FreecadMCPPlugin(
            host="localhost",
            port=socket_port,
            xmlrpc_port=xmlrpc_port,
            enable_xmlrpc=True,
        )
        plugin.start()

        # Register plugin with commands module for restart detection
        from freecad_mcp_bridge.bridge_utils import register_mcp_plugin

        register_mcp_plugin(plugin, xmlrpc_port, socket_port)

        FreeCAD.Console.PrintMessage("\n")
        FreeCAD.Console.PrintMessage("=" * 50 + "\n")
        FreeCAD.Console.PrintMessage("MCP Bridge started!\n")
        FreeCAD.Console.PrintMessage(f"  - XML-RPC: localhost:{xmlrpc_port}\n")
        FreeCAD.Console.PrintMessage(f"  - Socket:  localhost:{socket_port}\n")
        FreeCAD.Console.PrintMessage("=" * 50 + "\n")
        FreeCAD.Console.PrintMessage(
            "\nYou can now connect your MCP client (Claude Code, etc.) to FreeCAD.\n"
        )

    except Exception as e:
        FreeCAD.Console.PrintError(f"Failed to auto-start MCP Bridge: {e}\n")


# Schedule auto-start after FreeCAD finishes loading
# Strategy:
# - If FreeCAD.GuiUp is True: Qt event loop is running, use timer for deferred start
# - If FreeCAD.GuiUp is False but Qt is available: FreeCAD GUI is initializing.
#   Use GuiWaiter to wait for GuiUp to become True before starting.
#   This ensures the bridge uses Qt timer (not background thread) for queue processing.
# - If Qt is not available: Pure headless mode, start bridge directly
#
# CRITICAL: We must wait for FreeCAD.GuiUp to be True before starting the bridge
# in GUI mode. If we start when GuiUp is False, the bridge's _start_queue_processor()
# will see GuiUp=False and use a background thread. Later, code executed on that
# thread will try to do Qt operations, causing crashes (SIGABRT in QCocoaWindow).
try:
    from preferences import get_auto_start

    if get_auto_start():
        # Try to import Qt
        import contextlib

        QtCore = None
        try:
            from PySide2 import QtCore  # type: ignore[assignment, no-redef]
        except ImportError:
            with contextlib.suppress(ImportError):
                from PySide6 import QtCore  # type: ignore[assignment, no-redef]

        if FreeCAD.GuiUp:
            # GUI is already up - use timer for deferred start
            if QtCore is not None:
                _auto_start_timer = QtCore.QTimer()
                _auto_start_timer.setSingleShot(True)
                _auto_start_timer.timeout.connect(_auto_start_bridge)
                _auto_start_timer.start(1000)
            else:
                # GUI is up but Qt import failed - start directly
                _auto_start_bridge()
        elif QtCore is not None:
            # GUI not ready yet, but Qt is available (FreeCAD starting in GUI mode)
            # Use GuiWaiter to wait for GuiUp to become True before starting
            from freecad_mcp_bridge.bridge_utils import GuiWaiter

            _gui_waiter = GuiWaiter(
                callback=_auto_start_bridge,
                log_prefix="Robust MCP Bridge",
                timeout_error_extra=(
                    "\nTo start the bridge manually, select the Robust MCP Bridge "
                    "workbench\nand click 'Start MCP Bridge'.\n\n"
                ),
            )
            _gui_waiter.start()
        else:
            # True headless mode - no Qt, no GUI
            _auto_start_bridge()
except Exception as e:
    FreeCAD.Console.PrintWarning(f"Could not set up auto-start: {e}\n")
