"""Tests for billing app GraphQL queries."""

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

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

from .factories import PlanFactory, SubscriptionFactory


@pytest.mark.django_db
class TestPlansQuery:
    """Tests for plans query."""

    def test_plans_returns_all_active_plans(self):
        """Test that plans query returns all active plans."""
        PlanFactory(name="Basic", is_active=True)
        PlanFactory(name="Pro", is_active=True)
        PlanFactory(name="Deprecated", is_active=False)

        client = GraphQLTestClient()
        result = client.execute(
            """
            query Plans {
                plans {
                    id
                    name
                    isActive
                }
            }
            """
        )

        assert result.errors is None
        assert len(result.data["plans"]) == 2
        names = {p["name"] for p in result.data["plans"]}
        assert "Basic" in names
        assert "Pro" in names
        assert "Deprecated" not in names

    def test_plans_includes_inactive_when_requested(self):
        """Test that plans query can include inactive plans."""
        PlanFactory(name="Active", is_active=True)
        PlanFactory(name="Inactive", is_active=False)

        client = GraphQLTestClient()
        result = client.execute(
            """
            query Plans($activeOnly: Boolean) {
                plans(activeOnly: $activeOnly) {
                    id
                    name
                }
            }
            """,
            variables={"activeOnly": False},
        )

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


@pytest.mark.django_db
class TestPlanQuery:
    """Tests for plan query."""

    def test_plan_returns_single_plan(self):
        """Test that plan query returns a specific plan."""
        plan = PlanFactory(name="Pro Plan", price_cents=9999)

        client = GraphQLTestClient()
        result = client.execute(
            """
            query Plan($id: ID!) {
                plan(id: $id) {
                    id
                    name
                    priceCents
                    price
                }
            }
            """,
            variables={"id": str(plan.id)},
        )

        assert result.errors is None
        assert result.data["plan"]["name"] == "Pro Plan"
        assert result.data["plan"]["priceCents"] == 9999
        assert result.data["plan"]["price"] == 99.99

    def test_plan_returns_none_for_nonexistent(self):
        """Test that plan returns null for nonexistent plan."""
        client = GraphQLTestClient()
        result = client.execute(
            """
            query Plan($id: ID!) {
                plan(id: $id) {
                    id
                }
            }
            """,
            variables={"id": "99999"},
        )

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


@pytest.mark.django_db
class TestSubscriptionsQuery:
    """Tests for subscriptions query."""

    def test_subscriptions_returns_workspace_subscriptions(self):
        """Test that subscriptions query returns all subscriptions for a workspace."""
        user = UserFactory()
        workspace = WorkspaceFactory()
        WorkspaceMembershipFactory(user=user, workspace=workspace)

        SubscriptionFactory(workspace=workspace, status="active")
        SubscriptionFactory(workspace=workspace, status="canceled")

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

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

    def test_subscriptions_returns_empty_for_unauthenticated(self):
        """Test that subscriptions query returns empty for unauthenticated users."""
        workspace = WorkspaceFactory()
        SubscriptionFactory(workspace=workspace)

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

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

    def test_subscriptions_returns_empty_for_non_member(self):
        """Test that subscriptions query returns empty for non-members."""
        user = UserFactory()
        workspace = WorkspaceFactory()
        SubscriptionFactory(workspace=workspace)

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

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


@pytest.mark.django_db
class TestSubscriptionQuery:
    """Tests for subscription query."""

    def test_subscription_returns_single_subscription(self):
        """Test that subscription query returns a specific subscription."""
        user = UserFactory()
        workspace = WorkspaceFactory()
        WorkspaceMembershipFactory(user=user, workspace=workspace)
        subscription = SubscriptionFactory(workspace=workspace, status="active")

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

        assert result.errors is None
        assert result.data["subscription"]["status"] == "ACTIVE"

    def test_subscription_returns_none_for_no_access(self):
        """Test that subscription returns null when user has no access."""
        user = UserFactory()
        workspace = WorkspaceFactory()
        subscription = SubscriptionFactory(workspace=workspace)

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

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