import os
import json
import socket
import platform
import numpy as np
import pandas as pd
import streamlit as st
import sys
from streamlit_autorefresh import st_autorefresh

st.set_page_config(
    page_title="Баскетбол",
    page_icon="🏀",
    layout="wide",
    initial_sidebar_state="expanded",
    menu_items={"About": "версия 1.8 22.01.2025"},
)
REMOVE_PADDING_FROM_SIDES = """
<style>
    .block-container {
        padding-top: 0rem;
        padding-bottom: 0rem;
    }   
</style>
"""

st.markdown(REMOVE_PADDING_FROM_SIDES, unsafe_allow_html=True)
st_autorefresh()


# Функции для стилизации
def highlight_max(data):
    # Преобразуем данные к числовому типу, заменяя некорректные значения на NaN
    numeric_data = pd.to_numeric(data, errors="coerce")
    max_value = numeric_data.max() if pd.notna(numeric_data.max()) else None
    return [
        "background-color: green" if pd.notna(v) and v == max_value and v > 0 else ""
        for v in numeric_data
    ]


def color_win(s):
    return [
        (
            "background-color: ForestGreen"
            if v == True
            else "background-color: #FF4B4B" if v == False else None
        )
        for v in s
    ]


def highlight_grey(s):
    return ["background-color: grey"] * len(s) if s.foul == 5 else [""] * len(s)


def highlight_foul(s):
    return [
        (
            "background-color: orange"
            if v == 4
            else "background-color: red" if v == 5 else ""
        )
        for v in s
    ]


def load_json_data(filepath):
    """
    Загружает данные из JSON файла и кэширует их.
    Возвращает None, если файл не удается прочитать.
    """
    try:
        with open(filepath, "r", encoding="utf-8") as file:
            return json.load(file)
    except (json.JSONDecodeError, FileNotFoundError):
        return None


# Функция для обработки данных одной команды
def process_team_data(team_json, columns_to_include):
    team_data = pd.json_normalize(team_json)

    # Оставляем только нужные колонки
    team_data = team_data[:12][columns_to_include]

    # Обработка height и weight
    for column in ["height", "weight"]:
        if column in team_data.columns:
            team_data[column] = team_data[column].apply(
                lambda value: "" if value == 0 else value
            )

    return team_data


def process_player_data(team_json, player_index):
    team_data = pd.json_normalize(team_json)
    player_data = team_data.iloc[player_index]
    season_total = {
        "name": "Season Total",
        "game_count": str(player_data["TGameCount"]),
        "start_count": str(player_data["TStartCount"]),
        "pts": str(player_data["TPoints"]),
        "pt-2": str(player_data["TShots2"]),
        "pt-3": str(player_data["TShots3"]),
        "pt-1": str(player_data["TShots1"]),
        "fg": str(player_data["TShots23"]),
        "ast": str(player_data["TAssist"]),
        "stl": str(player_data["TSteal"]),
        "blk": str(player_data["TBlocks"]),
        "dreb": str(player_data["TDefRebound"]),
        "oreb": str(player_data["TOffRebound"]),
        "reb": str(player_data["TRebound"]),
        # "to": str(player_data["TTurnover"]),
        # "foul": str(player_data["TFoul"]),
        "fouled": str(player_data["TOpponentFoul"]),
        "dunk": str(player_data["TDunk"]),
        "time": str(player_data["TPlayedTime"]),
    }
    season_avg = {
        "name": "Season Average",
        "game_count": "",
        "start_count": "",
        "pts": str(player_data["AvgPoints"]),
        "pt-2": str(player_data["Shot2Percent"]),
        "pt-3": str(player_data["Shot3Percent"]),
        "pt-1": str(player_data["Shot1Percent"]),
        "fg": str(player_data["Shot23Percent"]),
        "ast": str(player_data["AvgAssist"]),
        "stl": str(player_data["AvgSteal"]),
        "blk": str(player_data["AvgBlocks"]),
        "dreb": str(player_data["AvgDefRebound"]),
        "oreb": str(player_data["AvgOffRebound"]),
        "reb": str(player_data["AvgRebound"]),
        # "to": str(player_data["AvgTurnover"]),
        # "foul": str(player_data["AvgFoul"]),
        "fouled": str(player_data["AvgOpponentFoul"]),
        "dunk": str(player_data["AvgDunk"]),
        "time": str(player_data["AvgPlayedTime"]),
    }
    career_total = {
        "name": "Career Total",
        "game_count": str(player_data["CareerTGameCount"]),
        "start_count": str(player_data["CareerTStartCount"]),
        "pts": str(player_data["CareerTPoints"]),
        "pt-2": str(player_data["CareerTShots2"]),
        "pt-3": str(player_data["CareerTShots3"]),
        "pt-1": str(player_data["CareerTShots1"]),
        "fg": str(player_data["CareerTShots23"]),
        "ast": str(player_data["CareerTAssist"]),
        "stl": str(player_data["CareerTSteal"]),
        "blk": str(player_data["CareerTBlocks"]),
        "dreb": str(player_data["CareerTDefRebound"]),
        "oreb": str(player_data["CareerTOffRebound"]),
        "reb": str(player_data["CareerTRebound"]),
        # "to": str(player_data["CareerTTurnover"]),
        # "foul": str(player_data["CareerTFoul"]),
        "fouled": str(player_data["CareerTOpponentFoul"]),
        "dunk": str(player_data["CareerTDunk"]),
        "time": str(player_data["CareerTPlayedTime"]),
    }

    return [season_total, season_avg, career_total], player_data


