import os
import logging
import logging.config
import platform
import requests
import urllib3
import json


class Config:
    VERSION = "v.2.0"
    MYHOST = platform.node()
    LOG_DIR = "logs"
    JSON_DIR = "JSON"
    LEAGUE = "vtb"
    API_URL = os.getenv("API_URL", (
        "https://basket.sportoteka.org/"
        if "uba" in LEAGUE.lower()
        # else "https://deti.russiabasket.org/"
        else "https://pro.russiabasket.org/"
    ))

    LANG = "en"
    TOKEN = os.getenv("BOT_TOKEN", "7639240596:AAH0YtdQoWZSC-_R_EW4wKAHHNLIA0F_ARY")
    GROUP_CHAT = os.getenv("GROUP_CHAT_ID", 228977654)
    TIMEOUT_ONLINE = 1
    FETCH_INTERVAL = 2
    TIMEOUT_DATA_OFF = 60

    @staticmethod
    def init_dirs():
        os.makedirs(Config.LOG_DIR, exist_ok=True)
        os.makedirs(Config.JSON_DIR, exist_ok=True)


class LoggerFactory:
    @staticmethod
    def setup_logger(name: str = __name__):
        logging_config = {
            "version": 1,
            "handlers": {
                "console": {
                    "class": "logging.StreamHandler",
                    "level": "DEBUG",
                    "formatter": "detailed",
                    "stream": "ext://sys.stdout",
                },
                "file": {
                    "class": "logging.FileHandler",
                    "level": "DEBUG",
                    "formatter": "detailed",
                    "filename": f"{Config.LOG_DIR}/GFX_{Config.MYHOST}.log",
                    "encoding": "utf-8",
                },
            },
            "loggers": {
                name: {
                    "handlers": ["console", "file"],
                    "level": "DEBUG",
                }
            },
            "formatters": {
                "detailed": {
                    "class": "logging.Formatter",
                    "format": "%(asctime)s %(levelname)-8s [%(funcName)s] - %(message)s",
                    "datefmt": "%d.%m.%Y %H:%M:%S",
                }
            },
        }
        logging.config.dictConfig(logging_config)
        return logging.getLogger(name)


Config.init_dirs()
logger = LoggerFactory.setup_logger()
urllib3.disable_warnings()


class ApiClient:
    def __init__(self, base_url: str, league: str, lang: str, logger):
        self.base_url = base_url
        self.league = league
        self.lang = lang
        self.logger = logger

    def get_json(self, endpoint: str, params: dict = None):
        url = self.base_url + endpoint
        try:
            self.logger.debug(f"GET: {url} | params: {params}")
            response = requests.get(url, params=params, verify=False, timeout=10)
            response.raise_for_status()
            return response.json()
        except requests.RequestException as e:
            self.logger.warning(f"Ошибка при запросе {url}: {e}")
            return None

    def get_box_score(self, game_id):
        return self.get_json("api/abc/games/box-score", {"Id": game_id})

    def get_game_info(self, game_id):
        return self.get_json("api/abc/games/game", {"Id": game_id, "Lang": self.lang})

    def get_play_by_play(self, game_id):
        return self.get_json("api/abc/games/play-by-play", {"Id": game_id})

    def get_live_status(self, game_id):
        return self.get_json("api/abc/games/live-status", {"id": game_id})

    def get_player_stat_season(self, player_id, season):
        return self.get_json("api/abc/players/stats", {"teamId": 0, "Tag": self.league, "season": season, "Id": player_id})

    def get_player_stat_career(self, player_id):
        return self.get_json("api/abc/players/career", {"teamId": 0, "Tag": self.league, "Id": player_id})

    def get_coach_stat(self, coach_id, season, team_id):
        return self.get_json("api/abc/coaches/career", {"teamId": team_id, "tag": self.league, "season": season, "Id": coach_id})

    def get_combined_game_data(self, game_id):
        box_score = self.get_box_score(game_id)
        if not box_score:
            return None

        if box_score.get("status") != "Ok":
            return self.get_game_info(game_id)

        game_info = self.get_game_info(game_id)
        play_by_play = self.get_play_by_play(game_id)

        if not game_info or not play_by_play:
            return None

        for index_team, team_data in enumerate(game_info["result"].get("teams", [])[1:]):
            for s in team_data.get("starts", []):
                matching_stats = next(
                    (stat for stat in box_score["result"]["teams"][index_team]["starts"] if stat["startNum"] == s["startNum"]),
                    None
                )
                if matching_stats:
                    s["stats"] = matching_stats
            team_data["total"] = box_score["result"]["teams"][index_team].get("total", {})

        game_info["result"]["plays"] = play_by_play.get("result", [])
        game_info["result"]["scoreByPeriods"] = box_score["result"].get("scoreByPeriods", [])
        game_info["result"]["fullScore"] = box_score["result"].get("fullScore", {})
        return game_info


