"""Keep a broadcast presentation inside the race office's active matchup.

The occupancy history can legitimately contain still-open claims from an earlier heat.  The
instance team configuration is the race office's explicit presentation of the matchup; when it is
present, teams outside it must not become grey rows, camera targets, or scoring entries.
"""

from __future__ import annotations


def active_presentation_roster(
    roster: dict[str, list[str]] | None,
    team_config: dict | None,
) -> tuple[dict[str, list[str]], list[str]]:
    """Return ``(roster, boats)`` limited to explicitly active teams when available.

    An absent team configuration preserves the complete resolved roster for backwards compatibility.
    The filter is by team id, not by the configuration's hull list: race-day hull substitutions are
    authoritative in the occupancy roster and must continue to work.
    """
    resolved = roster if isinstance(roster, dict) else {}
    if team_config:
        active = set(team_config)
        resolved = {team: list(boats or []) for team, boats in resolved.items() if team in active}
    boats = sorted({boat for team_boats in resolved.values() for boat in team_boats})
    return resolved, boats
