"""One clock-based registration gate shared by every player acquisition path."""

from django.utils import timezone


def recruitment_error(
    *, club, player=None, source_club=None, season=None, now=None, window=None
):
    from contracts.models import Contract
    from leagues.models import LeagueMembership
    from seasons.models import Season, SeasonAutomationPolicy
    from transfers.models import TransferWindow

    now = now or timezone.now()
    if season is None:
        season = Season.objects.filter(status="ACTIVE").first()
        if season is None:
            season = (
                Season.objects.filter(status="UPCOMING").order_by("start_date").first()
            )
    if season is None:
        return None  # Bootstrap clubs before the first season is configured.
    if season.status == "UPCOMING" and Season.objects.filter(status="ACTIVE").exclude(pk=season.pk).exists():
        return "The current season must finish before recruitment through a future season window."
    contracted = source_club is not None
    if player is not None:
        contracted = (
            contracted
            or Contract.objects.filter(player=player, status="ACTIVE").exists()
        )
    member = LeagueMembership.objects.filter(
        club=club,
        season=season,
        status="REGISTERED",
    ).exists()
    if not member and not contracted:
        return None  # Outside the league, only genuinely free players may be recruited.
    policy = SeasonAutomationPolicy.objects.filter(season=season).first()
    if policy:
        if season.status not in {"UPCOMING", "ACTIVE"}:
            return "Player recruitment is unavailable for this season."
        in_preseason = policy.registration_opens_at <= now < policy.starts_at
        in_midseason = (
            season.status == "ACTIVE"
            and policy.midseason_opens_at <= now < policy.midseason_closes_at
        )
        if not (in_preseason or in_midseason):
            return "Transfer window is closed: league teams may recruit only before kickoff or during the midseason window."
        if window is not None and (
            window.season_id != season.pk
            or not (window.start_at <= now < window.end_at)
            or window.status != "OPEN"
        ):
            return "The selected transfer window is not currently open."
        return None
    if member or contracted:
        if window is not None:
            # The legacy window rule validates its locked window object and timestamps.
            return None
        opened = TransferWindow.objects.filter(
            season=season, status="OPEN", start_at__lte=now, end_at__gt=now
        )
        if not opened.exists():
            return "Transfer window is closed."
    return None


def assert_recruitment(**kwargs):
    from contracts.exceptions import InvalidContractOfferError

    error = recruitment_error(**kwargs)
    if error:
        raise InvalidContractOfferError(error)
