"""Tests for gwtm.cli — Typer commands with CliRunner."""

from pathlib import Path

import pytest
from typer.testing import CliRunner

from gwtm.cli import app


runner = CliRunner()


class TestVersion:
    def test_version_flag(self) -> None:
        result = runner.invoke(app, ["--version"])
        assert result.exit_code == 0
        assert "gwtm 0.1.0" in result.output

    def test_help(self) -> None:
        result = runner.invoke(app, ["--help"])
        assert result.exit_code == 0
        assert "Git Worktree Manager" in result.output


class TestNewCommand:
    def test_new_creates_worktree(
        self, managed_repo: Path, monkeypatch: pytest.MonkeyPatch,
    ) -> None:
        monkeypatch.chdir(managed_repo)
        result = runner.invoke(app, ["new", "test-feat"])
        assert result.exit_code == 0
        assert "test-feat" in result.output

    def test_new_invalid_name(
        self, managed_repo: Path, monkeypatch: pytest.MonkeyPatch,
    ) -> None:
        monkeypatch.chdir(managed_repo)
        result = runner.invoke(app, ["new", "bad/name"])
        assert result.exit_code == 1


class TestLsCommand:
    def test_ls_shows_table(
        self, managed_repo: Path, monkeypatch: pytest.MonkeyPatch,
    ) -> None:
        monkeypatch.chdir(managed_repo)
        result = runner.invoke(app, ["ls"])
        assert result.exit_code == 0

    def test_ls_names_only(
        self, managed_repo: Path, monkeypatch: pytest.MonkeyPatch,
    ) -> None:
        monkeypatch.chdir(managed_repo)
        # First create a worktree
        runner.invoke(app, ["new", "names-only-test"])

        result = runner.invoke(app, ["ls", "--names-only"])
        assert result.exit_code == 0
        assert "names-only-test" in result.output


class TestRmCommand:
    def test_rm_removes_worktree(
        self, managed_repo: Path, monkeypatch: pytest.MonkeyPatch,
    ) -> None:
        monkeypatch.chdir(managed_repo)
        runner.invoke(app, ["new", "to-rm-cli"])

        result = runner.invoke(app, ["rm", "to-rm-cli"])
        assert result.exit_code == 0
        assert "Removed" in result.output

    def test_rm_nonexistent(
        self, managed_repo: Path, monkeypatch: pytest.MonkeyPatch,
    ) -> None:
        monkeypatch.chdir(managed_repo)
        result = runner.invoke(app, ["rm", "nope"])
        assert result.exit_code == 1


class TestNewCommandCarry:
    def test_carry_flag(
        self, managed_repo: Path, monkeypatch: pytest.MonkeyPatch,
    ) -> None:
        monkeypatch.chdir(managed_repo)
        (managed_repo / ".ai").mkdir()
        (managed_repo / ".ai" / "notes.md").write_text("context")

        result = runner.invoke(app, ["new", "carry-cli", "--carry", ".ai/"])
        assert result.exit_code == 0
        assert "1 item(s)" in result.output

    def test_carry_changes_flag(
        self, managed_repo: Path, monkeypatch: pytest.MonkeyPatch,
    ) -> None:
        monkeypatch.chdir(managed_repo)
        (managed_repo / "README.md").write_text("wip\n")

        result = runner.invoke(app, ["new", "carry-ch-cli", "--carry-changes"])
        assert result.exit_code == 0
        assert "changes applied" in result.output

    def test_no_carry_flag(
        self, managed_repo: Path, monkeypatch: pytest.MonkeyPatch,
    ) -> None:
        monkeypatch.chdir(managed_repo)
        result = runner.invoke(app, ["new", "no-carry-cli", "--no-carry"])
        assert result.exit_code == 0
        # Should not show carry info
        assert "Carried" not in result.output


class TestPathCommand:
    def test_path_main(
        self, managed_repo: Path, monkeypatch: pytest.MonkeyPatch,
    ) -> None:
        monkeypatch.chdir(managed_repo)
        result = runner.invoke(app, ["path", "main"])
        assert result.exit_code == 0
        assert str(managed_repo) in result.output

    def test_path_worktree(
        self, managed_repo: Path, monkeypatch: pytest.MonkeyPatch,
    ) -> None:
        monkeypatch.chdir(managed_repo)
        runner.invoke(app, ["new", "path-test"])

        result = runner.invoke(app, ["path", "path-test"])
        assert result.exit_code == 0
        assert "path-test" in result.output