config = {
    "flag": st.column_config.ImageColumn("flag"),
    "roleShort": st.column_config.TextColumn("R", width=27),
    "num": st.column_config.TextColumn("#", width=27),
    "NameGFX": st.column_config.TextColumn(width=170),
    "isOn": st.column_config.TextColumn("🏀", width=27),
    "pts": st.column_config.NumberColumn("PTS", width=27),
    "pt-2": st.column_config.TextColumn("2-PT", width=45),
    "pt-3": st.column_config.TextColumn("3-PT", width=45),
    "pt-1": st.column_config.TextColumn("FT", width=45),
    "fg": st.column_config.TextColumn("FG", width=45),
    "ast": st.column_config.NumberColumn("AS", width=27),
    "stl": st.column_config.NumberColumn("ST", width=27),
    "blk": st.column_config.NumberColumn("BL", width=27),
    "blkVic": st.column_config.NumberColumn("BV", width=27),
    "dreb": st.column_config.NumberColumn("DR", width=27),
    "oreb": st.column_config.NumberColumn("OR", width=27),
    "reb": st.column_config.NumberColumn("R", width=27),
    "to": st.column_config.NumberColumn("TO", width=27),
    "foul": st.column_config.NumberColumn("F", width=27),
    "fouled": st.column_config.NumberColumn("Fed", width=27),
    "plusMinus": st.column_config.NumberColumn("+/-", width=27),
    "dunk": st.column_config.NumberColumn("DUNK", width=27),
    "kpi": st.column_config.NumberColumn("KPI", width=27),
    "time": st.column_config.TextColumn("TIME"),
    "game_count": st.column_config.TextColumn("G", width=27),
    "start_count": st.column_config.TextColumn("S", width=27),
    "q_pts": st.column_config.TextColumn("PTS", width=27),
    "q_ast": st.column_config.TextColumn("AS", width=27),
    "q_stl": st.column_config.TextColumn("ST", width=27),
    "q_blk": st.column_config.TextColumn("BL", width=27),
    "q_reb": st.column_config.TextColumn("R", width=27),
    "q_rnk": st.column_config.TextColumn("KPI", width=27),
    "q_f": st.column_config.TextColumn("F", width=27),
    "q_f_on": st.column_config.TextColumn("Fed", width=27),
    "q_to": st.column_config.TextColumn("TO", width=27),
    "q_time": st.column_config.TextColumn("TIME"),
    "q_pt2": st.column_config.TextColumn("2-PT", width=45),
    "q_pt3": st.column_config.TextColumn("3-PT", width=45),
    "q_pt23": st.column_config.TextColumn("FG", width=45),
    "q_ft": st.column_config.TextColumn("FT", width=45),
}
config_season = {
    "flag": st.column_config.ImageColumn("flag"),
    "roleShort": st.column_config.TextColumn("R", width=27),
    "num": st.column_config.TextColumn("#", width=27),
    "NameGFX": st.column_config.TextColumn(width=170),
    "isOn": st.column_config.TextColumn("🏀", width=27),
    "pts": st.column_config.TextColumn("PTS", width=40),
    "pt-2": st.column_config.TextColumn("2-PT", width=60),
    "pt-3": st.column_config.TextColumn("3-PT", width=60),
    "pt-1": st.column_config.TextColumn("FT", width=60),
    "fg": st.column_config.TextColumn("FG", width=60),
    "ast": st.column_config.TextColumn("AS", width=40),
    "stl": st.column_config.TextColumn("ST", width=40),
    "blk": st.column_config.TextColumn("BL", width=40),
    "blkVic": st.column_config.TextColumn("BV", width=40),
    "dreb": st.column_config.TextColumn("DR", width=40),
    "oreb": st.column_config.TextColumn("OR", width=40),
    "reb": st.column_config.TextColumn("R", width=40),
    "to": st.column_config.TextColumn("TO", width=40),
    "foul": st.column_config.TextColumn("F", width=40),
    "fouled": st.column_config.TextColumn("Fed", width=40),
    "plusMinus": st.column_config.TextColumn("+/-", width=40),
    "dunk": st.column_config.TextColumn("DUNK", width=40),
    "kpi": st.column_config.TextColumn("KPI", width=40),
    "time": st.column_config.TextColumn("TIME"),
    "game_count": st.column_config.TextColumn("G", width=40),
    "start_count": st.column_config.TextColumn("S", width=40),
}

if "player1" not in st.session_state:
    st.session_state.player1 = None
if "player2" not in st.session_state:
    st.session_state.player2 = None


myhost = platform.node()
if sys.platform.startswith("win"):   # было: if platform == "win32":
    FOLDER_JSON = "JSON"
else:
    FOLDER_JSON = "static"