def rewrite_file(filename, data):
    filepath = os.path.join(Config.JSON_DIR, f"{filename}.json")
    try:
        with open(filepath, "w", encoding="utf-8") as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
        logger.debug(f"Файл {filepath} перезаписан.")
    except Exception as e:
        logger.error(f"Не удалось записать {filepath}: {e}")


def safe_int(value, default=0):
    try:
        return int(value)
    except (ValueError, TypeError):
        return default


def format_time(seconds):
    try:
        minutes = int(seconds // 60)
        seconds = int(seconds % 60)
        return f"{minutes}:{seconds:02}"
    except Exception:
        return "0:00"


def safe_percent(numerator, denominator):
    try:
        n = safe_int(numerator)
        d = safe_int(denominator)
        return f"{round(n * 100 / d, 1)}%" if d != 0 else "0.0%"
    except Exception:
        return "0.0%"


class TeamStatBuilder:
    def __init__(self, api_client: ApiClient):
        self.api = api_client

    def build_team_json(self, team_data, season, team_id, game_id, team_key):
        players = []
        for player in team_data.get("starts", []):
            person_id = player.get("personId")
            if not person_id:
                continue
            stat_season = self.api.get_player_stat_season(person_id, season)
            stat_career = self.api.get_player_stat_career(person_id)
            player_info = {
                "id": person_id,
                "name": player.get("name"),
                "position": player.get("position"),
                "stats": player.get("stats", {}),
                "seasonStats": stat_season.get("result") if stat_season else {},
                "careerStats": stat_career.get("result") if stat_career else {}
            }
            players.append(player_info)

        coach_id = team_data.get("coachId")
        coach_stats = self.api.get_coach_stat(coach_id, season, team_id) if coach_id else {}

        return {
            "teamId": team_id,
            "teamKey": team_key,
            "players": players,
            "coachStats": coach_stats.get("result") if coach_stats else {},
            "total": team_data.get("total", {})
        }


def process_game(game_id):
    api = ApiClient(Config.API_URL, Config.LEAGUE, Config.LANG, logger)
    team_builder = TeamStatBuilder(api)

    logger.info(f"Обработка игры {game_id}...")
    data = api.get_combined_game_data(game_id)
    if not data or "result" not in data:
        logger.error("Нет данных для обработки игры.")
        return

    result = data["result"]
    season = result.get("season")
    teams = result.get("teams", [])

    if len(teams) < 3:
        logger.error("Недостаточно данных о командах.")
        return

    team1 = team_builder.build_team_json(teams[1], season, result.get("team1Id"), game_id, "team1")
    team2 = team_builder.build_team_json(teams[2], season, result.get("team2Id"), game_id, "team2")

    rewrite_file("team1", team1)
    rewrite_file("team2", team2)

    top1 = sorted(team1["players"], key=lambda x: x["stats"].get("efficiency", 0), reverse=True)[:5]
    top2 = sorted(team2["players"], key=lambda x: x["stats"].get("efficiency", 0), reverse=True)[:5]

    rewrite_file("topTeam1", top1)
    rewrite_file("topTeam2", top2)

    logger.info("Готово!")


process_game(916116)