"""Smoke tests for handler registration."""

import pytest

from entr_adapter_core.app import Dispatcher
from entr_adapter_core.schemas import DocumentPayload, StatusEnum

from tests.mock_handler import (
    MockProcessHandler,
    MockRetrievalHandler,
    MockReviewHandler,
)


class TestHandlerRegistration:

    def test_single_handler_registration(self):
        d = Dispatcher(handlers={"mock": MockProcessHandler()})
        assert d.get_handler_identifiers() == ["mock"]

    def test_multiple_handler_registration(self):
        d = Dispatcher(handlers={
            "mock": MockProcessHandler(),
            "review": MockReviewHandler(),
        })
        ids = set(d.get_handler_identifiers())
        assert ids == {"mock", "review"}

    @pytest.mark.asyncio
    async def test_handler_with_retrieval_handler(self):
        retrieval = MockRetrievalHandler()
        handler = MockProcessHandler(retrieval_handler=retrieval)
        d = Dispatcher(handlers={"mock": handler})
        from entr_adapter_core.schemas import RetrievalPayload

        payload = RetrievalPayload(source_identifier="mock", date_from="2026-01-01")
        response = await d.dispatch_list_documents("mock", payload)
        assert response.status.value == "success"
        assert len(response.documents) == 2

    @pytest.mark.asyncio
    async def test_handler_without_retrieval_handler(self):
        d = Dispatcher(handlers={"mock": MockProcessHandler()})
        from entr_adapter_core.schemas import RetrievalPayload

        payload = RetrievalPayload(source_identifier="mock", date_from="2026-01-01")
        response = await d.dispatch_list_documents("mock", payload)
        assert response.status.value == "failed"
        assert "No retrieval handler" in response.message

    def test_duplicate_identifier_last_wins(self):
        handler_a = MockProcessHandler()
        handler_b = MockReviewHandler()
        d = Dispatcher(handlers={"mock": handler_a, "mock": handler_b})
        # Python dict: last value wins for duplicate keys
        assert d.get_handler_identifiers() == ["mock"]

    @pytest.mark.asyncio
    async def test_handler_is_singleton(self):
        handler = MockProcessHandler()
        d = Dispatcher(handlers={"mock": handler})

        payload1 = DocumentPayload(
            adapter_identifier="mock", document_id=1,
            data={"invoice_number": "INV-001"},
        )
        payload2 = DocumentPayload(
            adapter_identifier="mock", document_id=2,
            data={"invoice_number": "INV-002"},
        )

        resp1 = await d.dispatch_process(payload1)
        resp2 = await d.dispatch_process(payload2)

        # Both used the same handler instance (singleton)
        assert resp1.status == StatusEnum.SUCCESS
        assert resp2.status == StatusEnum.SUCCESS
        assert resp1.document_id == 1
        assert resp2.document_id == 2
