"""Unit tests for CLI telemetry commands."""

from __future__ import annotations

from typing import TYPE_CHECKING
from unittest.mock import MagicMock, patch

import pytest
from click.testing import CliRunner

if TYPE_CHECKING:
    from collections.abc import Generator

from augint_library.cli import cli


@pytest.fixture
def runner() -> CliRunner:
    """Create a Click test runner."""
    return CliRunner()


@pytest.fixture
def mock_telemetry_client() -> Generator[MagicMock, None, None]:
    """Mock telemetry client for tests."""
    mock_client = MagicMock()
    mock_client.enabled = False
    mock_client._get_anonymous_id.return_value = "test-uuid-1234"

    with patch("augint_library.cli.get_telemetry_client", return_value=mock_client):
        yield mock_client


class TestTelemetryCommands:
    """Test CLI telemetry commands."""

    def test_telemetry_status_disabled(
        self, runner: CliRunner, mock_telemetry_client: MagicMock
    ) -> None:
        """Test telemetry status when disabled."""
        mock_telemetry_client.enabled = False

        result = runner.invoke(cli, ["telemetry", "status"])

        assert result.exit_code == 0
        assert "Enabled: No" in result.output
        assert "Telemetry is disabled" in result.output
        assert "ai-test-script telemetry enable" in result.output

    def test_telemetry_status_enabled(
        self, runner: CliRunner, mock_telemetry_client: MagicMock
    ) -> None:
        """Test telemetry status when enabled."""
        mock_telemetry_client.enabled = True

        result = runner.invoke(cli, ["telemetry", "status"])

        assert result.exit_code == 0
        assert "Enabled: Yes" in result.output
        assert "Anonymous ID: test-uuid-1234" in result.output
        assert "Data collected:" in result.output
        assert "Command usage" in result.output
        assert "Data NOT collected:" in result.output
        assert "Personal information" in result.output

    def test_telemetry_enable_already_enabled(
        self, runner: CliRunner, mock_telemetry_client: MagicMock
    ) -> None:
        """Test enabling when already enabled."""
        mock_telemetry_client.enabled = True

        result = runner.invoke(cli, ["telemetry", "enable"])

        assert result.exit_code == 0
        assert "Telemetry is already enabled" in result.output
        mock_telemetry_client.set_consent.assert_not_called()

    def test_telemetry_enable_with_prompt_yes(
        self, runner: CliRunner, mock_telemetry_client: MagicMock
    ) -> None:
        """Test enabling with confirmation prompt."""
        mock_telemetry_client.enabled = False

        result = runner.invoke(cli, ["telemetry", "enable"], input="y\n")

        assert result.exit_code == 0
        assert "Help improve augint-library" in result.output
        assert "What we collect:" in result.output
        assert "What we DON'T collect:" in result.output
        assert "✓ Telemetry enabled" in result.output

        mock_telemetry_client.set_consent.assert_called_once_with(enabled=True)

    def test_telemetry_enable_with_prompt_no(
        self, runner: CliRunner, mock_telemetry_client: MagicMock
    ) -> None:
        """Test declining telemetry enable."""
        mock_telemetry_client.enabled = False

        result = runner.invoke(cli, ["telemetry", "enable"], input="n\n")

        assert result.exit_code == 0
        assert "Telemetry remains disabled" in result.output
        mock_telemetry_client.set_consent.assert_not_called()

    def test_telemetry_enable_skip_prompt(
        self, runner: CliRunner, mock_telemetry_client: MagicMock
    ) -> None:
        """Test enabling with --yes flag."""
        mock_telemetry_client.enabled = False

        result = runner.invoke(cli, ["telemetry", "enable", "--yes"])

        assert result.exit_code == 0
        assert "✓ Telemetry enabled" in result.output
        # Should not show the detailed prompt
        assert "What we collect:" not in result.output

        mock_telemetry_client.set_consent.assert_called_once_with(enabled=True)

    def test_telemetry_disable_already_disabled(
        self, runner: CliRunner, mock_telemetry_client: MagicMock
    ) -> None:
        """Test disabling when already disabled."""
        mock_telemetry_client.enabled = False

        result = runner.invoke(cli, ["telemetry", "disable"])

        assert result.exit_code == 0
        assert "Telemetry is already disabled" in result.output
        mock_telemetry_client.set_consent.assert_not_called()

    def test_telemetry_disable(self, runner: CliRunner, mock_telemetry_client: MagicMock) -> None:
        """Test disabling telemetry."""
        mock_telemetry_client.enabled = True

        result = runner.invoke(cli, ["telemetry", "disable"])

        assert result.exit_code == 0
        assert "✓ Telemetry disabled" in result.output
        assert "anonymous ID has been preserved" in result.output

        mock_telemetry_client.set_consent.assert_called_once_with(enabled=False)

    def test_telemetry_test_disabled(
        self, runner: CliRunner, mock_telemetry_client: MagicMock
    ) -> None:
        """Test telemetry test command when disabled."""
        mock_telemetry_client.enabled = False

        result = runner.invoke(cli, ["telemetry", "test"])

        assert result.exit_code == 0
        assert "Telemetry is disabled" in result.output
        assert "ai-test-script telemetry enable" in result.output

        # Should not track anything
        mock_telemetry_client.track_command.assert_not_called()
        mock_telemetry_client.track_metric.assert_not_called()
        mock_telemetry_client.track_error.assert_not_called()

    def test_telemetry_test_enabled(
        self, runner: CliRunner, mock_telemetry_client: MagicMock
    ) -> None:
        """Test telemetry test command when enabled."""
        mock_telemetry_client.enabled = True

        result = runner.invoke(cli, ["telemetry", "test"])

        assert result.exit_code == 0
        assert "Sending test telemetry event" in result.output
        assert "✓ Test events sent successfully" in result.output
        assert "Check your Sentry dashboard" in result.output

        # Verify tracking calls
        mock_telemetry_client.track_command.assert_called_once_with(
            "telemetry_test", success=True, duration=0.1
        )
        mock_telemetry_client.track_metric.assert_called_once_with(
            "test_metric", 42.0, unit="test", tags={"type": "verification"}
        )
        mock_telemetry_client.track_error.assert_called_once()
        mock_telemetry_client.flush.assert_called_once()

    def test_telemetry_group_help(self, runner: CliRunner) -> None:
        """Test telemetry group help text."""
        result = runner.invoke(cli, ["telemetry", "--help"])

        assert result.exit_code == 0
        assert "Manage anonymous usage telemetry settings" in result.output
        assert "status" in result.output
        assert "enable" in result.output
        assert "disable" in result.output
        assert "test" in result.output


class TestCommandTracking:
    """Test command execution tracking."""

    def test_greet_command_tracked(
        self, runner: CliRunner, mock_telemetry_client: MagicMock
    ) -> None:
        """Test greet command is tracked."""
        mock_telemetry_client.enabled = True

        # Mock the telemetry decorator's get_telemetry_client
        with patch(
            "augint_library.telemetry.get_telemetry_client",
            return_value=mock_telemetry_client,
        ):
            result = runner.invoke(cli, ["greet", "World"])

            assert result.exit_code == 0
            assert "Hi World" in result.output

            # Verify command was tracked
            mock_telemetry_client.track_command.assert_called()
            call_args = mock_telemetry_client.track_command.call_args
            assert call_args[0][0] == "greet"
            assert call_args[1]["success"] is True
            assert "duration" in call_args[1]
