# See examples at: https://lol.fandom.com/wiki/Help:Leaguepedia_API

import json
import os
import sys
from datetime import datetime, timedelta
from functools import wraps

sys.path.append(os.path.dirname(os.path.dirname(__file__)))

from src.lolpedia_api import (
    AuthCredentials,
    LeaguepediaClient,
    and_,
    logger,
    select,
    tables,
)

P = tables.Player
PR = tables.PlayerRedirect
T = tables.Tournament
TP = tables.TournamentPlayer
SG = tables.ScoreboardGame
MSG = tables.MatchScheduleGame
MS = tables.MatchSchedule
SP = tables.ScoreboardPlayer
SG = tables.ScoreboardGame


def log_result(fn):
    @wraps(fn)
    def wrapper(*args, **kwargs):
        result = fn(*args, **kwargs)
        logger.logger.info(fn.__name__)
        logger.logger.info(json.dumps(result, indent=4))
        return result

    return wrapper


@log_result
def get_score_board_games(client: LeaguepediaClient):
    statement = (
        select(T.Name, SG.DateTime_UTC, SG.Team1, SG.Team2)
        .select_from(SG)
        .join(T, SG.OverviewPage == T.OverviewPage)
        .limit(10)  # Not in original but meh
    )
    return client.execute_query(statement)


@log_result
def get_score_board_games_after(client: LeaguepediaClient):
    statement = (
        select(T.Name, SG.DateTime_UTC, SG.Team1, SG.Team2)
        .select_from(SG)
        .join(T, SG.OverviewPage == T.OverviewPage)
        .where(SG.DateTime_UTC >= datetime(2019, 8, 1))
        .limit(10)  # Not in original but meh
    )
    return client.execute_query(statement)


@log_result
def get_scheduled_game(client: LeaguepediaClient, page_to_query: str):
    statement = (
        select(MSG.OverviewPage, MSG.RiotPlatformGameId)
        .select_from(MSG)
        .join(MS, MSG.MatchId == MS.MatchId)
        .where(
            and_(
                MSG._pageName == page_to_query,
                MSG.RiotPlatformGameId.is_not(None),
            )
        )
        .order_by(MS.N_Page, MS.N_MatchInPage, MSG.N_GameInMatch)
        .limit(3)
    )

    return client.execute_query(statement)


@log_result
def get_game_in_between(client: LeaguepediaClient, date: datetime):
    statement = (
        select(
            T.Name,  # .label not implemented
            SG.DateTime_UTC,
            SG.Team1,
            SG.Team2,
            SG.Winner,
            SG.Patch,
            SP.Link,
            SP.Team,
            SP.Champion,
            SP.SummonerSpells,
            SP.KeystoneMastery,
            SP.KeystoneRune,
            SP.Role,
            SP.GameId,
            SP.Side,
        )
        .select_from(SG)
        .join(SP, SG.GameId == SP.GameId)
        .join(T, SG.OverviewPage == T.OverviewPage)
        .where(
            and_(
                SG.DateTime_UTC >= datetime(2020, 1, 25),
                SG.DateTime_UTC <= date + timedelta(1),
            )
        )
        .limit(3)
    )

    return client.execute_query(statement)


@log_result
def get_lec_player_info(client: LeaguepediaClient):
    statement = (
        select(P.Player, P.Name, P.Country, P.Birthdate, P.Residency, P.Role)
        .select_from(T)
        .join(TP, T.OverviewPage == TP.OverviewPage)
        .join(PR, TP.Player == PR.AllName)
        .join(P, PR.OverviewPage == P.OverviewPage)
        .where(
            and_(
                T.League == "LoL EMEA Championship",
                P.Player.is_not(None),
            )
        )
        .group_by(P.OverviewPage)
        .limit(20)
    )

    return client.execute_query(statement)


if __name__ == "__main__":
    import argparse
    import logging

    logging.basicConfig(
        format="%(asctime)s %(levelname)s %(message)s",
        level=logging.INFO,
        stream=sys.stdout,
    )

    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--example", "-e", help="Example to run (e.g., score_board_games)"
    )
    args = parser.parse_args()

    creds = AuthCredentials(user_file="bot")
    client = LeaguepediaClient(creds)

    examples = {
        "score_board_games": lambda: get_score_board_games(client),
        "score_board_after": lambda: get_score_board_games_after(client),
        "scheduled_game": lambda: get_scheduled_game(
            client, "Data:2023 Mid-Season Invitational"
        ),
        "game_between": lambda: get_game_in_between(client, datetime(2020, 1, 25)),
        "lec_players": lambda: get_lec_player_info(client),
    }

    if args.example:
        if args.example in examples:
            examples[args.example]()
        else:
            print(f"Unknown example: {args.example}")
            print(f"Available: {', '.join(examples.keys())}")
    else:
        print(f"Available examples: {', '.join(examples.keys())}")