def get_ip_address():
    try:
        # Попытка получить IP-адрес с использованием внешнего сервиса
        # Может потребоваться подключение к интернету
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("8.8.8.8", 80))
        ip_address = s.getsockname()[0]
    except socket.error:
        # Если не удалось получить IP-адрес через внешний сервис,
        # используем метод для локального получения IP
        ip_address = socket.gethostbyname(socket.gethostname())
    return ip_address


def load_data_from_json(filepath):
    directory = FOLDER_JSON
    os.makedirs(directory, exist_ok=True)
    filepath_full = os.path.join(directory, f"{filepath}.json")

    ip = get_ip_address()
    host = ip_check.get(ip, {}).get("host") or ""   # безопаснее

    # Ключ в session_state: <имя файла> без префикса <host>_
    # Пример: static/abc_game_online.json -> game_online
    base = os.path.basename(filepath_full).replace(".json","")
    key  = base.replace(f"{host}_", "", 1)

    temp = load_json_data(filepath_full)  # None, если нет файла/парсинга
    st.session_state[key] = temp          # ключ гарантированно создаётся

try:
    with open("match_id.json", "r", encoding="utf-8") as f:
        ip_check = json.load(f)
except (FileNotFoundError, json.JSONDecodeError):
    ip_check = {}

ip_address = get_ip_address()
prefix = ip_check.get(ip_address, {}).get("host")


load_data_from_json(f"{prefix}_game_online")
cached_game_online = st.session_state.get("game_online")

load_data_from_json(f"{prefix}_team1")
cached_team1 = st.session_state.get("team1")

load_data_from_json(f"{prefix}_team2")
cached_team2 = st.session_state.get("team2")

load_data_from_json(f"{prefix}_referee")
cached_referee = st.session_state.get("referee")

# standings — может не быть тега/файла
league_tag = None
if isinstance(cached_game_online, dict):
    league_tag = ((cached_game_online.get("result") or {}).get("league") or {}).get("tag")
if league_tag:
    load_data_from_json(f"{prefix}_standings_{league_tag}")
cached_standings = st.session_state.get(f"standings_{league_tag}") if league_tag else None

load_data_from_json(f"{prefix}_scores_quarter")
cached_scores_quarter = st.session_state.get("scores_quarter")

load_data_from_json(f"{prefix}_play_by_play")
cached_play_by_play = st.session_state.get("play_by_play")

load_data_from_json(f"{prefix}_team_stats")
cached_team_stats = st.session_state.get("team_stats")

load_data_from_json(f"{prefix}_scores")
cached_scores = st.session_state.get("scores") or []   # важно!

load_data_from_json(f"{prefix}_live_status")
cached_live_status = st.session_state.get("live_status")

load_data_from_json(f"{prefix}_schedule")
cached_schedule = st.session_state.get("schedule")

# st.session_state
def ensure_state(key: str, default=None):
    # Инициализирует ключ один раз и возвращает значение
    return st.session_state.setdefault(key, default)


period_max = 0
if isinstance(cached_play_by_play, list) and isinstance(cached_game_online, dict):
    plays = (cached_game_online.get("result") or {}).get("plays") or []
    if plays:
        df_data_pbp = pd.DataFrame(cached_play_by_play)
        if not df_data_pbp.empty and "period" in df_data_pbp.columns:
            period_max = int(df_data_pbp.iloc[0]["period"])
            count_quarter = [
                f"Четверть {i}" if i < 5 else f"Овертайм {i-4}"
                for i in range(1, period_max + 1)
            ]

            for i in range(1, period_max + 1):
                key_team1 = f"team1_{i}"
                key_team2 = f"team2_{i}"
                load_data_from_json(key_team1)
                load_data_from_json(key_team2)
                _q1 = st.session_state.get(key_team1)  # может быть None — это ок
                _q2 = st.session_state.get(key_team2)


timeout1 = []
timeout2 = []

if isinstance(cached_game_online, dict):
    result = cached_game_online.get("result") or {}
    plays  = result.get("plays") or []

    timeout1, timeout2 = [], []
    for event in plays:
        if isinstance(event, dict) and event.get("play") == 23:
            if event.get("startNum") == 1:
                timeout1.append(event)
            elif event.get("startNum") == 2:
                timeout2.append(event)

    col1, col4, col2, col5, col3 = st.columns([1, 5, 3, 5, 1])

    t1 = (result.get("team1") or {})
    t2 = (result.get("team2") or {})
    if t1.get("logo"):
        col1.image(t1["logo"], width=100)
    team1_name = t1.get("name") or ""
    team2_name = t2.get("name") or ""
    if team1_name or team2_name:
        col2.markdown(
            f"<h2 style='text-align: center'>{team1_name} — {team2_name}</h2>",
            unsafe_allow_html=True,
        )
    if t2.get("logo"):
        col3.image(t2["logo"], width=100)

    col4_1, col4_2, col4_3 = col4.columns((1, 1, 1))
    col5_1, col5_2, col5_3 = col5.columns((1, 1, 1))

    # Points метрики безопасно
    val1 = val2 = None
    if isinstance(cached_team_stats, list) and len(cached_team_stats) > 0:
        v1 = cached_team_stats[0].get("val1")
        v2 = cached_team_stats[0].get("val2")
        if v1 is not None and v2 is not None:
            val1, val2 = int(v1), int(v2)
            delta_color_1 = "off" if val1 == val2 else "normal"
            col4_1.metric("Points", v1, val1 - val2, delta_color_1)
            col5_3.metric("Points", v2, val2 - val1, delta_color_1)

    col4_3.metric("TimeOuts", len(timeout1))
    col5_1.metric("TimeOuts", len(timeout2))

    if isinstance(cached_live_status, list) and cached_live_status:
        foulsA = (cached_live_status[0] or {}).get("foulsA")
        foulsB = (cached_live_status[0] or {}).get("foulsB")
        if foulsA is not None:
            col4_2.metric("Fouls", foulsA)
        if foulsB is not None:
            col5_2.metric("Fouls", foulsB)


