"""
Tests for django_stripe_billing.models.

Covers StripeWebhookEvent creation and state transitions (mark_processing, etc.).
"""
import pytest
from django.utils import timezone

from django_stripe_billing.models import (
    StripeWebhookEvent,
    WEBHOOK_STATUS_PENDING,
    WEBHOOK_STATUS_PROCESSING,
    WEBHOOK_STATUS_SUCCESS,
    WEBHOOK_STATUS_ERROR,
    WEBHOOK_STATUS_SKIPPED,
)


@pytest.mark.django_db
class TestStripeWebhookEvent:
    """StripeWebhookEvent model and state transitions."""

    def test_create_default_status_pending(self):
        ev = StripeWebhookEvent.objects.create(
            stripe_event_id="evt_test_1",
            event_type="invoice.payment_succeeded",
            payload='{"data": {"object": {}}}',
        )
        assert ev.status == WEBHOOK_STATUS_PENDING
        assert ev.attempts == 0
        assert ev.error_message == ""

    def test_str_representation(self):
        ev = StripeWebhookEvent.objects.create(
            stripe_event_id="evt_123",
            event_type="invoice.payment_succeeded",
            payload="{}",
        )
        assert "evt_123" in str(ev)
        assert "invoice.payment_succeeded" in str(ev)
        assert ev.status in str(ev)

    def test_mark_processing_increments_attempts(self):
        ev = StripeWebhookEvent.objects.create(
            stripe_event_id="evt_p",
            event_type="invoice.payment_succeeded",
            payload="{}",
        )
        ev.mark_processing()
        ev.refresh_from_db()
        assert ev.status == WEBHOOK_STATUS_PROCESSING
        assert ev.attempts == 1

    def test_mark_success_sets_processed_at(self):
        ev = StripeWebhookEvent.objects.create(
            stripe_event_id="evt_s",
            event_type="invoice.payment_succeeded",
            payload="{}",
        )
        ev.mark_success()
        ev.refresh_from_db()
        assert ev.status == WEBHOOK_STATUS_SUCCESS
        assert ev.processed_at is not None

    def test_mark_error_stores_message(self):
        ev = StripeWebhookEvent.objects.create(
            stripe_event_id="evt_e",
            event_type="invoice.payment_succeeded",
            payload="{}",
        )
        ev.mark_error("Something went wrong")
        ev.refresh_from_db()
        assert ev.status == WEBHOOK_STATUS_ERROR
        assert "Something went wrong" in ev.error_message
        assert ev.processed_at is not None

    def test_mark_error_truncates_long_message(self):
        ev = StripeWebhookEvent.objects.create(
            stripe_event_id="evt_long",
            event_type="invoice.payment_succeeded",
            payload="{}",
        )
        long_msg = "x" * 10000
        ev.mark_error(long_msg)
        ev.refresh_from_db()
        assert len(ev.error_message) <= 5000

    def test_mark_skipped_sets_reason(self):
        ev = StripeWebhookEvent.objects.create(
            stripe_event_id="evt_sk",
            event_type="unknown.event",
            payload="{}",
        )
        ev.mark_skipped(reason="No handler for unknown.event")
        ev.refresh_from_db()
        assert ev.status == WEBHOOK_STATUS_SKIPPED
        assert "No handler" in ev.error_message

    def test_unique_stripe_event_id_enforced(self):
        StripeWebhookEvent.objects.create(
            stripe_event_id="evt_dup",
            event_type="invoice.payment_succeeded",
            payload="{}",
        )
        with pytest.raises(Exception):  # IntegrityError
            StripeWebhookEvent.objects.create(
                stripe_event_id="evt_dup",
                event_type="invoice.payment_failed",
                payload="{}",
            )
