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

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

from accounts.tests.factories import (
    UserFactory,
    WorkspaceFactory,
    WorkspaceMembershipFactory,
)

from .factories import IdentityFactory, MemberFactory


@pytest.mark.django_db
class TestMembersQuery:
    """Tests for members query."""

    def test_members_returns_workspace_members(self):
        """Test that members query returns all members in a workspace."""
        user = UserFactory()
        workspace = WorkspaceFactory()
        WorkspaceMembershipFactory(user=user, workspace=workspace, role="member")

        # Create some members
        MemberFactory.create_batch(3, workspace=workspace)

        client = GraphQLTestClient(user=user)
        result = client.execute(
            """
            query Members($workspaceId: ID!) {
                members(workspaceId: $workspaceId) {
                    id
                    displayName
                    email
                }
            }
            """,
            variables={"workspaceId": str(workspace.id)},
        )

        assert result.errors is None
        assert len(result.data["members"]) == 3

    def test_members_returns_empty_for_unauthenticated(self):
        """Test that members query returns empty for unauthenticated users."""
        workspace = WorkspaceFactory()
        MemberFactory.create_batch(3, workspace=workspace)

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

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

    def test_members_returns_empty_for_non_member(self):
        """Test that members query returns empty for users not in the workspace."""
        user = UserFactory()
        workspace = WorkspaceFactory()
        MemberFactory.create_batch(3, workspace=workspace)

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

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


@pytest.mark.django_db
class TestMemberQuery:
    """Tests for member query."""

    def test_member_returns_single_member(self):
        """Test that member query returns a specific member."""
        user = UserFactory()
        workspace = WorkspaceFactory()
        WorkspaceMembershipFactory(user=user, workspace=workspace)
        member = MemberFactory(workspace=workspace, display_name="Test Member")

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

        assert result.errors is None
        assert result.data["member"]["displayName"] == "Test Member"

    def test_member_returns_none_for_nonexistent(self):
        """Test that member query returns null for nonexistent member."""
        user = UserFactory()

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

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


@pytest.mark.django_db
class TestIdentitiesQuery:
    """Tests for identities query."""

    def test_identities_returns_member_identities(self):
        """Test that identities query returns all identities for a member."""
        user = UserFactory()
        workspace = WorkspaceFactory()
        WorkspaceMembershipFactory(user=user, workspace=workspace)
        member = MemberFactory(workspace=workspace)
        IdentityFactory(member=member, provider="github", handle="ghuser")
        IdentityFactory(member=member, provider="discord", handle="dcuser")

        client = GraphQLTestClient(user=user)
        result = client.execute(
            """
            query Identities($memberId: ID!) {
                identities(memberId: $memberId) {
                    provider
                    handle
                }
            }
            """,
            variables={"memberId": str(member.id)},
        )

        assert result.errors is None
        assert len(result.data["identities"]) == 2


@pytest.mark.django_db
class TestCreateMemberMutation:
    """Tests for createMember mutation."""

    def test_create_member_success(self):
        """Test creating a member successfully."""
        user = UserFactory()
        workspace = WorkspaceFactory()
        WorkspaceMembershipFactory(user=user, workspace=workspace, role="admin")

        client = GraphQLTestClient(user=user)
        result = client.execute(
            """
            mutation CreateMember($input: CreateMemberInput!) {
                createMember(input: $input) {
                    id
                    displayName
                    email
                }
            }
            """,
            variables={
                "input": {
                    "workspaceId": str(workspace.id),
                    "displayName": "New Member",
                    "email": "new@example.com",
                }
            },
        )

        assert result.errors is None
        assert result.data["createMember"]["displayName"] == "New Member"
        assert result.data["createMember"]["email"] == "new@example.com"

    def test_create_member_requires_auth(self):
        """Test that creating a member requires authentication."""
        workspace = WorkspaceFactory()

        client = GraphQLTestClient()
        result = client.execute(
            """
            mutation CreateMember($input: CreateMemberInput!) {
                createMember(input: $input) {
                    id
                }
            }
            """,
            variables={
                "input": {
                    "workspaceId": str(workspace.id),
                    "displayName": "New Member",
                }
            },
        )

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


@pytest.mark.django_db
class TestDeleteMemberMutation:
    """Tests for deleteMember mutation."""

    def test_delete_member_success(self):
        """Test deleting a member successfully."""
        user = UserFactory()
        workspace = WorkspaceFactory()
        WorkspaceMembershipFactory(user=user, workspace=workspace, role="admin")
        member = MemberFactory(workspace=workspace)

        client = GraphQLTestClient(user=user)
        result = client.execute(
            """
            mutation DeleteMember($id: ID!) {
                deleteMember(id: $id)
            }
            """,
            variables={"id": str(member.id)},
        )

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