if isinstance(cached_game_online, dict) and ((cached_game_online.get("result") or {}).get("plays") or []):
    col_1_col = [f"col_1_{i}" for i in range(1, period_max + 1)]
    col_2_col = [f"col_2_{i}" for i in range(1, period_max + 1)]
    count_q = 0

    score_by_quarter_1 = [x.get("score1") for x in cached_scores if isinstance(x, dict) and x.get("score1") not in ("", None)]
    score_by_quarter_2 = [x.get("score2") for x in cached_scores if isinstance(x, dict) and x.get("score2") not in ("", None)]

    if score_by_quarter_1:
        col_1_col = col4.columns([1 for _ in range(len(score_by_quarter_1))])
        col_2_col = col5.columns([1 for _ in range(len(score_by_quarter_2))])

    for q1, q2, col1_i, col2_i in zip(score_by_quarter_1, score_by_quarter_2, col_1_col, col_2_col):
        count_q += 1
        name_q = f"OT{count_q-4}" if count_q > 4 else f"Q{count_q}"
        try:
            delta_color = "off" if int(q1) == int(q2) else "normal"
            col1_i.metric(name_q, q1, int(q1) - int(q2), delta_color, border=True)
            col2_i.metric(name_q, q2, int(q2) - int(q1), delta_color, border=True)
        except (ValueError, TypeError):
            # если кривые данные в JSON, просто пропустим
            pass



(
    tab_temp_1,
    tab_temp_2,
    tab_temp_3,
    tab_temp_4,
    tab_temp_5,
    tab_temp_6,
    tab_pbp,
    tab_temp_7,
    tab_temp_8,
    tab_schedule,
) = st.tabs(
    [
        "Игроки",
        "Команды",
        "Судьи",
        "Турнирная таблица",
        "Статистика четвертей",
        "Ход игры",
        "События игры",
        "Статистика по четвертям",
        "Milestones",
        "Прошедшие/будущие матчи",
    ]
)


def check_milestone(value, milestone_type, name, num, where):
    milestone_checks = {
        "PTS": "point",
        "AST": "assist",
        "BLK": "block",
        "REB": "rebound",
        "DREB": "defensive rebound",
        "OREB": "offensive rebound",
        "STL": "steal",
        "GAMES": "game",
    }
    if milestone_type == "GAMES":
        list_data = [*range(50, 5100, 50)]
        if int(value) % 100 in [49, 99]:
            diff = [l - int(value) for l in list_data]
            positive_numbers = [num for num in diff if num > -1]
            count = 0
            for i in diff:
                count += 1
                if i == min(positive_numbers):
                    break
            full_word = [
                word
                for w, word in milestone_checks.items()
                if w.lower() == milestone_type.lower()
            ][0]
            # print(positive_numbers)
            if min(positive_numbers) != 0:
                word = full_word if min(positive_numbers) == 1 else f"{full_word}s"
                if where == "season":
                    where = "in this season"
                elif where == "league":
                    where = "in career VTB"
                string_value = f"{name} needs {min(positive_numbers)} {word} to reach {list_data[count-1]} {full_word}s {where}"
            else:
                string_value = ""
            return {
                "NameGFX": f"{name} ({num})",
                "type": milestone_type.upper(),
                "value": value,
                "string_value": string_value,
            }
    else:
        list_data = [*range(100, 5100, 100)]
        if (int(value) % 100) >= 90 or (int(value) % 1000) in list_data:
            diff = [l - int(value) for l in list_data]
            positive_numbers = [num for num in diff if num > -1]
            count = 0
            for i in diff:
                count += 1
                if i == min(positive_numbers):
                    break
            # print(positive_numbers)
            full_word = [
                word
                for w, word in milestone_checks.items()
                if w.lower() == milestone_type.lower()
            ][0]
            # print(positive_numbers)
            if min(positive_numbers) != 0:
                word = full_word if min(positive_numbers) == 1 else f"{full_word}s"
                if where == "season":
                    where = "in this season"
                elif where == "league":
                    where = "in career VTB"
                string_value = f"{name} needs {min(positive_numbers)} {word} to reach {list_data[count-1]} {full_word}s {where}"
            else:
                string_value = ""
            return {
                "NameGFX": f"{name} ({num})",
                "type": milestone_type.upper(),
                "value": value,
                "string_value": string_value,
            }
    return None


