"""Tests for accounts app GraphQL queries and mutations."""

import pytest
from tests.backend.graphql.conftest import GraphQLTestClient

from .factories import UserFactory, WorkspaceFactory, WorkspaceMembershipFactory


@pytest.mark.django_db
class TestWorkspacesQuery:
    """Tests for workspaces query."""

    def test_workspaces_returns_user_workspaces(self):
        """Test that workspaces query returns all workspaces user has access to."""
        user = UserFactory()
        workspace1 = WorkspaceFactory(name="Workspace 1")
        workspace2 = WorkspaceFactory(name="Workspace 2")
        WorkspaceMembershipFactory(user=user, workspace=workspace1)
        WorkspaceMembershipFactory(user=user, workspace=workspace2)

        # Create another workspace the user doesn't have access to
        WorkspaceFactory(name="Other Workspace")

        client = GraphQLTestClient(user=user)
        result = client.execute(
            """
            query Workspaces {
                workspaces {
                    id
                    name
                    slug
                }
            }
            """
        )

        assert result.errors is None
        assert len(result.data["workspaces"]) == 2
        names = {ws["name"] for ws in result.data["workspaces"]}
        assert "Workspace 1" in names
        assert "Workspace 2" in names

    def test_workspaces_returns_empty_for_unauthenticated(self):
        """Test that workspaces query returns empty for unauthenticated users."""
        WorkspaceFactory()

        client = GraphQLTestClient()
        result = client.execute(
            """
            query Workspaces {
                workspaces {
                    id
                }
            }
            """
        )

        assert result.errors is None
        assert result.data["workspaces"] == []


@pytest.mark.django_db
class TestWorkspaceQuery:
    """Tests for workspace query."""

    def test_workspace_returns_single_workspace(self):
        """Test that workspace query returns a specific workspace."""
        user = UserFactory()
        workspace = WorkspaceFactory(name="My Workspace", slug="my-workspace")
        WorkspaceMembershipFactory(user=user, workspace=workspace)

        client = GraphQLTestClient(user=user)
        result = client.execute(
            """
            query Workspace($id: ID!) {
                workspace(id: $id) {
                    id
                    name
                    slug
                }
            }
            """,
            variables={"id": str(workspace.id)},
        )

        assert result.errors is None
        assert result.data["workspace"]["name"] == "My Workspace"
        assert result.data["workspace"]["slug"] == "my-workspace"

    def test_workspace_returns_none_for_no_access(self):
        """Test that workspace returns null for workspaces user can't access."""
        user = UserFactory()
        workspace = WorkspaceFactory()

        client = GraphQLTestClient(user=user)
        result = client.execute(
            """
            query Workspace($id: ID!) {
                workspace(id: $id) {
                    id
                }
            }
            """,
            variables={"id": str(workspace.id)},
        )

        assert result.errors is None
        assert result.data["workspace"] is None

    def test_workspace_returns_none_for_nonexistent(self):
        """Test that workspace returns null for nonexistent workspace."""
        user = UserFactory()

        client = GraphQLTestClient(user=user)
        result = client.execute(
            """
            query Workspace($id: ID!) {
                workspace(id: $id) {
                    id
                }
            }
            """,
            variables={"id": "99999"},
        )

        assert result.errors is None
        assert result.data["workspace"] is None


