from __future__ import annotations
"""LLM analysis agent (OpenAI).

Generates a human-readable pre-match analysis for upcoming matches
based on DB data (teams, recent form, odds, model probabilities).
Stores the analysis into football.predictions.analysis_text.
"""


import logging
from datetime import datetime, timedelta
from sqlalchemy.orm import Session

from app.agents.base import BaseAgent
from app.core.config import settings
from app.core.db.repositories.match_repository import MatchRepository
from app.core.db.repositories.prediction_repository import PredictionRepository
from app.core.db.repositories.model_repository import ModelRepository
from app.core.db.repositories.odds_repository import OddsRepository
from app.core.db.models.match import MatchStatus
from app.llm.openai_client import OpenAIClient

logger = logging.getLogger(__name__)


class LLMAnalysisAgent(BaseAgent):
        """Generate LLM analysis for upcoming matches."""

        def __init__(self, db: Session):
            super().__init__(db, agent_name="llm_analysis")
            self.match_repo = MatchRepository(db)
            self.pred_repo = PredictionRepository(db)
            self.model_repo = ModelRepository(db)
            self.odds_repo = OddsRepository(db)

        def _build_prompt(self, match, pred, odds_row) -> str:
            kickoff = match.match_date.isoformat() if getattr(match, "match_date", None) else str(match.kickoff_at)
            home = match.home_team.name
            away = match.away_team.name

            probs = f"P(Home)={pred.prob_home_win:.2f}, P(Draw)={pred.prob_draw:.2f}, P(Away)={pred.prob_away_win:.2f}"
            odds_txt = ""
            if odds_row is not None:
                odds_txt = f"Bookmaker={odds_row.bookmaker}, 1={odds_row.odd_home}, X={odds_row.odd_draw}, 2={odds_row.odd_away}"

            return f"""Ты футбольный аналитик. Составь короткий, конкретный pre-match разбор (8-12 пунктов).
Формат:
- 1 строка: матч и дата
- 3-5 пунктов про контекст/форму/мотивацию (без выдумок, только осторожные формулировки)
- 2-3 пункта про вероятности модели и что они означают
- 2-3 пункта про риски (травмы неизвестны, ротация, мотивация, погода и т.д.)
- 1 строка: аккуратный вывод (не гарантировать исход).

ДАННЫЕ:
Матч: {home} vs {away}
Дата: {kickoff}
Вероятности модели: {probs}
Коэффициенты 1X2 (если есть): {odds_txt}

Пиши по-русски, без токсичности и без призывов к ставкам."""  # noqa: E501

        def run(self) -> bool:
            if not settings.openai_api_key:
                logger.warning("OPENAI_API_KEY is not set; skipping LLMAnalysisAgent.")
                return True

            try:
                run_id = self.start_run()
                client = OpenAIClient(
                    api_key=settings.openai_api_key,
                    model=settings.openai_model,
                )

                # Upcoming matches window
                now = datetime.utcnow()
                horizon = now + timedelta(hours=settings.llm_horizon_hours)
                matches = self.match_repo.get_upcoming(from_date=now, to_date=horizon, limit=settings.llm_max_matches)

                if not matches:
                    self.finish_run(success=True, logs="No upcoming matches found")
                    return True

                # Use latest active model (or latest by date)
                model = self.model_repo.get_latest()
                if not model:
                    self.finish_run(success=False, error="No active model found for LLM analysis")
                    return False

                generated = 0
                for m in matches:
                    # Fetch prediction for this match+model
                    pred = self.pred_repo.get_latest_for_match(match_id=m.id, model_id=model.id)
                    if not pred:
                        continue
                    if getattr(pred, "analysis_text", None):
                        continue

                    odds_row = self.odds_repo.get_latest_1x2_for_match(m.id)

                    prompt = self._build_prompt(m, pred, odds_row)
                    messages = [
                        {"role": "system", "content": "Ты аккуратный спортивный аналитик."},
                        {"role": "user", "content": prompt},
                    ]

                    text = client.chat(
                        messages,
                        temperature=settings.openai_temperature,
                        max_tokens=settings.openai_max_tokens,
                    ).strip()

                    self.pred_repo.update_or_create(
                        match_id=m.id,
                        model_id=model.id,
                        analysis_text=text,
                        analysis_generated_at=datetime.utcnow(),
                    )
                    generated += 1

                # Update run stats
                run = self.run_repo.get_by_id(run_id)
                if run:
                    run.records_created = generated
                    self.db.commit()

                self.finish_run(success=True, logs=f"Generated analyses: {generated}")
                return True
            except Exception as e:
                msg = str(e)
                logger.error("LLM analysis failed: %s", msg, exc_info=True)
                self.finish_run(success=False, error=msg)
                return False