def milestones(data):
    new_data_season = []
    new_data_career = []
    for d in data:
        if d["startRole"] == "Player":
            milestone_checks = {
                "PTS": d["TPoints"],
                "AST": d["TAssist"],
                "BLK": d["TBlocks"],
                "REB": d["TRebound"],
                "DREB": d["TDefRebound"],
                "OREB": d["TOffRebound"],
                "STL": d["TSteal"],
                "GAMES": d["TGameCount"],
            }
            milestone_career_checks = {
                "PTS": d["CareerTPoints"],
                "AST": d["CareerTAssist"],
                "BLK": d["CareerTBlocks"],
                "REB": d["CareerTRebound"],
                "DREB": d["CareerTDefRebound"],
                "OREB": d["CareerTOffRebound"],
                "STL": d["CareerTSteal"],
                "GAMES": d["CareerTGameCount"],
            }
            for milestone_type, value in milestone_checks.items():
                milestone_data = check_milestone(
                    value, milestone_type, d["NameGFX"], d["num"], "season"
                )
                if milestone_data:
                    new_data_season.append(milestone_data)
            for milestone_type_car, value_car in milestone_career_checks.items():
                milestone_data_car = check_milestone(
                    value_car, milestone_type_car, d["NameGFX"], d["num"], "league"
                )
                if milestone_data_car:
                    new_data_career.append(milestone_data_car)
    return new_data_season, new_data_career


columns_game = [
    "num",
    # "roleShort",
    "NameGFX",
    "isOn",
    # "flag",
    "pts",
    "pt-2",
    "pt-3",
    "pt-1",
    "fg",
    "ast",
    "stl",
    "blk",
    "blkVic",
    "dreb",
    "oreb",
    "reb",
    "to",
    "foul",
    "fouled",
    "plusMinus",
    "dunk",
    "kpi",
    "time",
]
if cached_team1 and cached_team2:
    team1_data = process_team_data(cached_team1, columns_game)
    team2_data = process_team_data(cached_team2, columns_game)


    # Стилизация данных
    team1_styled = (
        team1_data.style.apply(highlight_grey, axis=1)
        .apply(highlight_foul, subset="foul")
        .apply(highlight_max, subset="pts")
    )
    team2_styled = (
        team2_data.style.apply(highlight_grey, axis=1)
        .apply(highlight_foul, subset="foul")
        .apply(highlight_max, subset="pts")
    )

    # Вывод данных
    col_player1, col_player2 = tab_temp_1.columns((5, 5))
    event1 = col_player1.dataframe(
        team1_styled,
        column_config=config,
        hide_index=True,
        height=460,
        on_select="rerun",
        selection_mode=[
            "single-row",
        ],
    )
    event2 = col_player2.dataframe(
        team2_styled,
        column_config=config,
        hide_index=True,
        height=460,
        on_select="rerun",
        selection_mode=[
            "single-row",
        ],
    )

    if event1.selection and event1.selection.get("rows"):
        selected_index1 = event1.selection["rows"][0]
        st.session_state["player1"] = (
            selected_index1  # Сохранение состояния в session_state
        )
    if st.session_state["player1"] is not None:
        selected_player_1, player_data_1 = process_player_data(
            cached_team1, st.session_state["player1"]
        )
        if player_data_1["num"]:
            z, a, b, c, d, e = col_player1.columns((1, 6, 1, 1, 1, 1))
            z.metric("Номер", player_data_1["num"], border=False)
            a.metric("Игрок", player_data_1["NameGFX"], border=False)
            b.metric("Амплуа", player_data_1["roleShort"], border=False)
            c.metric("Возраст", player_data_1["age"], border=False)
            d.metric("Рост", player_data_1["height"].split()[0], border=False)
            e.metric("Вес", player_data_1["weight"].split()[0], border=False)

            col_player1.dataframe(
                selected_player_1,
                column_config=config_season,
                hide_index=True,
            )
    if event2.selection and event2.selection.get("rows"):
        selected_index2 = event2.selection["rows"][0]
        st.session_state["player2"] = (
            selected_index2  # Сохранение состояния в session_state
        )
    if st.session_state["player2"] is not None:
        selected_player_2, player_data_2 = process_player_data(
            cached_team2, st.session_state["player2"]
        )
        if player_data_2["num"]:
            z, a, b, c, d, e = col_player2.columns((1, 6, 1, 1, 1, 1))
            z.metric("Номер", player_data_2["num"], border=False)
            a.metric("Игрок", player_data_2["NameGFX"], border=False)
            b.metric("Амплуа", player_data_2["roleShort"], border=False)
            c.metric("Возраст", player_data_2["age"], border=False)
            d.metric("Рост", player_data_2["height"].split()[0], border=False)
            e.metric("Вес", player_data_2["weight"].split()[0], border=False)

            col_player2.dataframe(
                selected_player_2,
                column_config=config_season,
                hide_index=True,
            )


if isinstance(cached_team_stats, list) and len(cached_team_stats) >= 34:
    cached_team_stats_new = [
        cached_team_stats[0],
        *cached_team_stats[25:29],
        cached_team_stats[7],
        cached_team_stats[33],
        *cached_team_stats[9:11],
        *cached_team_stats[15:17],
    ]
    tab_temp_2.table(cached_team_stats_new)

