"""Tests for transition decorator generation."""

from unittest.mock import Mock

from apps.core.state_machine.decorators import (
    TransitionMethodFactory,
    create_transition_method,
    generate_transition_decorator,
    with_transition_logging,
)


def test_generate_transition_decorator():
    """Test basic transition decorator generation."""
    decorator = generate_transition_decorator(source="pending", target="approved", field_name="status")
    assert callable(decorator)


def test_create_transition_method_basic():
    """Test basic transition method creation."""
    method = create_transition_method(
        method_name="approve",
        source="pending",
        target="approved",
        field_name="status",
    )
    assert callable(method)
    assert method.__name__ == "approve"
    assert "pending" in method.__doc__
    assert "approved" in method.__doc__


def test_create_transition_method_with_guard():
    """Test transition method with permission guard."""

    def mock_guard(instance, user=None):
        return user is not None

    method = create_transition_method(
        method_name="approve",
        source="pending",
        target="approved",
        field_name="status",
        permission_guard=mock_guard,
    )
    assert callable(method)


def test_create_transition_method_with_callbacks():
    """Test transition method with callbacks."""
    success_called = []
    error_called = []

    def on_success(instance, user=None, **kwargs):
        success_called.append(True)

    def on_error(instance, exception):
        error_called.append(True)

    method = create_transition_method(
        method_name="approve",
        source="pending",
        target="approved",
        field_name="status",
        on_success=on_success,
        on_error=on_error,
    )
    assert callable(method)


def test_factory_create_approve_method():
    """Test approval method creation."""
    factory = TransitionMethodFactory()
    method = factory.create_approve_method(source="pending", target="approved", field_name="status")
    assert callable(method)
    assert method.__name__ == "approve"


def test_factory_create_reject_method():
    """Test rejection method creation."""
    factory = TransitionMethodFactory()
    method = factory.create_reject_method(source="pending", target="rejected", field_name="status")
    assert callable(method)
    assert method.__name__ == "reject"


def test_factory_create_escalate_method():
    """Test escalation method creation."""
    factory = TransitionMethodFactory()
    method = factory.create_escalate_method(source="pending", target="escalated", field_name="status")
    assert callable(method)
    assert method.__name__ == "escalate"


def test_factory_create_generic_method():
    """Test generic transition method creation."""
    factory = TransitionMethodFactory()
    method = factory.create_generic_transition_method(
        method_name="custom_transition",
        source="pending",
        target="processed",
        field_name="status",
    )
    assert callable(method)
    assert method.__name__ == "custom_transition"


def test_factory_generic_method_with_docstring():
    """Test generic method with custom docstring."""
    factory = TransitionMethodFactory()
    custom_doc = "This is a custom transition"
    method = factory.create_generic_transition_method(
        method_name="custom_transition",
        source="pending",
        target="processed",
        field_name="status",
        docstring=custom_doc,
    )
    assert method.__doc__ == custom_doc


def test_with_transition_logging():
    """Test logging decorator wrapper."""

    def sample_transition(instance, user=None):
        return "result"

    wrapped = with_transition_logging(sample_transition)
    assert callable(wrapped)

    # Test execution (should work even if django-fsm-log not installed)
    mock_instance = Mock()
    result = wrapped(mock_instance, user=None)
    # If django-fsm-log not available, it should still execute
    assert result is not None or result is None


def test_method_signature_generation():
    """Test that generated methods have proper signatures."""
    factory = TransitionMethodFactory()
    method = factory.create_approve_method(source="pending", target="approved")

    # Check method accepts expected parameters
    mock_instance = Mock()
    mock_user = Mock()

    # Should not raise
    try:  # noqa: SIM105
        method(mock_instance, user=mock_user, comment="test")
    except Exception:
        # May fail due to django-fsm not being fully configured
        # but signature should be correct
        pass
