"""Unit tests for cart checkout helpers."""
from __future__ import annotations

from types import SimpleNamespace
from unittest.mock import patch

import pytest

from cart.bp.cart.services.checkout import (
    build_sumup_description,
    build_sumup_reference,
    build_webhook_url,
    validate_webhook_secret,
)


def _ci(title=None, qty=1):
    return SimpleNamespace(product_title=title, quantity=qty)


# ---------------------------------------------------------------------------
# build_sumup_description
# ---------------------------------------------------------------------------

class TestBuildSumupDescription:
    def test_empty_cart_no_tickets(self):
        result = build_sumup_description([], 1)
        assert "Order 1" in result
        assert "0 items" in result
        assert "order items" in result

    def test_single_item(self):
        result = build_sumup_description([_ci("Widget", 1)], 42)
        assert "Order 42" in result
        assert "1 item)" in result
        assert "Widget" in result

    def test_quantity_counted(self):
        result = build_sumup_description([_ci("Widget", 3)], 1)
        assert "3 items" in result

    def test_three_titles(self):
        items = [_ci("A"), _ci("B"), _ci("C")]
        result = build_sumup_description(items, 1)
        assert "A, B, C" in result
        assert "more" not in result

    def test_four_titles_truncated(self):
        items = [_ci("A"), _ci("B"), _ci("C"), _ci("D")]
        result = build_sumup_description(items, 1)
        assert "A, B, C" in result
        assert "+ 1 more" in result

    def test_none_titles_excluded(self):
        items = [_ci(None), _ci("Visible")]
        result = build_sumup_description(items, 1)
        assert "Visible" in result

    def test_tickets_singular(self):
        result = build_sumup_description([], 1, ticket_count=1)
        assert "1 ticket" in result
        assert "tickets" not in result

    def test_tickets_plural(self):
        result = build_sumup_description([], 1, ticket_count=3)
        assert "3 tickets" in result

    def test_mixed_items_and_tickets(self):
        result = build_sumup_description([_ci("A", 2)], 1, ticket_count=1)
        assert "3 items" in result  # 2 + 1


# ---------------------------------------------------------------------------
# build_sumup_reference
# ---------------------------------------------------------------------------

class TestBuildSumupReference:
    def test_with_page_config(self):
        pc = SimpleNamespace(sumup_checkout_prefix="SHOP-")
        assert build_sumup_reference(42, pc) == "SHOP-42"

    def test_without_page_config(self):
        with patch("cart.bp.cart.services.checkout.config",
                   return_value={"sumup": {"checkout_reference_prefix": "RA-"}}):
            assert build_sumup_reference(99) == "RA-99"

    def test_no_prefix(self):
        with patch("cart.bp.cart.services.checkout.config",
                   return_value={"sumup": {}}):
            assert build_sumup_reference(1) == "1"


# ---------------------------------------------------------------------------
# build_webhook_url
# ---------------------------------------------------------------------------

class TestBuildWebhookUrl:
    def test_no_secret(self):
        with patch("cart.bp.cart.services.checkout.config",
                   return_value={"sumup": {}}):
            assert build_webhook_url("https://x.com/hook") == "https://x.com/hook"

    def test_with_secret_no_query(self):
        with patch("cart.bp.cart.services.checkout.config",
                   return_value={"sumup": {"webhook_secret": "s3cret"}}):
            result = build_webhook_url("https://x.com/hook")
            assert "?token=s3cret" in result

    def test_with_secret_existing_query(self):
        with patch("cart.bp.cart.services.checkout.config",
                   return_value={"sumup": {"webhook_secret": "s3cret"}}):
            result = build_webhook_url("https://x.com/hook?a=1")
            assert "&token=s3cret" in result


# ---------------------------------------------------------------------------
# validate_webhook_secret
# ---------------------------------------------------------------------------

class TestValidateWebhookSecret:
    def test_no_secret_configured(self):
        with patch("cart.bp.cart.services.checkout.config",
                   return_value={"sumup": {}}):
            assert validate_webhook_secret(None) is True

    def test_correct_token(self):
        with patch("cart.bp.cart.services.checkout.config",
                   return_value={"sumup": {"webhook_secret": "abc"}}):
            assert validate_webhook_secret("abc") is True

    def test_wrong_token(self):
        with patch("cart.bp.cart.services.checkout.config",
                   return_value={"sumup": {"webhook_secret": "abc"}}):
            assert validate_webhook_secret("wrong") is False

    def test_none_token_with_secret(self):
        with patch("cart.bp.cart.services.checkout.config",
                   return_value={"sumup": {"webhook_secret": "abc"}}):
            assert validate_webhook_secret(None) is False
