import subprocess
import sys
import tempfile
from pathlib import Path
from unittest.mock import patch


def test_version():
    result = subprocess.run(
        [sys.executable, "-m", "skilark_cli.main", "--version"],
        capture_output=True,
        text=True,
    )
    assert result.returncode == 0
    assert "skilark" in result.stdout.lower()


def test_unknown_command_exits_nonzero():
    result = subprocess.run(
        [sys.executable, "-m", "skilark_cli.main", "notacommand"],
        capture_output=True,
        text=True,
    )
    assert result.returncode == 1
    assert "unknown command" in result.stderr.lower()


def test_today_dispatches_to_run():
    """main() routes `skilark today` to today.run() without error."""
    from skilark_cli.main import main

    with patch("skilark_cli.commands.today.run") as mock_run:
        with patch.object(sys, "argv", ["skilark", "today"]):
            main()

    mock_run.assert_called_once()


def test_no_args_first_run_skips_menu():
    """First run (no config) bypasses menu and goes straight to onboarding."""
    from skilark_cli.main import main

    with (
        patch("skilark_cli.config_store.ConfigStore.is_first_run", return_value=True),
        patch("skilark_cli.commands.today.run") as mock_run,
        patch.object(sys, "argv", ["skilark"]),
    ):
        main()

    mock_run.assert_called_once()


def test_no_args_menu_dispatches_status():
    """Bare `skilark` → menu → 'status' dispatches to status.run()."""
    from skilark_cli.main import main

    with (
        patch("skilark_cli.config_store.ConfigStore.is_first_run", return_value=False),
        patch("skilark_cli.main._show_menu", return_value="status") as mock_menu,
        patch("skilark_cli.commands.status.run") as mock_status,
        patch.object(sys, "argv", ["skilark"]),
    ):
        main()

    mock_menu.assert_called_once()
    mock_status.assert_called_once()


def test_no_args_menu_dispatches_signals():
    """Bare `skilark` → menu → 'signals' dispatches to signals.dispatch([])."""
    from skilark_cli.main import main

    with (
        patch("skilark_cli.config_store.ConfigStore.is_first_run", return_value=False),
        patch("skilark_cli.main._show_menu", return_value="signals"),
        patch("skilark_cli.commands.signals.dispatch") as mock_dispatch,
        patch.object(sys, "argv", ["skilark"]),
    ):
        main()

    mock_dispatch.assert_called_once_with([])


def test_no_args_menu_fit_prompts_for_query():
    """Bare `skilark` → menu → 'fit' prompts for a query, then dispatches."""
    from skilark_cli.main import main

    with (
        patch("skilark_cli.config_store.ConfigStore.is_first_run", return_value=False),
        patch("skilark_cli.main._show_menu", return_value="fit"),
        patch("skilark_cli.main._prompt_fit_query", return_value="backend python") as mock_prompt,
        patch("skilark_cli.commands.fit.dispatch") as mock_dispatch,
        patch.object(sys, "argv", ["skilark"]),
    ):
        main()

    mock_prompt.assert_called_once()
    mock_dispatch.assert_called_once_with(["backend python"])


def test_no_args_menu_fit_empty_query_exits(capsys):
    """Bare `skilark` → menu → 'fit' → empty query prints message, does not dispatch."""
    from skilark_cli.main import main

    with (
        patch("skilark_cli.config_store.ConfigStore.is_first_run", return_value=False),
        patch("skilark_cli.main._show_menu", return_value="fit"),
        patch("skilark_cli.main._prompt_fit_query", return_value=None),
        patch("skilark_cli.commands.fit.dispatch") as mock_dispatch,
        patch.object(sys, "argv", ["skilark"]),
    ):
        main()

    mock_dispatch.assert_not_called()
    assert "no query" in capsys.readouterr().out.lower()


def test_status_first_run_message():
    """status exits cleanly with a setup hint when no config file exists.

    Uses a temp directory inside Path.home() to satisfy the SKILARK_CONFIG_DIR
    path-traversal guard, which rejects paths outside the user's home directory.
    """
    with tempfile.TemporaryDirectory(dir=Path.home()) as tmp:
        env = {**subprocess.os.environ, "SKILARK_CONFIG_DIR": tmp}
        result = subprocess.run(
            [sys.executable, "-m", "skilark_cli.main", "status"],
            capture_output=True,
            text=True,
            env=env,
        )
    assert result.returncode == 0
    assert "skilark today" in result.stdout.lower()


def test_config_first_run_message():
    """config exits cleanly with a setup hint when no config file exists.

    Uses a temp directory inside Path.home() to satisfy the SKILARK_CONFIG_DIR
    path-traversal guard, which rejects paths outside the user's home directory.
    """
    with tempfile.TemporaryDirectory(dir=Path.home()) as tmp:
        env = {**subprocess.os.environ, "SKILARK_CONFIG_DIR": tmp}
        result = subprocess.run(
            [sys.executable, "-m", "skilark_cli.main", "config"],
            capture_output=True,
            text=True,
            env=env,
        )
    assert result.returncode == 0
    assert "skilark today" in result.stdout.lower()
