"""Echo Core message router — routes messages to Claude or commands."""

import logging
from src.config import Config
from src.claude_session import (
    send_message,
    clear_session,
    get_active_session,
    list_sessions,
    set_session_model,
    VALID_MODELS,
)

log = logging.getLogger(__name__)

# Module-level config instance (lazy singleton)
_config: Config | None = None


def _get_config() -> Config:
    """Return the module-level config, creating it on first access."""
    global _config
    if _config is None:
        _config = Config()
    return _config


def route_message(channel_id: str, user_id: str, text: str, model: str | None = None) -> tuple[str, bool]:
    """Route an incoming message. Returns (response_text, is_command).

    If text starts with / it's a command (handled here for text-based commands).
    Otherwise it goes to Claude via send_message (auto start/resume).
    """
    text = text.strip()

    # Text-based commands (not slash commands — these work in any adapter)
    if text.lower() == "/clear":
        default_model = _get_config().get("bot.default_model", "sonnet")
        cleared = clear_session(channel_id)
        if cleared:
            return f"Session cleared. Model reset to {default_model}.", True
        return "No active session.", True

    if text.lower() == "/status":
        return _status(channel_id), True

    if text.lower().startswith("/model"):
        return _model_command(channel_id, text), True

    if text.startswith("/"):
        return f"Unknown command: {text.split()[0]}", True

    # Regular message → Claude
    if not model:
        # Check session model first, then channel default, then global default
        session = get_active_session(channel_id)
        if session and session.get("model"):
            model = session["model"]
        else:
            channel_cfg = _get_channel_config(channel_id)
            model = (channel_cfg or {}).get("default_model") or _get_config().get("bot.default_model", "sonnet")

    try:
        response = send_message(channel_id, text, model=model)
        return response, False
    except Exception as e:
        log.error("Claude error for channel %s: %s", channel_id, e)
        return f"Error: {e}", False


def _status(channel_id: str) -> str:
    """Build status message for a channel."""
    session = get_active_session(channel_id)
    if not session:
        return "No active session."

    model = session.get("model", "unknown")
    sid = session.get("session_id", "unknown")[:12]
    count = session.get("message_count", 0)

    return f"Model: {model} | Session: {sid}... | Messages: {count}"


def _model_command(channel_id: str, text: str) -> str:
    """Handle /model [choice] text command."""
    parts = text.strip().split()
    if len(parts) == 1:
        # /model — show current
        session = get_active_session(channel_id)
        if session:
            current = session.get("model", "unknown")
        else:
            channel_cfg = _get_channel_config(channel_id)
            current = (channel_cfg or {}).get("default_model") or _get_config().get("bot.default_model", "sonnet")
        available = ", ".join(sorted(VALID_MODELS))
        return f"Current model: {current}\nAvailable: {available}"

    choice = parts[1].lower()
    if choice not in VALID_MODELS:
        return f"Invalid model '{choice}'. Choose from: {', '.join(sorted(VALID_MODELS))}"

    session = get_active_session(channel_id)
    if session:
        set_session_model(channel_id, choice)
    else:
        # Pre-set for next message
        from src.claude_session import _load_sessions, _save_sessions
        from datetime import datetime, timezone
        sessions = _load_sessions()
        sessions[channel_id] = {
            "session_id": "",
            "model": choice,
            "created_at": datetime.now(timezone.utc).isoformat(),
            "last_message_at": datetime.now(timezone.utc).isoformat(),
            "message_count": 0,
        }
        _save_sessions(sessions)
    return f"Model changed to {choice}."


def _get_channel_config(channel_id: str) -> dict | None:
    """Find channel config by ID."""
    channels = _get_config().get("channels", {})
    for alias, ch in channels.items():
        if ch.get("id") == channel_id:
            return ch
    return None
