"""Integration tests for CLI commands using Click's CliRunner."""

import json
from click.testing import CliRunner
from pjctx.cli import cli
from pjctx.core.config import get_pjctx_dir, save_config, DEFAULT_CONFIG
from pjctx.core.context import Context
from pjctx.core.storage import save_context


def test_version():
    runner = CliRunner()
    result = runner.invoke(cli, ["--version"])
    assert result.exit_code == 0
    assert "0.1.0" in result.output


def test_init(tmp_git_repo):
    runner = CliRunner()
    result = runner.invoke(cli, ["init"])
    assert result.exit_code == 0
    assert (tmp_git_repo / ".pjctx" / "config.json").exists()
    assert (tmp_git_repo / ".pjctx" / "contexts").is_dir()


def test_init_twice(tmp_git_repo):
    runner = CliRunner()
    runner.invoke(cli, ["init"])
    result = runner.invoke(cli, ["init"])
    assert result.exit_code == 0
    assert "already exists" in result.output


def test_save_quick(initialized_repo):
    runner = CliRunner()
    result = runner.invoke(cli, ["save", "Quick test message"])
    assert result.exit_code == 0
    assert "Context saved" in result.output

    # Verify file was created
    ctx_dir = initialized_repo / ".pjctx" / "contexts"
    json_files = list(ctx_dir.rglob("*.json"))
    assert len(json_files) >= 1


def test_save_auto(initialized_repo):
    runner = CliRunner()
    result = runner.invoke(cli, ["save", "--auto"])
    assert result.exit_code == 0
    assert "Context saved" in result.output


def test_save_with_tags(initialized_repo):
    runner = CliRunner()
    result = runner.invoke(cli, ["save", "tagged", "-t", "bug", "-t", "urgent"])
    assert result.exit_code == 0

    from pjctx.core.git_ops import get_current_branch
    from pjctx.core.storage import load_latest
    branch = get_current_branch(initialized_repo)
    ctx = load_latest(initialized_repo, branch)
    assert "bug" in ctx.tags
    assert "urgent" in ctx.tags


def test_resume_no_context(initialized_repo):
    runner = CliRunner()
    result = runner.invoke(cli, ["resume", "--no-copy"])
    assert result.exit_code != 0
    assert "No context found" in result.output


def test_resume_with_context(initialized_repo):
    # Save a context first
    from pjctx.core.git_ops import get_current_branch
    branch = get_current_branch(initialized_repo)
    ctx = Context(message="test resume", branch=branch, task="testing")
    save_context(initialized_repo, ctx)

    runner = CliRunner()
    result = runner.invoke(cli, ["resume", "--no-copy"])
    assert result.exit_code == 0
    assert "test resume" in result.output


def test_resume_xml_format(initialized_repo):
    from pjctx.core.git_ops import get_current_branch
    branch = get_current_branch(initialized_repo)
    ctx = Context(message="xml test", branch=branch)
    save_context(initialized_repo, ctx)

    runner = CliRunner()
    result = runner.invoke(cli, ["resume", "--no-copy", "-f", "xml"])
    assert result.exit_code == 0
    assert "<context>" in result.output


def test_log_empty(initialized_repo):
    runner = CliRunner()
    result = runner.invoke(cli, ["log"])
    assert result.exit_code == 0
    assert "No contexts" in result.output


def test_log_with_entries(initialized_repo):
    from pjctx.core.git_ops import get_current_branch
    branch = get_current_branch(initialized_repo)
    for i in range(3):
        save_context(initialized_repo, Context(message=f"entry {i}", branch=branch))

    runner = CliRunner()
    result = runner.invoke(cli, ["log"])
    assert result.exit_code == 0
    assert "entry 0" in result.output
    assert "entry 2" in result.output


def test_diff_command(initialized_repo):
    runner = CliRunner()
    result = runner.invoke(cli, ["diff"])
    assert result.exit_code == 0


def test_hook_status(initialized_repo):
    runner = CliRunner()
    result = runner.invoke(cli, ["hook", "status"])
    assert result.exit_code == 0
    assert "not installed" in result.output


def test_hook_install_and_uninstall(initialized_repo):
    runner = CliRunner()

    result = runner.invoke(cli, ["hook", "install"])
    assert result.exit_code == 0
    assert "installed" in result.output

    result = runner.invoke(cli, ["hook", "status"])
    assert "installed" in result.output

    result = runner.invoke(cli, ["hook", "uninstall"])
    assert result.exit_code == 0

    result = runner.invoke(cli, ["hook", "status"])
    assert "not installed" in result.output
