"""Tests for the Django integration."""

from __future__ import annotations

import json
from typing import Any
from unittest.mock import MagicMock, patch

import httpx
import pytest

from kanban_analytics.client import AnalyticsClient, ScopedAnalyticsClient
from kanban_analytics.integrations.django import AnalyticsMiddleware


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------


def _make_initialized_analytics() -> AnalyticsClient:
    """Return an initialised AnalyticsClient with a mock transport."""

    def _handler(request: httpx.Request) -> httpx.Response:
        return httpx.Response(200, json={})

    transport = httpx.MockTransport(_handler)
    client = AnalyticsClient()
    client._client = httpx.Client(transport=transport)
    client._api_key = "test-key"
    client._endpoint = "https://example.com/api/ingest"

    from kanban_analytics.context import build_server_context

    client._context = build_server_context({})  # type: ignore[arg-type]
    client._api_key_validated = True
    client._initialized = True
    return client


def _make_request(
    user: Any | None = None,
    request_id: str | None = None,
) -> MagicMock:
    """Create a mock Django request object."""
    request = MagicMock()
    if user is not None:
        request.user = user
    else:
        del request.user
    if request_id is not None:
        request.request_id = request_id
    else:
        del request.request_id
    return request


# ---------------------------------------------------------------------------
# AnalyticsMiddleware tests
# ---------------------------------------------------------------------------


class TestDjangoMiddleware:
    def test_attaches_analytics_to_request(self) -> None:
        client = _make_initialized_analytics()

        with patch("kanban_analytics.analytics", client):
            response = MagicMock()
            get_response = MagicMock(return_value=response)
            middleware = AnalyticsMiddleware(get_response)

            request = _make_request()
            result = middleware(request)

            assert result is response
            assert hasattr(request, "analytics")
            assert isinstance(request.analytics, ScopedAnalyticsClient)

    def test_extracts_authenticated_user_id(self) -> None:
        client = _make_initialized_analytics()

        user = MagicMock()
        user.is_authenticated = True
        user.pk = 42

        with patch("kanban_analytics.analytics", client):
            get_response = MagicMock(return_value=MagicMock())
            middleware = AnalyticsMiddleware(get_response)

            request = _make_request(user=user)
            middleware(request)

            # The scoped client should carry user_id="42"
            assert request.analytics._context["user_id"] == "42"

    def test_handles_unauthenticated_user(self) -> None:
        client = _make_initialized_analytics()

        user = MagicMock()
        user.is_authenticated = False

        with patch("kanban_analytics.analytics", client):
            get_response = MagicMock(return_value=MagicMock())
            middleware = AnalyticsMiddleware(get_response)

            request = _make_request(user=user)
            middleware(request)

            assert request.analytics._context["user_id"] is None


# ---------------------------------------------------------------------------
# Auth signals tests
# ---------------------------------------------------------------------------


class TestDjangoAuthSignals:
    def test_connect_auth_signals_noop_when_disabled(self) -> None:
        """auto_track=False should not connect anything."""
        from kanban_analytics.integrations.django import connect_auth_signals

        # Should not raise or do anything
        connect_auth_signals(auto_track=False)
