File size: 4,409 Bytes
c04d3f9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
"""Data layer: in-memory match cache, Supabase loading, and table calculations."""
import re
from datetime import datetime, timezone

import pandas as pd

from config import supabase, IST, logger

# Global in-memory match cache.
# Each entry is a list: [id, home, away, home_goals, away_goals, datetime_str]
matches = []


def load_matches():
    """Load all matches from Supabase into the in-memory cache."""
    global matches

    logger.info("=" * 60)
    logger.info("LOADING MATCHES FROM SUPABASE")
    logger.info("=" * 60)

    try:
        logger.info(f"-> Connecting to Supabase: {supabase.supabase_url}")
        response = supabase.table("matches").select("*").order("datetime", desc=True).execute()

        matches = []
        if response.data:
            for record in response.data:
                matches.append([
                    str(record["id"]),
                    record["home"],
                    record["away"],
                    record["home_goals"],
                    record["away_goals"],
                    record["datetime"]
                ])
            logger.info(f"✓ Successfully loaded {len(matches)} matches from Supabase")
        else:
            logger.info("✓ No matches found in database")

        logger.info("=" * 60)

    except Exception as e:
        logger.error(f"✗ Error accessing Supabase: {e}")
        matches = []

    return matches


def get_teams_from_matches():
    """Extract sorted unique team names from the in-memory match cache."""
    teams = set()
    for match in matches:
        teams.add(match[1])
        teams.add(match[2])
    return sorted(list(teams)) if teams else []


def calculate_table(matches_list):
    """Calculate the league table DataFrame from a list of match records."""
    all_teams = set()
    for match in matches_list:
        all_teams.add(match[1])
        all_teams.add(match[2])

    table = {
        t: {"P": 0, "W": 0, "D": 0, "L": 0, "GF": 0, "GA": 0,
            "Pts": 0, "GPM": 0.0, "GAM": 0.0, "GDM": 0.0, "WP": 0.0,
            "#WW": 0, "#5GM": 0}
        for t in all_teams
    }

    for match in matches_list:
        match_id, h, a, gh, ga = match[0], match[1], match[2], match[3], match[4]

        table[h]["P"] += 1
        table[a]["P"] += 1
        table[h]["GF"] += gh
        table[h]["GA"] += ga
        table[a]["GF"] += ga
        table[a]["GA"] += gh

        if gh >= 5:
            table[h]["#5GM"] += 1
        if ga >= 5:
            table[a]["#5GM"] += 1

        if gh > ga:
            table[h]["W"] += 1
            table[a]["L"] += 1
            table[h]["Pts"] += 3
            if ga == 0:
                table[h]["#WW"] += 1
        elif gh < ga:
            table[a]["W"] += 1
            table[h]["L"] += 1
            table[a]["Pts"] += 3
            if gh == 0:
                table[a]["#WW"] += 1
        else:
            table[h]["D"] += 1
            table[a]["D"] += 1
            table[h]["Pts"] += 1
            table[a]["Pts"] += 1

    for t in all_teams:
        if table[t]["P"] > 0:
            table[t]["GPM"] = round(table[t]["GF"] / table[t]["P"], 2)
            table[t]["GAM"] = round(table[t]["GA"] / table[t]["P"], 2)
            table[t]["GDM"] = round((table[t]["GF"] - table[t]["GA"]) / table[t]["P"], 2)
            table[t]["WP"] = round((table[t]["W"] / table[t]["P"]) * 100, 2)

    df = pd.DataFrame.from_dict(table, orient="index")
    df["GD"] = df["GF"] - df["GA"]
    df.reset_index(inplace=True)
    df.rename(columns={"index": "Team"}, inplace=True)
    df = df[["Team", "WP", "GPM", "GAM", "GDM", "P", "W", "D", "L", "GF", "GA", "GD", "Pts", "#WW", "#5GM"]]
    df = df.sort_values(by=["WP"], ascending=False)
    return df


def _parse_datetime(dt):
    """Parse an ISO datetime string, handling variable microsecond precision."""
    try:
        return datetime.fromisoformat(dt)
    except ValueError:
        dt_normalized = re.sub(
            r'\.(\d+)', lambda m: '.' + m.group(1).ljust(6, '0')[:6], dt
        )
        return datetime.fromisoformat(dt_normalized)


def format_datetime(dt):
    """Convert a UTC/naive datetime string to an IST-formatted display string."""
    dt_obj = _parse_datetime(dt)
    if dt_obj.tzinfo is None:
        dt_obj = dt_obj.replace(tzinfo=timezone.utc).astimezone(IST)
    else:
        dt_obj = dt_obj.astimezone(IST)
    return dt_obj.strftime("%d-%m-%y %I:%M %p IST")