from __future__ import annotations

import logging
from typing import Optional

log = logging.getLogger("agents.analyzer")


class AnalyzerAgent:
    """
    Считает силу команд (attack/defense) по последним N завершённым матчам.
    Под твою схему matches:
      - home_team, away_team
      - home_score, away_score
      - kickoff_ts
      - status
    """

    def __init__(self, db, window: int = 20):
        self.db = db
        self.window = window

    async def recompute_team_strengths(self) -> int:
        """
        Возвращает количество команд, по которым обновили team_stats.
        """
        # Поддержим разные статусы "матч завершён"
        finished_statuses = ("finished", "FT", "AET", "FT_PEN", "ended", "Finished", "FINISHED")

        query = f"""
        WITH team_games AS (
            SELECT
                home_team AS team,
                home_score::float AS goals_for,
                away_score::float AS goals_against,
                kickoff_ts AS ts
            FROM matches
            WHERE status = ANY($1)
              AND home_score IS NOT NULL
              AND away_score IS NOT NULL
              AND kickoff_ts IS NOT NULL

            UNION ALL

            SELECT
                away_team AS team,
                away_score::float AS goals_for,
                home_score::float AS goals_against,
                kickoff_ts AS ts
            FROM matches
            WHERE status = ANY($1)
              AND home_score IS NOT NULL
              AND away_score IS NOT NULL
              AND kickoff_ts IS NOT NULL
        ),
        ranked AS (
            SELECT
                team,
                goals_for,
                goals_against,
                ts,
                ROW_NUMBER() OVER (PARTITION BY team ORDER BY ts DESC) AS rn
            FROM team_games
        ),
        weighted AS (
            SELECT
                team,
                goals_for,
                goals_against,
                CASE
                    WHEN rn <= 5  THEN 1.5
                    WHEN rn <= 15 THEN 1.0
                    WHEN rn <= {self.window} THEN 0.6
                    ELSE 0
                END AS w
            FROM ranked
            WHERE rn <= {self.window}
        )
        SELECT
            team,
            (SUM(goals_for * w) / NULLIF(SUM(w), 0))::float AS gf,
            (SUM(goals_against * w) / NULLIF(SUM(w), 0))::float AS ga,
            COUNT(*)::int AS n
        FROM weighted
        GROUP BY team
        HAVING COUNT(*) >= 2
        """

        rows = await self.db.fetch_all(query, list(finished_statuses))

        if not rows:
            log.warning("team_strengths: no rows computed (maybe no finished matches yet).")
            return 0

        updated = 0
        for r in rows:
            team = r["team"]
            gf = float(r["gf"]) if r["gf"] is not None else 0.0
            ga = float(r["ga"]) if r["ga"] is not None else 0.0

            # Нормализация — защита от мусора
            attack = max(0.7, min(gf, 3.2))
            defense = max(0.7, min(ga, 3.2))

            await self.db.execute(
                """
                INSERT INTO team_stats(team_id, team_name, attack, defense)
                VALUES ($1, $2, $3, $4)
                ON CONFLICT (team_id)
                DO UPDATE SET
                    attack = EXCLUDED.attack,
                    defense = EXCLUDED.defense,
                    updated_at = now()
                """,
                team, team, attack, defense
            )
            updated += 1

        log.info("team_strengths: updated=%d teams (window=%d)", updated, self.window)
        return updated

