"""Unit tests for meter operations."""

from unittest.mock import MagicMock, Mock, patch

import pytest

from augint_billing_lib.cli.products.setup import create_metered_price_with_tiers


@pytest.mark.unit
class TestMeterOperations:
    """Test meter-related operations."""

    @patch("augint_billing_lib.cli.products.setup.stripe")
    def test_create_metered_price_with_meter(self, mock_stripe: MagicMock) -> None:
        """Test creating a metered price with a meter ID."""
        mock_price = Mock(id="price_123")
        mock_stripe.Price.create.return_value = mock_price

        result = create_metered_price_with_tiers(
            product_id="prod_test",
            currency="usd",
            tiers=[{"up_to": 1000, "unit_amount": 100}],
            meter_id="meter_123",
        )

        # Verify Price.create was called with meter in recurring config
        mock_stripe.Price.create.assert_called_once()
        call_args = mock_stripe.Price.create.call_args
        assert call_args[1]["product"] == "prod_test"
        assert call_args[1]["currency"] == "usd"
        assert call_args[1]["recurring"]["meter"] == "meter_123"
        assert call_args[1]["recurring"]["usage_type"] == "metered"
        assert result == mock_price

    @patch("augint_billing_lib.cli.products.setup.stripe")
    def test_create_metered_price_without_meter(self, mock_stripe: MagicMock) -> None:
        """Test creating a metered price without a meter ID (backward compatibility)."""
        mock_price = Mock(id="price_456")
        mock_stripe.Price.create.return_value = mock_price

        result = create_metered_price_with_tiers(
            product_id="prod_test",
            currency="usd",
            tiers=[{"up_to": 1000, "unit_amount": 100}],
            meter_id=None,
        )

        # Verify Price.create was called without meter in recurring config
        mock_stripe.Price.create.assert_called_once()
        call_args = mock_stripe.Price.create.call_args
        assert call_args[1]["product"] == "prod_test"
        assert call_args[1]["currency"] == "usd"
        assert "meter" not in call_args[1]["recurring"]
        assert call_args[1]["recurring"]["usage_type"] == "metered"
        assert result == mock_price


@pytest.mark.unit
class TestMeterEventReporting:
    """Test meter event reporting."""

    @patch("augint_billing_lib.adapters.stripe.stripe")
    def test_report_usage_with_meter_event(self, mock_stripe: MagicMock) -> None:
        """Test reporting usage creates a meter event correctly."""
        from augint_billing_lib.adapters.stripe import StripeAdapter

        adapter = StripeAdapter("sk_test", "price_123")

        # Mock subscription item and subscription
        mock_sub_item = Mock(subscription="sub_123")
        mock_subscription = Mock(customer="cus_test")
        mock_stripe.SubscriptionItem.retrieve.return_value = mock_sub_item
        mock_stripe.Subscription.retrieve.return_value = mock_subscription

        # Mock meter event creation
        mock_event = {"id": "evt_test", "object": "billing.meter_event"}
        mock_stripe.billing.MeterEvent.create.return_value = mock_event

        result = adapter.report_usage("si_test", 500, 1234567890, "idem_key")

        # Verify the meter event was created with correct parameters
        mock_stripe.billing.MeterEvent.create.assert_called_once_with(
            event_name="api_usage",
            payload={
                "stripe_customer_id": "cus_test",
                "value": "500",  # Should be string
            },
            timestamp=1234567890,
            idempotency_key="idem_key",
        )
        assert result == mock_event

    @patch("augint_billing_lib.adapters.stripe.stripe")
    def test_report_usage_without_idempotency_key(self, mock_stripe: MagicMock) -> None:
        """Test reporting usage without idempotency key."""
        from augint_billing_lib.adapters.stripe import StripeAdapter

        adapter = StripeAdapter("sk_test", "price_123")

        # Mock subscription item and subscription
        mock_sub_item = Mock(subscription="sub_123")
        mock_subscription = Mock(customer="cus_test")
        mock_stripe.SubscriptionItem.retrieve.return_value = mock_sub_item
        mock_stripe.Subscription.retrieve.return_value = mock_subscription

        # Mock meter event creation
        mock_event = {"id": "evt_test2", "object": "billing.meter_event"}
        mock_stripe.billing.MeterEvent.create.return_value = mock_event

        result = adapter.report_usage("si_test", 750, 1234567890, None)

        # Verify the meter event was created without idempotency_key
        mock_stripe.billing.MeterEvent.create.assert_called_once_with(
            event_name="api_usage",
            payload={"stripe_customer_id": "cus_test", "value": "750"},
            timestamp=1234567890,
        )
        assert result == mock_event
