from .constants import TransferStatus, TransferWindowStatus
from .exceptions import TransferNotFoundError, TransferWindowNotFoundError
from .models import Transfer, TransferWindow


def get_window(*, window_id):
    try:
        return TransferWindow.objects.select_related("season").get(pk=window_id)
    except TransferWindow.DoesNotExist as exc:
        raise TransferWindowNotFoundError(
            "Transfer window does not exist."
        ) from exc


def get_active_window(*, season):
    return (
        TransferWindow.objects
        .filter(season=season, status=TransferWindowStatus.OPEN)
        .order_by("start_at")
        .first()
    )


def get_open_windows(*, season):
    return TransferWindow.objects.filter(
        season=season,
        status=TransferWindowStatus.OPEN,
    ).order_by("start_at")


def get_scheduled_windows(*, season):
    return TransferWindow.objects.filter(
        season=season,
        status=TransferWindowStatus.SCHEDULED,
    ).order_by("start_at")


def get_closed_windows(*, season):
    return TransferWindow.objects.filter(
        season=season,
        status=TransferWindowStatus.CLOSED,
    ).order_by("-end_at")


def get_cancelled_windows(*, season):
    return TransferWindow.objects.filter(
        season=season,
        status=TransferWindowStatus.CANCELLED,
    ).order_by("-start_at")


def get_windows_for_season(*, season):
    return TransferWindow.objects.filter(season=season).order_by("start_at", "id")


def get_transfer(*, transfer_id):
    try:
        return (
            Transfer.objects
            .select_related(
                "player",
                "source_club",
                "destination_club",
                "window__season",
            )
            .get(pk=transfer_id)
        )
    except Transfer.DoesNotExist as exc:
        raise TransferNotFoundError("Transfer does not exist.") from exc


def get_active_transfer_for_player(*, player):
    return (
        Transfer.objects
        .select_related("source_club", "destination_club", "window__season")
        .filter(player=player, status__in=Transfer.ACTIVE_STATUSES)
        .order_by("-created_at")
        .first()
    )


def get_player_transfers(*, player, season=None):
    query = Transfer.objects.filter(player=player)
    if season is not None:
        query = query.filter(window__season=season)
    return query.select_related(
        "source_club",
        "destination_club",
        "window__season",
    ).order_by("-created_at")


def get_completed_transfers_for_season(*, season):
    return (
        Transfer.objects
        .filter(window__season=season, status=TransferStatus.COMPLETED)
        .select_related("player", "source_club", "destination_club")
        .order_by("completed_at", "created_at")
    )
