from decimal import Decimal

from robosystems.config.billing import core
from robosystems.config.billing.core import (
  DEFAULT_GRAPH_BILLING_PLANS,
  TIER_CREDIT_ALLOCATIONS,
  BillingConfig,
)
from robosystems.config.credits import CreditConfig


def test_get_subscription_plan_returns_plan_with_credit_allocation():
  """Test that subscription plans include monthly_credit_allocation.

  ~38 credits per typical agent call → 8,000 credits ≈ 200 agent calls/month
  """
  plan = BillingConfig.get_subscription_plan("ladybug-standard")

  assert plan is not None
  assert plan["name"] == "ladybug-standard"
  assert plan["monthly_credit_allocation"] == 8000  # ~200 agent calls/month
  assert plan["base_price_cents"] == 9900  # $99/month


def test_get_subscription_plan_returns_none_for_unknown_tier():
  assert BillingConfig.get_subscription_plan("does-not-exist") is None


def test_tier_credit_allocations_matches_plans():
  """Test that TIER_CREDIT_ALLOCATIONS is built from DEFAULT_GRAPH_BILLING_PLANS."""
  for plan in DEFAULT_GRAPH_BILLING_PLANS:
    tier_name = plan["name"]
    assert tier_name in TIER_CREDIT_ALLOCATIONS
    assert TIER_CREDIT_ALLOCATIONS[tier_name] == plan["monthly_credit_allocation"]


def test_get_monthly_credits_returns_from_plans():
  """Test that get_monthly_credits returns values from plans."""
  assert BillingConfig.get_monthly_credits("ladybug-standard") == 8000  # ~200 calls
  assert BillingConfig.get_monthly_credits("ladybug-large") == 32000  # ~800 calls
  assert BillingConfig.get_monthly_credits("ladybug-xlarge") == 100000  # ~2,600 calls
  assert BillingConfig.get_monthly_credits("unknown") == 0


def test_get_operation_cost_uses_credit_config(monkeypatch):
  monkeypatch.setattr(
    CreditConfig,
    "get_operation_cost",
    classmethod(lambda cls, op: Decimal("42") if op == "agent_call" else Decimal("0")),
  )

  assert BillingConfig.get_operation_cost("agent_call") == Decimal("42")
  assert BillingConfig.get_operation_cost("unknown") == Decimal("0")


def test_validate_configuration_reports_missing_required_fields(monkeypatch):
  """Test that validation catches missing required fields in billing plans."""
  # Create a plan missing the 'base_price_cents' field
  bad_plans = [{"name": "test-tier", "monthly_credit_allocation": 1000}]
  monkeypatch.setattr(core, "DEFAULT_GRAPH_BILLING_PLANS", bad_plans)
  warnings: list[str] = []
  monkeypatch.setattr(
    core.logger,
    "warning",
    lambda message, *args, **kwargs: warnings.append(message),
  )

  result = BillingConfig.validate_configuration()

  assert not result["valid"]
  assert any("base_price_cents" in issue for issue in result["issues"])
  assert any("validation found" in message for message in warnings)


def test_validate_configuration_passes_with_valid_plans(monkeypatch):
  """Test that validation passes when all plans have required fields."""
  infos: list[str] = []
  monkeypatch.setattr(
    core.logger,
    "info",
    lambda message, *args, **kwargs: infos.append(message),
  )

  result = BillingConfig.validate_configuration()

  assert result["valid"]
  assert result["summary"]["billing_plans"] == len(DEFAULT_GRAPH_BILLING_PLANS)
  assert any("validation passed" in message for message in infos)


def test_get_all_pricing_info_returns_expected_structure():
  """Test get_all_pricing_info returns correct structure."""
  pricing = BillingConfig.get_all_pricing_info()

  assert set(pricing["subscription_tiers"]) == {
    "ladybug-standard",
    "ladybug-large",
    "ladybug-xlarge",
  }
  assert (
    pricing["subscription_tiers"]["ladybug-large"]["monthly_credit_allocation"] == 32000
  )
  # AI operations use token-based pricing now, no fixed costs
  assert pricing["ai_operation_costs"] == {}
  assert "query" in pricing["no_credit_operations"]
