"""Shared fixtures for backend tests."""

from dataclasses import dataclass
from typing import Any

import pytest
import strawberry
from django.contrib.auth import get_user_model

# Import the Query and Mutation classes directly to build a test schema without extensions
from core.graphql import Mutation, Query

User = get_user_model()

# Create a test schema without the problematic extensions
test_schema = strawberry.Schema(query=Query, mutation=Mutation)


@dataclass
class GraphQLResult:
    """Result from a GraphQL query/mutation execution."""

    data: dict[str, Any] | None
    errors: list[Any] | None


class GraphQLTestClient:
    """Test client for GraphQL queries and mutations."""

    def __init__(self, user=None):
        self.user = user
        self._schema = test_schema

    def execute(self, query: str, variables: dict[str, Any] | None = None) -> GraphQLResult:
        """Execute a GraphQL query with optional authentication."""
        context = type("Context", (), {"user": self.user})()
        result = self._schema.execute_sync(
            query,
            variable_values=variables,
            context_value=context,
        )
        return GraphQLResult(
            errors=result.errors,
            data=result.data,
        )


@pytest.fixture
def graphql_client():
    """Return an unauthenticated GraphQL test client."""
    return GraphQLTestClient()


@pytest.fixture
def authenticated_client(user):
    """Return an authenticated GraphQL test client."""
    return GraphQLTestClient(user=user)


@pytest.fixture
def user(db):
    """Create a test user."""
    return User.objects.create_user(
        username="testuser",
        email="test@example.com",
        password="testpass123",
        first_name="Test",
        last_name="User",
    )


@pytest.fixture
def admin_user(db):
    """Create an admin test user."""
    return User.objects.create_superuser(
        username="admin",
        email="admin@example.com",
        password="adminpass123",
        first_name="Admin",
        last_name="User",
    )
