"""Tests for notification settings and alert endpoints."""

from unittest.mock import AsyncMock, patch


class TestGetNotificationSettings:
    """Tests for GET /v1/notifications/settings."""

    def test_get_settings_success(self, client, auth_header):
        project_id = "660e8400-e29b-41d4-a716-446655440000"
        with patch("api.db.get_notification_settings") as mock_get, \
             patch("api.routers.notifications.check_project_access", new_callable=AsyncMock):
            mock_get.return_value = {
                "project_id": project_id,
                "enabled": True,
                "channels": [{"type": "slack"}],
                "notification_types": ["new_flaky", "fix_available"],
            }
            response = client.get(
                f"/v1/notifications/settings?project_id={project_id}",
                headers=auth_header,
            )
            assert response.status_code == 200
            data = response.json()
            assert data["enabled"] is True
            assert len(data["channels"]) == 1

    def test_get_settings_not_configured(self, client, auth_header):
        project_id = "660e8400-e29b-41d4-a716-446655440000"
        with patch("api.db.get_notification_settings") as mock_get, \
             patch("api.routers.notifications.check_project_access", new_callable=AsyncMock):
            mock_get.return_value = None
            response = client.get(
                f"/v1/notifications/settings?project_id={project_id}",
                headers=auth_header,
            )
            assert response.status_code == 200
            data = response.json()
            assert data["enabled"] is False

    def test_get_settings_unauthorized(self, client):
        response = client.get(
            "/v1/notifications/settings?project_id=660e8400-e29b-41d4-a716-446655440000",
        )
        assert response.status_code == 401


class TestUpdateNotificationSettings:
    """Tests for POST /v1/notifications/settings."""

    def test_update_settings_success(self, client, auth_header):
        project_id = "660e8400-e29b-41d4-a716-446655440000"
        with patch("api.db.update_notification_settings") as mock_update, \
             patch("api.routers.notifications.check_project_access", new_callable=AsyncMock):
            mock_update.return_value = {
                "project_id": project_id,
                "enabled": True,
                "channels": [{"type": "slack", "webhook_url": "https://hooks.slack.com/test"}],
                "notification_types": ["new_flaky"],
            }
            response = client.post(
                f"/v1/notifications/settings?project_id={project_id}",
                json={
                    "slack_webhook_url": "https://hooks.slack.com/test",
                    "notification_types": ["new_flaky"],
                    "enabled": True,
                },
                headers=auth_header,
            )
            assert response.status_code == 200
            mock_update.assert_called_once()

    def test_update_settings_invalid_slack_url(self, client, auth_header):
        project_id = "660e8400-e29b-41d4-a716-446655440000"
        with patch("api.routers.notifications.check_project_access", new_callable=AsyncMock):
            response = client.post(
                f"/v1/notifications/settings?project_id={project_id}",
                json={
                    "slack_webhook_url": "https://evil.com/webhook",
                    "enabled": True,
                },
                headers=auth_header,
            )
            assert response.status_code == 400

    def test_update_settings_unauthorized(self, client):
        response = client.post(
            "/v1/notifications/settings?project_id=660e8400-e29b-41d4-a716-446655440000",
            json={"enabled": True},
        )
        assert response.status_code == 401


class TestSendTestNotification:
    """Tests for POST /v1/notifications/test."""

    def test_send_test_notification_success(self, client, auth_header):
        project_id = "660e8400-e29b-41d4-a716-446655440000"
        with patch("api.db.get_notification_settings") as mock_settings, \
             patch("api.routers.notifications.check_project_access", new_callable=AsyncMock), \
             patch("api.notifications.send_notification") as mock_send:
            mock_settings.return_value = {"enabled": True, "channels": []}
            mock_send.return_value = {"success": True, "channels": ["slack"]}
            response = client.post(
                f"/v1/notifications/test?project_id={project_id}",
                headers=auth_header,
            )
            assert response.status_code == 200
            data = response.json()
            assert data["success"] is True

    def test_send_test_notification_not_enabled(self, client, auth_header):
        project_id = "660e8400-e29b-41d4-a716-446655440000"
        with patch("api.db.get_notification_settings") as mock_settings, \
             patch("api.routers.notifications.check_project_access", new_callable=AsyncMock):
            mock_settings.return_value = {"enabled": False}
            response = client.post(
                f"/v1/notifications/test?project_id={project_id}",
                headers=auth_header,
            )
            assert response.status_code == 400

    def test_send_test_notification_unauthorized(self, client):
        response = client.post(
            "/v1/notifications/test?project_id=660e8400-e29b-41d4-a716-446655440000",
        )
        assert response.status_code == 401
