"""Tests for CLI dashboard project-configure command."""

from __future__ import annotations

from unittest.mock import MagicMock, patch

import pytest
from typer.testing import CliRunner

from complyform.cli.dashboard_cmd import dashboard_app

runner = CliRunner()

_P_RESOLVE_KEY = "complyform.cli.dashboard_cmd._resolve_api_key"


class TestDashboardConfigureCmd:
    """CLI project-configure subcommand tests."""

    def test_configure_scheduled_mode(self) -> None:
        mock_resp = MagicMock()
        mock_resp.status_code = 200
        mock_resp.json.return_value = {
            "project_id": "prod",
            "drift_mode": "scheduled",
            "drift_alerts": True,
            "setup_instructions": None,
            "webhook_secret": None,
        }

        with (
            patch(_P_RESOLVE_KEY, return_value="test-key"),
            patch("httpx.post", return_value=mock_resp),
        ):
            result = runner.invoke(
                dashboard_app,
                [
                    "project-configure",
                    "--project-label=prod",
                    "--drift-mode=scheduled",
                    "--drift-alerts=on",
                ],
            )
            assert result.exit_code == 0
            assert "configured" in result.output

    def test_configure_event_driven_prints_secret(self) -> None:
        mock_resp = MagicMock()
        mock_resp.status_code = 200
        mock_resp.json.return_value = {
            "project_id": "prod",
            "drift_mode": "event_driven",
            "drift_alerts": True,
            "setup_instructions": {
                "cloud": "gcp",
                "webhook_url": "https://api.complyform.dev/v1/drift/event",
                "terraform_module_url": "https://complyform.dev/docs/drift-setup/gcp/",
                "variables": {"project_id": "my-proj"},
                "quickstart": "1. Download\n2. Configure\n3. Apply",
            },
            "webhook_secret": "cf_drift_abc123def456",
        }

        with (
            patch(_P_RESOLVE_KEY, return_value="test-key"),
            patch("httpx.post", return_value=mock_resp),
        ):
            result = runner.invoke(
                dashboard_app,
                [
                    "project-configure",
                    "--project-label=prod",
                    "--drift-mode=event_driven",
                ],
            )
            assert result.exit_code == 0
            assert "cf_drift_abc123def456" in result.output

    def test_configure_missing_project_label_fails(self) -> None:
        result = runner.invoke(
            dashboard_app,
            ["project-configure"],
        )
        assert result.exit_code != 0

    def test_configure_missing_api_key_fails(self) -> None:
        with patch(
            _P_RESOLVE_KEY,
            side_effect=Exception("No API key"),
        ):
            result = runner.invoke(
                dashboard_app,
                [
                    "project-configure",
                    "--project-label=prod",
                    "--drift-alerts=on",
                ],
            )
            assert result.exit_code != 0

    @pytest.mark.parametrize(
        "value,expected_exit",
        [("on", 0), ("off", 0)],
    )
    def test_drift_alerts_on_off_parsing(self, value: str, expected_exit: int) -> None:
        mock_resp = MagicMock()
        mock_resp.status_code = 200
        mock_resp.json.return_value = {
            "project_id": "prod",
            "drift_mode": "scheduled",
            "drift_alerts": value == "on",
            "setup_instructions": None,
            "webhook_secret": None,
        }

        with (
            patch(_P_RESOLVE_KEY, return_value="test-key"),
            patch("httpx.post", return_value=mock_resp),
        ):
            result = runner.invoke(
                dashboard_app,
                [
                    "project-configure",
                    "--project-label=prod",
                    f"--drift-alerts={value}",
                ],
            )
            assert result.exit_code == expected_exit

    def test_invalid_drift_mode_fails(self) -> None:
        with patch(_P_RESOLVE_KEY, return_value="test-key"):
            result = runner.invoke(
                dashboard_app,
                [
                    "project-configure",
                    "--project-label=prod",
                    "--drift-mode=invalid",
                ],
            )
            assert result.exit_code != 0

    def test_drift_alerts_invalid_value_fails(self) -> None:
        with patch(_P_RESOLVE_KEY, return_value="test-key"):
            result = runner.invoke(
                dashboard_app,
                [
                    "project-configure",
                    "--project-label=prod",
                    "--drift-alerts=maybe",
                ],
            )
            assert result.exit_code != 0
