"""
Tests for django_stripe_billing.checkout.

Covers input validation (_non_empty) and create_checkout_session / create_billing_portal_session
with mocked Stripe API.
"""
import pytest
from unittest.mock import patch, MagicMock
from django.test import override_settings

from django_stripe_billing.checkout import (
    create_checkout_session,
    create_billing_portal_session,
)


@pytest.fixture
def stripe_keys():
    return override_settings(
        STRIPE_BILLING={
            "STRIPE_SECRET_KEY": "sk_test_fake",
            "STRIPE_WEBHOOK_SECRET": "whsec_fake",
        }
    )


class TestCreateCheckoutSessionValidation:
    """create_checkout_session validates required args before calling Stripe."""

    def test_raises_value_error_for_empty_price_id(self, stripe_keys):
        with stripe_keys:
            with pytest.raises(ValueError) as exc_info:
                create_checkout_session(
                    price_id="",
                    success_url="https://example.com/success",
                    cancel_url="https://example.com/cancel",
                )
            assert "price_id" in str(exc_info.value).lower()

    def test_raises_value_error_for_empty_success_url(self, stripe_keys):
        with stripe_keys:
            with pytest.raises(ValueError) as exc_info:
                create_checkout_session(
                    price_id="price_123",
                    success_url="  ",
                    cancel_url="https://example.com/cancel",
                )
            assert "success_url" in str(exc_info.value).lower()

    def test_raises_value_error_for_empty_cancel_url(self, stripe_keys):
        with stripe_keys:
            with pytest.raises(ValueError) as exc_info:
                create_checkout_session(
                    price_id="price_123",
                    success_url="https://example.com/success",
                    cancel_url="",
                )
            assert "cancel_url" in str(exc_info.value).lower()

    def test_calls_stripe_with_expected_params(self, stripe_keys):
        mock_session = MagicMock()
        mock_session.id = "cs_test_123"
        mock_session.url = "https://checkout.stripe.com/..."
        with stripe_keys:
            with patch(
                "django_stripe_billing.checkout.stripe"
            ) as mock_stripe:
                mock_stripe.checkout.Session.create.return_value = mock_session
                session = create_checkout_session(
                    price_id="price_123",
                    success_url="https://example.com/success",
                    cancel_url="https://example.com/cancel",
                )
                assert session.id == "cs_test_123"
                call_kw = mock_stripe.checkout.Session.create.call_args[1]
                assert call_kw["line_items"] == [{"price": "price_123", "quantity": 1}]
                assert call_kw["mode"] == "subscription"
                assert call_kw["success_url"] == "https://example.com/success"
                assert call_kw["cancel_url"] == "https://example.com/cancel"


class TestCreateBillingPortalSessionValidation:
    """create_billing_portal_session validates customer_id and return_url."""

    def test_raises_value_error_for_empty_customer_id(self, stripe_keys):
        with stripe_keys:
            with pytest.raises(ValueError) as exc_info:
                create_billing_portal_session(
                    customer_id="",
                    return_url="https://example.com/account",
                )
            assert "customer_id" in str(exc_info.value).lower()

    def test_raises_value_error_for_empty_return_url(self, stripe_keys):
        with stripe_keys:
            with pytest.raises(ValueError) as exc_info:
                create_billing_portal_session(
                    customer_id="cus_123",
                    return_url="   ",
                )
            assert "return_url" in str(exc_info.value).lower()

    def test_calls_stripe_portal_with_params(self, stripe_keys):
        mock_session = MagicMock()
        mock_session.url = "https://billing.stripe.com/..."
        with stripe_keys:
            with patch(
                "django_stripe_billing.checkout.stripe"
            ) as mock_stripe:
                mock_stripe.billing_portal.Session.create.return_value = mock_session
                session = create_billing_portal_session(
                    customer_id="cus_123",
                    return_url="https://example.com/account",
                )
                call_kw = mock_stripe.billing_portal.Session.create.call_args[1]
                assert call_kw["customer"] == "cus_123"
                assert call_kw["return_url"] == "https://example.com/account"
