"""Source citation checks -- verify expected sources appear in response."""

from __future__ import annotations

from typing import Callable

from finagent_evals.sources import get_source_by_id as _default_resolver


def check_sources(expected: list[str], response_text: str) -> tuple[bool, str]:
    """Check that expected source references appear in the response text."""
    if not expected:
        return (True, "")

    text_lower = response_text.lower()
    missing = [s for s in expected if s.lower() not in text_lower]

    if missing:
        return (False, f"Missing source references: {missing}")

    return (True, "")


def check_authoritative_sources(
    expected_ids: list[str],
    authoritative_sources: list[dict],
    source_resolver: Callable[[str], dict | None] | None = None,
) -> tuple[bool, str]:
    """Check that expected authoritative source IDs appear in the response's authoritative_sources field.

    Uses the bundled sources registry by default. Pass a custom ``source_resolver``
    callback ``(source_id) -> dict | None`` to override.
    """
    if not expected_ids:
        return (True, "")

    resolver = source_resolver or _default_resolver

    actual_labels = {s.get("label", "") for s in authoritative_sources}
    missing = []
    for sid in expected_ids:
        source = resolver(sid)
        if source is None:
            missing.append(f"{sid} (unknown source ID)")
            continue
        if source["label"] not in actual_labels:
            missing.append(f"{sid} ({source['label']})")

    if missing:
        return (False, f"Missing authoritative sources: {missing}")

    return (True, "")
