"""
MUMLA CLI - Shared utilities, app instances, and helpers.

All command modules import from here to avoid circular dependencies.
"""

import os
from datetime import datetime

import jwt
import typer
from rich.console import Console
from rich.panel import Panel

# Re-export temporal helpers
from app.utils.temporal_helpers import (  # noqa: F401
    format_current_local_time,
    format_local_time,
    parse_relative_time,
)
from cli.client.api_client import MumlaAPIClient  # noqa: F401
from cli.client.direct_client import DirectClient
from cli.config.manager import ConfigManager

# Re-export connect utilities
from cli.connect.agent_registry import (  # noqa: F401
    AGENT_REGISTRY,
    detect_agents_in_project,
    detect_mumla_installed,
    detect_mumla_installed_global,
    list_agents,
)
from cli.connect.engine import install_agent, remove_agent  # noqa: F401

# Re-export display functions
from cli.ui.display import print_logo, show_welcome_banner  # noqa: F401

# Re-export theme constants for all command modules
from cli.ui.theme import (  # noqa: F401
    ACCENT,
    BOLD_BRIGHT,
    BOLD_PRIMARY,
    BRIGHT,
    DIM,
    ERROR,
    PRIMARY,
    SUCCESS,
    WARNING,
)

# Initialize Typer app and console
app = typer.Typer(
    name="mumla",
    help="MUMLA CLI - Moorcheh Universal Memory Layer for Agentic AI",
    add_completion=False,
)
console = Console()
config_manager = ConfigManager()

# Create subcommands
agent_app = typer.Typer(help="Agent management commands")
session_app = typer.Typer(help="Session management commands")
config_app = typer.Typer(help="Configuration commands")
schedule_app = typer.Typer(help="Daily summary scheduling commands")
memory_app = typer.Typer(help="Memory management commands")
connect_app = typer.Typer(help="Connect MUMLA to external tools")

app.add_typer(agent_app, name="agent")
app.add_typer(session_app, name="session")
app.add_typer(config_app, name="config")
app.add_typer(schedule_app, name="schedule")
app.add_typer(memory_app, name="memory")
app.add_typer(connect_app, name="connect")


def _error(message: str, hint: str = None) -> None:
    """Print a consistent red error Panel and exit."""
    body = message
    if hint:
        body += f"\n[dim]{hint}[/dim]"
    console.print(Panel(body, title="Error", border_style="red"))
    raise typer.Exit(1)


def _warn(message: str) -> None:
    """Print a non-fatal warning."""
    console.print(f"[yellow]Warning:[/yellow] {message}")


def get_client() -> DirectClient:
    """Get configured direct client or exit if not initialized."""
    api_key = config_manager.get_api_key()

    if not api_key:
        _error("MUMLA not configured.", hint="Run 'mumla' to set up your API key.")

    # Ensure env is set for app services
    os.environ["MOORCHEH_API_KEY"] = api_key

    client = DirectClient(api_key)

    # Restore active session if available
    active_agent_id, active_session_token = config_manager.get_active_session()
    session_cfg = config_manager.get_session_config()

    if active_session_token and active_agent_id:
        client.session_token = active_session_token
        client.agent_id = active_agent_id

        # Check if the token is completely expired, and auto-renew if enabled
        if session_cfg.get("auto_renew_enabled", True):
            try:
                payload = jwt.decode(
                    active_session_token, options={"verify_signature": False}
                )
                expires_at_str = payload.get("expires_at", "")
                if expires_at_str.endswith("Z"):
                    expires_at_str = expires_at_str[:-1]

                if expires_at_str:
                    expires_at = datetime.fromisoformat(expires_at_str)

                    if datetime.utcnow() > expires_at:
                        # Silently revive the session
                        new_data = client.activate_agent(active_agent_id)
                        client.session_token = new_data["session_token"]
                        config_manager.set_active_session(
                            active_agent_id, client.session_token
                        )
            except Exception:
                pass  # Fall back to letting the underlying request fail if something is malformed

    return client
