"""Smriti CLI entry point.

Supports subcommands with aliases:
    sm create --tag dev
    sm a --target vajra
    sm cc --args "--resume"
"""

import sys

from vidhi import parse_cli_args

from . import __version__
from .claude_code import (
    auto_connect_cc,
    auto_connect_cc_dir,
    launch_cc,
    list_all_cc_sessions,
    list_cc_sessions_dir,
)
from .config import (
    CC_TAG,
    DEFAULT_TAG,
    Auto,
    AutoDir,
    Claude,
    ClaudeAuto,
    ClaudeAutoDir,
    ClaudeKill,
    ClaudeKillAll,
    ClaudeList,
    ClaudeListDir,
    ClaudeReattach,
    Create,
    Env,
    Kill,
    KillAll,
    KillLatest,
    ListAll,
    ListDir,
    Reattach,
    SmritiCommand,
)
from .env_detect import detect_env, print_env_info
from .naming import get_dir_pattern
from .session import (
    create_session,
    kill_session,
    list_sessions,
    reattach_session,
    screen_available,
)
from .utils import (
    exclude_cc_sessions,
    format_session_list,
    get_latest_from,
    log_error,
    pick_session,
)


def main() -> None:
    # Pre-flight
    if not screen_available():
        log_error("GNU Screen is not installed. Install it with: apt install screen")
        sys.exit(1)

    # Version flag
    if len(sys.argv) > 1 and sys.argv[1] in ("-V", "--version"):
        print(f"smriti v{__version__}")
        sys.exit(0)

    # Parse with Vidhi subcommands
    cmd = parse_cli_args(SmritiCommand)

    # Env detection (shared via base class field)
    env = None
    if not cmd.no_conda:
        env = detect_env()

    # Dispatch
    if isinstance(cmd, Create):
        if env and cmd.verbose:
            print_env_info(env)
        create_session(tag=cmd.tag, env=env)

    elif isinstance(cmd, AutoDir):
        pattern = get_dir_pattern()
        sessions = exclude_cc_sessions(list_sessions(pattern=pattern))
        latest = get_latest_from(sessions)
        if latest:
            reattach_session(latest["name"])
        else:
            create_session(tag=DEFAULT_TAG, env=env)

    elif isinstance(cmd, Auto):
        sessions = exclude_cc_sessions(list_sessions())
        if cmd.target:
            matches = [s for s in sessions if cmd.target in s["name"]]
            if len(matches) == 1:
                reattach_session(matches[0]["name"])
            elif len(matches) > 1:
                picked = pick_session(matches)
                if picked:
                    reattach_session(picked["name"])
            else:
                log_error(f"No session matching '{cmd.target}'.")
        else:
            latest = get_latest_from(sessions)
            if latest:
                reattach_session(latest["name"])
            else:
                create_session(tag=DEFAULT_TAG, env=env)

    elif isinstance(cmd, Reattach):
        sessions = exclude_cc_sessions(list_sessions())
        if not sessions:
            log_error("No sessions found.")
        elif len(sessions) == 1:
            reattach_session(sessions[0]["name"])
        else:
            picked = pick_session(sessions)
            if picked:
                reattach_session(picked["name"])

    elif isinstance(cmd, ListDir):
        pattern = get_dir_pattern()
        sessions = exclude_cc_sessions(list_sessions(pattern=pattern))
        format_session_list(sessions, f"Sessions in {pattern}", current_dir_pattern=pattern)

    elif isinstance(cmd, ListAll):
        sessions = exclude_cc_sessions(list_sessions())
        format_session_list(sessions, "All sessions", current_dir_pattern=get_dir_pattern())

    elif isinstance(cmd, Kill):
        sessions = exclude_cc_sessions(list_sessions(pattern=get_dir_pattern()))
        latest = get_latest_from(sessions)
        if latest:
            kill_session(latest["name"])
        else:
            log_error("No sessions to kill in this directory.")

    elif isinstance(cmd, KillLatest):
        sessions = exclude_cc_sessions(list_sessions())
        latest = get_latest_from(sessions)
        if latest:
            kill_session(latest["name"])
        else:
            log_error("No sessions to kill.")

    elif isinstance(cmd, KillAll):
        sessions = exclude_cc_sessions(list_sessions(pattern=get_dir_pattern()))
        if not sessions:
            log_error("No sessions to kill in this directory.")
        else:
            for s in sessions:
                kill_session(s["name"])

    elif isinstance(cmd, Claude):
        launch_cc(env=env, extra_args=cmd.args, config_dir=cmd.config_dir)

    elif isinstance(cmd, ClaudeAutoDir):
        auto_connect_cc_dir(env=env, config_dir=cmd.config_dir)

    elif isinstance(cmd, ClaudeAuto):
        auto_connect_cc(env=env, config_dir=cmd.config_dir)

    elif isinstance(cmd, ClaudeReattach):
        sessions = list_all_cc_sessions()
        if not sessions:
            log_error("No Claude Code sessions found.")
        elif len(sessions) == 1:
            reattach_session(sessions[0]["name"])
        else:
            picked = pick_session(sessions)
            if picked:
                reattach_session(picked["name"])

    elif isinstance(cmd, ClaudeListDir):
        sessions = list_cc_sessions_dir()
        format_session_list(
            sessions,
            "Claude Code sessions (current dir)",
            current_dir_pattern=get_dir_pattern(tag_filter=CC_TAG),
        )

    elif isinstance(cmd, ClaudeList):
        sessions = list_all_cc_sessions()
        format_session_list(
            sessions,
            "Claude Code sessions",
            current_dir_pattern=get_dir_pattern(tag_filter=CC_TAG),
        )

    elif isinstance(cmd, ClaudeKill):
        pattern = get_dir_pattern(tag_filter=CC_TAG)
        sessions = list_sessions(pattern=pattern)
        latest = get_latest_from(sessions)
        if latest:
            kill_session(latest["name"])
        else:
            log_error("No Claude Code sessions to kill in this directory.")

    elif isinstance(cmd, ClaudeKillAll):
        pattern = get_dir_pattern(tag_filter=CC_TAG)
        sessions = list_sessions(pattern=pattern)
        if not sessions:
            log_error("No Claude Code sessions to kill in this directory.")
        else:
            for s in sessions:
                kill_session(s["name"])

    elif isinstance(cmd, Env):
        print_env_info(env)


if __name__ == "__main__":
    main()
