"""Integration tests for the CLI."""

import os
import tempfile
from pathlib import Path

import pytest
from click.testing import CliRunner

from agentreflect.cli import cli


@pytest.fixture
def runner():
    return CliRunner()


@pytest.fixture
def sample_failures_path():
    return str(Path(__file__).parent / "fixtures" / "sample-failures.txt")


@pytest.fixture
def sample_agents_path():
    return str(Path(__file__).parent / "fixtures" / "sample-agents.md")


class TestCLI:
    def test_version(self, runner):
        result = runner.invoke(cli, ["--version"])
        assert result.exit_code == 0
        assert "0.3.0" in result.output

    def test_help(self, runner):
        result = runner.invoke(cli, ["--help"])
        assert result.exit_code == 0
        assert "agentreflect" in result.output

    def test_generate_help(self, runner):
        result = runner.invoke(cli, ["generate", "--help"])
        assert result.exit_code == 0
        assert "--from-pytest" in result.output
        assert "--from-git" in result.output
        assert "--from-notes" in result.output

    def test_generate_requires_input(self, runner):
        result = runner.invoke(cli, ["generate"])
        assert result.exit_code != 0

    def test_generate_from_notes_produces_output(self, runner):
        result = runner.invoke(cli, ["generate", "--from-notes", "agent forgot to check for None"])
        assert result.exit_code == 0
        assert len(result.output) > 0
        assert "agentreflect suggestions" in result.output

    def test_generate_from_pytest_file(self, runner, sample_failures_path):
        result = runner.invoke(cli, ["generate", "--from-pytest", sample_failures_path])
        assert result.exit_code == 0
        assert "agentreflect suggestions" in result.output

    def test_generate_from_pytest_produces_at_least_one_suggestion(self, runner, sample_failures_path):
        result = runner.invoke(cli, ["generate", "--from-pytest", sample_failures_path])
        assert result.exit_code == 0
        assert "- [ ]" in result.output

    def test_generate_from_notes_produces_at_least_one_suggestion(self, runner):
        result = runner.invoke(cli, ["generate", "--from-notes", "agent used wrong variable name"])
        assert result.exit_code == 0
        assert "- [ ]" in result.output

    def test_generate_from_git_does_not_crash(self, runner):
        # Even in a dir with no relevant commits
        result = runner.invoke(cli, ["generate", "--from-git"])
        # May produce no commits found but should not error fatally
        assert result.exit_code == 0 or "No fix" in result.output

    def test_generate_diff_format(self, runner):
        result = runner.invoke(
            cli,
            ["generate", "--from-notes", "agent made a mistake", "--format", "diff"],
        )
        assert result.exit_code == 0
        assert "---" in result.output or "+++" in result.output

    def test_generate_apply_creates_file(self, runner, tmp_path):
        agents_file = str(tmp_path / "AGENTS.md")
        result = runner.invoke(
            cli,
            [
                "generate",
                "--from-notes", "agent used wrong variable",
                "--apply", agents_file,
                "--yes",
            ],
        )
        assert result.exit_code == 0
        assert Path(agents_file).exists()
        content = Path(agents_file).read_text()
        assert "Learned Rules" in content

    def test_generate_apply_modifies_existing_file(self, runner, sample_agents_path, tmp_path):
        # Copy fixture to tmp
        target = tmp_path / "agents.md"
        target.write_text(Path(sample_agents_path).read_text())
        result = runner.invoke(
            cli,
            [
                "generate",
                "--from-notes", "agent uses wrong variable",
                "--apply", str(target),
                "--yes",
            ],
        )
        assert result.exit_code == 0
        content = target.read_text()
        # Original content preserved
        assert "General Rules" in content
        # New content added
        assert "Learned Rules" in content

    def test_generate_from_notes_none_suggestion(self, runner):
        result = runner.invoke(
            cli,
            ["generate", "--from-notes", "the agent did not check for None and got AttributeError"],
        )
        assert result.exit_code == 0
        output_lower = result.output.lower()
        assert "none" in output_lower or "attribute" in output_lower

    def test_llm_flag_without_key_falls_back(self, runner, monkeypatch):
        monkeypatch.delenv("ANTHROPIC_API_KEY", raising=False)
        result = runner.invoke(
            cli,
            ["generate", "--from-notes", "test failure", "--llm"],
        )
        # Should fall back to pattern mode, not crash
        assert result.exit_code == 0 or "fallback" in result.output.lower() or "error" in result.output.lower()

    def test_min_confidence_filter(self, runner):
        result = runner.invoke(
            cli,
            ["generate", "--from-notes", "agent error", "--min-confidence", "0.95"],
        )
        # Should run without error (may produce 0 suggestions for very high threshold)
        assert result.exit_code == 0