if isinstance(cached_referee, (list, pd.DataFrame)):
    tab_temp_3.dataframe(cached_referee, height=600, column_config={"flag": st.column_config.ImageColumn("flag")})


column_config_ref = {
    "flag": st.column_config.ImageColumn(
        "flag",
    ),
}

if cached_referee:
    tab_temp_3.dataframe(cached_referee, height=600, column_config=column_config_ref)


def highlight_teams(s):
    try:
        if s.iloc[0] in (
            cached_game_online["result"]["team1"]["teamId"],
            cached_game_online["result"]["team2"]["teamId"],
        ):
            return ["background-color: #FF4B4B"] * len(s)
        else:
            return [""] * len(s)
    except NameError:
        return [""] * len(s)


if cached_standings:
    df_st = pd.json_normalize(cached_standings)
    def highlight_teams(s):
        try:
            t1 = ((cached_game_online or {}).get("result") or {}).get("team1", {}).get("teamId")
            t2 = ((cached_game_online or {}).get("result") or {}).get("team2", {}).get("teamId")
            if s.iloc[0] in (t1, t2):
                return ["background-color: #FF4B4B"] * len(s)
        except Exception:
            pass
        return [""] * len(s)
    styled = df_st.style.apply(highlight_teams, axis=1)
    tab_temp_4.dataframe(
        styled,
        column_config={"logo": st.column_config.ImageColumn("logo")},
        hide_index=True,
        height=610,
    )


if isinstance(cached_scores_quarter, list) and len(cached_scores_quarter) >= 2:
    column_config = {}
    for quarter in ["Q1", "Q2", "Q3", "Q4", "OT1", "OT2", "OT3", "OT4"]:
        column_name = f"score_avg{quarter}"
        column_config[column_name] = st.column_config.NumberColumn(column_name, format="%.1f")

    columns_quarters_name = ["Q1", "Q2", "Q3", "Q4"]
    columns_quarters_name_ot = ["OT1", "OT2", "OT3", "OT4"]
    columns_quarters = tab_temp_5.columns((1, 1, 1, 1))

    # Основные четверти
    for index, col in enumerate(columns_quarters):
        q = columns_quarters_name[index]
        df_col = [
            {
                "team": cached_scores_quarter[0].get("team"),
                "W":   cached_scores_quarter[0].get(f"win{q}"),
                "L":   cached_scores_quarter[0].get(f"lose{q}"),
                "D":   cached_scores_quarter[0].get(f"draw{q}"),
                "PTS": cached_scores_quarter[0].get(f"score{q}"),
                "AVG": cached_scores_quarter[0].get(f"score_avg{q}"),
            },
            {
                "team": cached_scores_quarter[1].get("team"),
                "W":   cached_scores_quarter[1].get(f"win{q}"),
                "L":   cached_scores_quarter[1].get(f"lose{q}"),
                "D":   cached_scores_quarter[1].get(f"draw{q}"),
                "PTS": cached_scores_quarter[1].get(f"score{q}"),
                "AVG": cached_scores_quarter[1].get(f"score_avg{q}"),
            },
        ]
        col.write(q)
        col.dataframe(df_col)

    # Овертаймы
    for index, col in enumerate(columns_quarters):
        q = columns_quarters_name_ot[index]
        df_col = [
            {
                "team": cached_scores_quarter[0].get("team"),
                "W":   cached_scores_quarter[0].get(f"win{q}"),
                "L":   cached_scores_quarter[0].get(f"lose{q}"),
                "D":   cached_scores_quarter[0].get(f"draw{q}"),
                "PTS": cached_scores_quarter[0].get(f"score{q}"),
                "AVG": cached_scores_quarter[0].get(f"score_avg{q}"),
            },
            {
                "team": cached_scores_quarter[1].get("team"),
                "W":   cached_scores_quarter[1].get(f"win{q}"),
                "L":   cached_scores_quarter[1].get(f"lose{q}"),
                "D":   cached_scores_quarter[1].get(f"draw{q}"),
                "PTS": cached_scores_quarter[1].get(f"score{q}"),
                "AVG": cached_scores_quarter[1].get(f"score_avg{q}"),
            },
        ]
        col.write(q)
        col.dataframe(df_col)


if isinstance(cached_play_by_play, list) and isinstance(cached_game_online, dict):
    plays = (cached_game_online.get("result") or {}).get("plays") or []
    if plays:
        tab_temp_6.table(cached_play_by_play)


