"""Unit tests for SettingsManager parse/infer helpers and Stripe webhook stubs.

Tests the pure logic in SettingsManager._parse_value and _infer_type without DB.
Also covers the Stripe webhook handler stubs for completeness.
"""

import pytest
from unittest.mock import AsyncMock

from app.core.settings_manager import SettingsManager
from app.core.stripe_handlers import (
    WEBHOOK_HANDLERS,
    handle_checkout_completed,
    handle_invoice_paid,
    handle_invoice_payment_failed,
    handle_subscription_deleted,
    handle_subscription_updated,
)


class TestSettingsManagerParseValue:

    def test_parse_string(self):
        assert SettingsManager._parse_value("hello", "string") == "hello"

    def test_parse_boolean_true(self):
        assert SettingsManager._parse_value("true", "boolean") is True

    def test_parse_boolean_True_capitalized(self):
        assert SettingsManager._parse_value("True", "boolean") is True

    def test_parse_boolean_false(self):
        assert SettingsManager._parse_value("false", "boolean") is False

    def test_parse_integer(self):
        assert SettingsManager._parse_value("42", "integer") == 42

    def test_parse_json_dict(self):
        result = SettingsManager._parse_value('{"key": "val"}', "json")
        assert result == {"key": "val"}

    def test_parse_json_list(self):
        result = SettingsManager._parse_value('[1, 2, 3]', "json")
        assert result == [1, 2, 3]

    def test_parse_none_returns_none(self):
        assert SettingsManager._parse_value(None, "string") is None

    def test_parse_unknown_type_returns_string(self):
        assert SettingsManager._parse_value("val", "unknown") == "val"


class TestSettingsManagerInferType:

    def test_infer_boolean(self):
        assert SettingsManager._infer_type(True) == "boolean"
        assert SettingsManager._infer_type(False) == "boolean"

    def test_infer_integer(self):
        assert SettingsManager._infer_type(42) == "integer"

    def test_infer_dict_as_json(self):
        assert SettingsManager._infer_type({"k": "v"}) == "json"

    def test_infer_list_as_json(self):
        assert SettingsManager._infer_type([1, 2]) == "json"

    def test_infer_string(self):
        assert SettingsManager._infer_type("hello") == "string"

    def test_infer_none_as_string(self):
        # None is not bool/int/dict/list, falls to string
        assert SettingsManager._infer_type(None) == "string"


class TestStripeWebhookHandlers:
    """Test that stub handlers run without error and are registered."""

    @pytest.mark.asyncio
    async def test_checkout_completed(self):
        await handle_checkout_completed({"id": "evt_123"}, AsyncMock())

    @pytest.mark.asyncio
    async def test_invoice_paid(self):
        await handle_invoice_paid({"id": "evt_456"}, AsyncMock())

    @pytest.mark.asyncio
    async def test_invoice_payment_failed(self):
        await handle_invoice_payment_failed({"id": "evt_789"}, AsyncMock())

    @pytest.mark.asyncio
    async def test_subscription_updated(self):
        await handle_subscription_updated({"id": "evt_abc"}, AsyncMock())

    @pytest.mark.asyncio
    async def test_subscription_deleted(self):
        await handle_subscription_deleted({"id": "evt_def"}, AsyncMock())

    def test_webhook_handlers_registry(self):
        assert "checkout.session.completed" in WEBHOOK_HANDLERS
        assert "invoice.paid" in WEBHOOK_HANDLERS
        assert "invoice.payment_failed" in WEBHOOK_HANDLERS
        assert "customer.subscription.updated" in WEBHOOK_HANDLERS
        assert "customer.subscription.deleted" in WEBHOOK_HANDLERS
        assert len(WEBHOOK_HANDLERS) == 5