@pytest.mark.django_db
class TestCreateWorkspaceMutation:
    """Tests for createWorkspace mutation."""

    def test_create_workspace_success(self):
        """Test creating a workspace successfully."""
        user = UserFactory()

        client = GraphQLTestClient(user=user)
        result = client.execute(
            """
            mutation CreateWorkspace($input: CreateWorkspaceInput!) {
                createWorkspace(input: $input) {
                    id
                    name
                    slug
                }
            }
            """,
            variables={"input": {"name": "New Workspace", "slug": "new-workspace"}},
        )

        assert result.errors is None
        assert result.data["createWorkspace"]["name"] == "New Workspace"
        assert result.data["createWorkspace"]["slug"] == "new-workspace"

    def test_create_workspace_requires_auth(self):
        """Test that creating a workspace requires authentication."""
        client = GraphQLTestClient()
        result = client.execute(
            """
            mutation CreateWorkspace($input: CreateWorkspaceInput!) {
                createWorkspace(input: $input) {
                    id
                }
            }
            """,
            variables={"input": {"name": "New Workspace", "slug": "new-workspace"}},
        )

        assert result.errors is not None
        assert "Authentication required" in str(result.errors)

    def test_create_workspace_duplicate_slug(self):
        """Test that duplicate slugs are rejected."""
        user = UserFactory()
        WorkspaceFactory(slug="existing-slug")

        client = GraphQLTestClient(user=user)
        result = client.execute(
            """
            mutation CreateWorkspace($input: CreateWorkspaceInput!) {
                createWorkspace(input: $input) {
                    id
                }
            }
            """,
            variables={"input": {"name": "New Workspace", "slug": "existing-slug"}},
        )

        assert result.errors is not None
        assert "already exists" in str(result.errors)


@pytest.mark.django_db
class TestUpdateWorkspaceMutation:
    """Tests for updateWorkspace mutation."""

    def test_update_workspace_success(self):
        """Test updating a workspace successfully."""
        user = UserFactory()
        workspace = WorkspaceFactory(name="Old Name")
        WorkspaceMembershipFactory(user=user, workspace=workspace, role="admin")

        client = GraphQLTestClient(user=user)
        result = client.execute(
            """
            mutation UpdateWorkspace($id: ID!, $input: UpdateWorkspaceInput!) {
                updateWorkspace(id: $id, input: $input) {
                    id
                    name
                }
            }
            """,
            variables={"id": str(workspace.id), "input": {"name": "New Name"}},
        )

        assert result.errors is None
        assert result.data["updateWorkspace"]["name"] == "New Name"

    def test_update_workspace_requires_admin(self):
        """Test that updating requires admin access."""
        user = UserFactory()
        workspace = WorkspaceFactory()
        WorkspaceMembershipFactory(user=user, workspace=workspace, role="member")

        client = GraphQLTestClient(user=user)
        result = client.execute(
            """
            mutation UpdateWorkspace($id: ID!, $input: UpdateWorkspaceInput!) {
                updateWorkspace(id: $id, input: $input) {
                    id
                }
            }
            """,
            variables={"id": str(workspace.id), "input": {"name": "New Name"}},
        )

        assert result.errors is not None
        assert "Permission denied" in str(result.errors)


@pytest.mark.django_db
class TestDeleteWorkspaceMutation:
    """Tests for deleteWorkspace mutation."""

    def test_delete_workspace_success(self):
        """Test deleting a workspace successfully."""
        user = UserFactory()
        workspace = WorkspaceFactory()
        WorkspaceMembershipFactory(user=user, workspace=workspace, role="owner")

        client = GraphQLTestClient(user=user)
        result = client.execute(
            """
            mutation DeleteWorkspace($id: ID!) {
                deleteWorkspace(id: $id)
            }
            """,
            variables={"id": str(workspace.id)},
        )

        assert result.errors is None
        assert result.data["deleteWorkspace"] is True

    def test_delete_workspace_requires_owner(self):
        """Test that deleting requires owner access."""
        user = UserFactory()
        workspace = WorkspaceFactory()
        WorkspaceMembershipFactory(user=user, workspace=workspace, role="admin")

        client = GraphQLTestClient(user=user)
        result = client.execute(
            """
            mutation DeleteWorkspace($id: ID!) {
                deleteWorkspace(id: $id)
            }
            """,
            variables={"id": str(workspace.id)},
        )

        assert result.errors is not None
        assert "Permission denied" in str(result.errors)