def schedule_selected_team(team_id, data, game_id, selected, away_team_id):
    columns = [
        "game.localDate",
        "team1.name",
        "team1.logo",
        "game.score",
        "team2.logo",
        "team2.name",
        "game.fullScore",
        "win",
    ]
    df_schedule_new = data.loc[
        # (data["game.id"] < game_id)
        # &
        (
            (data["team1.teamId"].isin([team_id]))
            | (data["team2.teamId"].isin([team_id]))
        )
    ]
    df_schedule_new.loc[:, "game.fullScore"] = df_schedule_new[
        "game.fullScore"
    ].str.split(",")
    conditions = [
        (df_schedule_new["team1.teamId"] == team_id)
        & (df_schedule_new["game.score1"] > df_schedule_new["game.score2"]),
        (df_schedule_new["team1.teamId"] == team_id)
        & (df_schedule_new["game.score1"] < df_schedule_new["game.score2"]),
        (df_schedule_new["team2.teamId"] == team_id)
        & (df_schedule_new["game.score2"] > df_schedule_new["game.score1"]),
        (df_schedule_new["team2.teamId"] == team_id)
        & (df_schedule_new["game.score2"] < df_schedule_new["game.score1"]),
    ]
    values = [True, False, True, False]

    df_schedule_new = df_schedule_new.copy()
    df_schedule_new.loc[:, "win"] = np.select(conditions, values, default=None)
    mask = pd.Series(True, index=df_schedule_new.index)

    # Проверяем каждое выбранное условие и объединяем с маской
    if selected:
        if "Дома" in selected:
            mask &= df_schedule_new["team1.teamId"] == team_id
        if "В гостях" in selected:
            mask &= df_schedule_new["team2.teamId"] == team_id
        if "Выигрыши" in selected:
            mask &= df_schedule_new["win"] == True
        if "Поражения" in selected:
            mask &= df_schedule_new["win"] == False
        if "Друг с другом" in selected:
            mask &= df_schedule_new["team1.teamId"].isin(
                [away_team_id, team_id]
            ) & df_schedule_new["team2.teamId"].isin([away_team_id, team_id])
    return df_schedule_new[columns].loc[mask]


def get_in(d, path, default=None):
    cur = d
    for key in path:
        if not isinstance(cur, dict):
            return default
        cur = cur.get(key, default)
        if cur is default:
            return default
    return cur

if tab_schedule:
    if cached_schedule and "items" in cached_schedule:
        cached_schedule = cached_schedule["items"]
        pd_schedule = pd.json_normalize(cached_schedule)

        game_online = st.session_state.get("game_online")
        team1_id   = get_in(game_online, ["result", "team1", "teamId"])
        team1_name = get_in(game_online, ["result", "team1", "name"])
        team2_id   = get_in(game_online, ["result", "team2", "teamId"])
        team2_name = get_in(game_online, ["result", "team2", "name"])
        game_id    = get_in(game_online, ["result", "game", "id"])


        col1_schedule, col2_schedule = tab_schedule.columns((5, 5))
        options = ["Дома", "В гостях", "Выигрыши", "Поражения", "Друг с другом"]
        selection1 = col1_schedule.segmented_control(
            "Фильтр", options, selection_mode="multi", key="1"
        )
        selection2 = col2_schedule.segmented_control(
            "Фильтр", options, selection_mode="multi", key="2"
        )

        team1_data = schedule_selected_team(
            team1_id, pd_schedule, game_id, selection1, team2_id
        )
        team2_data = schedule_selected_team(
            team2_id, pd_schedule, game_id, selection2, team1_id
        )

        def highlight_two_teams(s):
            try:
                if str(s.loc["team1.name"]) in (
                    team1_name,
                    team2_name,
                ) and str(s.loc["team2.name"]) in (
                    team1_name,
                    team2_name,
                ):
                    return ["background-color: #FF4B4B"] * len(s)
                else:
                    return [""] * len(s)
            except NameError:
                return [""] * len(s)

        column_config = {
            "team1.name": st.column_config.TextColumn("Команда1", width=150),
            "team2.name": st.column_config.TextColumn("Команда2", width=150),
            "game.score": st.column_config.TextColumn(
                "Счёт",
            ),
            "game.localDate": st.column_config.TextColumn(
                "Дата",
            ),
            "game.fullScore": st.column_config.Column(
                "Счёт по четвертям",
            ),
            "team1.logo": st.column_config.ImageColumn("Лого1", width=50),
            "team2.logo": st.column_config.ImageColumn("Лого2", width=50),
        }
        count_game_1 = len(team1_data)
        count_game_2 = len(team2_data)
        team1_data = team1_data.style.apply(highlight_two_teams, axis=1).apply(
            color_win, subset="win"
        )
        team2_data = team2_data.style.apply(highlight_two_teams, axis=1).apply(
            color_win, subset="win"
        )
        height1 = 38 * max(count_game_1, 10)
        height2 = 38 * max(count_game_2, 10)
        col1_schedule.dataframe(
            team1_data,
            hide_index=True,
            height=int(min(height1, 1200)),
            column_config=column_config,
        )
        col2_schedule.dataframe(
            team2_data,
            hide_index=True,
            height=int(min(height2, 1200)),
            column_config=column_config,
        )


def get_play_info(play):
    # Ищем в списке play_type_id элемент, у которого PlayTypeID совпадает с play
    for item in play_type_id:
        if item["PlayTypeID"] == play:
            return item["PlayInfoSite"]
    return None  # Если совпадение не найдено


def get_player_name(start_num):
    # Ищем в списке teams_temp элемент, у которого startNum совпадает с temp_data_pbp["startNum"]
    for player in teams_temp:
        if player["startNum"] == start_num:
            return f"{player['firstName']} {player['lastName']}"
    return None  # Если совпадение не найдено


