"""E2E tests for payer routing — route resolution through to pool submission."""

from __future__ import annotations

from typing import Any
from unittest.mock import MagicMock, patch

from claim_validator.clearinghouse.base import BaseClearinghouseClient
from claim_validator.clearinghouse.models import (
    ClearinghouseEligibilityResponse,
    SubmissionResult,
)
from claim_validator.clearinghouse.pool import ClearinghouseClientPool
from claim_validator.routing.models import PayerRoute
from claim_validator.routing.router import PayerRouter
from claim_validator.shared.code_tables.payer_routing import load_default_mapping


def _mock_client(name: str) -> MagicMock:
    c = MagicMock(spec=BaseClearinghouseClient)
    c.provider_name = name
    c.submit_claim.return_value = SubmissionResult(
        status="accepted", accepted=True, reference_id=f"{name}-REF-001",
    )
    c.check_eligibility.return_value = ClearinghouseEligibilityResponse(
        status="ok", eligible=True,
    )
    return c


class TestPayerRoutingEndToEnd:
    """Tests the full flow: load mapping -> resolve route -> pool submit."""

    def test_default_mapping_has_aetna(self) -> None:
        """Aetna (60054) is in the default mapping and can be routed."""
        router = PayerRouter()
        route = router.route("60054")
        assert isinstance(route, PayerRoute)
        assert route.priority == 1

    def test_fallback_returns_multiple_routes(self) -> None:
        """Aetna should have multiple route options."""
        router = PayerRouter()
        routes = router.route_with_fallback("60054")
        assert len(routes) >= 1
        assert all(isinstance(r, PayerRoute) for r in routes)

    @patch("claim_validator.clearinghouse.pool.get_clearinghouse_client")
    def test_pool_routes_claim_through_router(self, mock_factory: MagicMock) -> None:
        """Full flow: Pool uses PayerRouter to find clearinghouse, then submits."""
        mock_factory.return_value = _mock_client("stedi")

        custom = {"E2E_PAYER": [PayerRoute("stedi", "E2E", 1, frozenset({"837P"}))]}
        router = PayerRouter(custom_mappings=custom)
        pool = ClearinghouseClientPool(
            configs={"stedi": {"api_key": "test"}},
            router=router,
        )

        result = pool.submit_claim({"npi": "1234567893"}, "E2E_PAYER")
        assert result.accepted is True
        assert result.reference_id == "stedi-REF-001"

    @patch("claim_validator.clearinghouse.pool.get_clearinghouse_client")
    def test_pool_routes_eligibility_through_router(self, mock_factory: MagicMock) -> None:
        """Full flow: Pool routes eligibility check via PayerRouter."""
        mock_factory.return_value = _mock_client("stedi")

        custom = {"ELIG_PAYER": [PayerRoute("stedi", "EP", 1, frozenset({"270/271"}))]}
        router = PayerRouter(custom_mappings=custom)
        pool = ClearinghouseClientPool(
            configs={"stedi": {"api_key": "test"}},
            router=router,
        )

        result = pool.check_eligibility({"payer_id": "ELIG_PAYER"}, "ELIG_PAYER")
        assert result.eligible is True

    def test_custom_overrides_route_to_different_clearinghouse(self) -> None:
        """Custom mappings override defaults for specific payers."""
        custom_route = PayerRoute("custom_ch", "OVERRIDE", 1, frozenset({"837P"}))
        router = PayerRouter(custom_mappings={"60054": [custom_route]})
        result = router.route("60054")
        assert result.clearinghouse == "custom_ch"

    def test_default_mapping_entry_count(self) -> None:
        """Default mapping should have substantial payer coverage."""
        mapping = load_default_mapping()
        assert len(mapping) >= 2000