def get_event_time(row):
    if row != 0:
        time_str = 6000 - row
        if time_str == 0:
            time_str = "0:00"
        else:
            time_str = time_str // 10
            time_str = f"{time_str // 60}:{str(time_str % 60).zfill(2)}"
        return time_str


# Безопасная загрузка PlayTypeID
try:
    with open("PlayTypeID.json", "r", encoding="utf-8") as f:
        play_type_id = json.load(f)
except (FileNotFoundError, json.JSONDecodeError):
    play_type_id = []

teams_section = ((cached_game_online or {}).get("result") or {}).get("teams") or {}

# Если teams_section — список (например, [{"starts": [...]}, {...}])
if isinstance(teams_section, list):
    if len(teams_section) >= 2:
        starts1 = (teams_section[0] or {}).get("starts") or []
        starts2 = (teams_section[1] or {}).get("starts") or []
    elif len(teams_section) == 1:
        starts1 = (teams_section[0] or {}).get("starts") or []
        starts2 = []
    else:
        starts1 = []
        starts2 = []
# Если teams_section — словарь (обычно {"1": {...}, "2": {...}})
elif isinstance(teams_section, dict):
    starts1 = (teams_section.get(1) or teams_section.get("1") or {}).get("starts") or []
    starts2 = (teams_section.get(2) or teams_section.get("2") or {}).get("starts") or []
else:
    starts1 = []
    starts2 = []

teams_temp = sorted([x for x in starts1 if isinstance(x, dict)], key=lambda x: x.get("playerNumber", 0)) \
           + sorted([x for x in starts2 if isinstance(x, dict)], key=lambda x: x.get("playerNumber", 0))

list_fullname = [None] + [
    f"({x.get('displayNumber')}) {x.get('firstName','')} {x.get('lastName','')}".strip()
    for x in teams_temp
    if x.get("startRole") == "Player"
]

def get_play_info(play):
    for item in play_type_id:
        if isinstance(item, dict) and item.get("PlayTypeID") == play:
            return item.get("PlayInfoSite")
    return None

def get_player_name(start_num):
    for player in teams_temp:
        if player.get("startNum") == start_num:
            return f"{player.get('firstName','')} {player.get('lastName','')}".strip()
    return None

def get_event_time(row):
    if isinstance(row, (int, float)) and row != 0:
        time_val = 6000 - int(row)
        if time_val <= 0:
            return "0:00"
        time_val //= 10
        return f"{time_val // 60}:{str(time_val % 60).zfill(2)}"
    return None

with tab_pbp:
    plays = ((cached_game_online or {}).get("result") or {}).get("plays") or []
    if plays:
        temp_data_pbp = pd.DataFrame(plays)
        col1_pbp, col2_pbp = tab_pbp.columns((3, 4))
        option_player = col1_pbp.selectbox("Выбрать игрока", list_fullname)

        options_pbp = ["1 очко", "2 очка", "3 очка"]
        selection_pbp = col1_pbp.segmented_control("Фильтр", options_pbp, selection_mode="multi", key=3)

        if not temp_data_pbp.empty and "period" in temp_data_pbp.columns:
            options_quarter = [
                (f"{i+1} четверть" if i + 1 < 5 else f"{i-3} овертайм")
                for i in range(int(temp_data_pbp["period"].max()))
            ]
            selection_quarter = col1_pbp.segmented_control("Выбор четверти", options_quarter, selection_mode="multi", key=4)

            temp_data_pbp["info"] = temp_data_pbp["play"].map(get_play_info)
            temp_data_pbp["who"]  = temp_data_pbp["startNum"].map(get_player_name)
            temp_data_pbp["time"] = temp_data_pbp["sec"].map(get_event_time)

            mask1 = pd.Series(True, index=temp_data_pbp.index)

            if option_player:
                # безопасный поиск startNum
                for x in teams_temp:
                    display = f"({x.get('displayNumber')}) {x.get('firstName','')} {x.get('lastName','')}".strip()
                    if display == option_player:
                        mask1 &= temp_data_pbp["startNum"] == x.get("startNum")
                        break

            if selection_pbp:
                plays_mapping = {"1 очко": 1, "2 очка": 2, "3 очка": 3}
                selected_plays = [plays_mapping[p] for p in selection_pbp if p in plays_mapping]
                mask1 &= temp_data_pbp["play"].isin(selected_plays)

            if selection_quarter:
                select_quart = [i+1 for i, q in enumerate(options_quarter) if q in selection_quarter]
                mask1 &= temp_data_pbp["period"].isin(select_quart)

            filtered_data_pbp = temp_data_pbp[mask1]
            count_pbp = len(filtered_data_pbp)

            column_pbp = ["num", "info", "who", "period", "time"]
            column_config_pbp = {
                "info": st.column_config.TextColumn(width="medium"),
                "who": st.column_config.TextColumn(width="large"),
            }
            col2_pbp.dataframe(
                filtered_data_pbp[column_pbp],
                column_config=column_config_pbp,
                hide_index=True,
                height=(38 * count_pbp if count_pbp > 10 else None),
            )
    else:
        st.info("Данных play-by-play нет.")
