#!/usr/bin/env python3
"""
Telegram Alerts — Service d'alertes pré-course pour les utilisateurs Premium/Pro
HRT-79: Alertes Telegram configurables (Premium)

Fonctionnement :
  - 30 minutes avant chaque course détectée, envoie un message Telegram
    aux utilisateurs Premium/Pro ayant configuré leur chat_id.
  - Les préférences individuelles (value_bets, top1, quinte_only) sont respectées.
  - Requiert la variable d'environnement TELEGRAM_BOT_TOKEN.
"""

import os
import logging
import sqlite3
from datetime import datetime
from typing import Optional

import requests

logger = logging.getLogger(__name__)

DB_PATH = os.environ.get("TURF_SAAS_DB", "/home/h3r7/turf_saas/turf_saas.db")
BOT_TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN", "")

TELEGRAM_API_BASE = "https://api.telegram.org/bot{token}/sendMessage"


# ── Helpers ───────────────────────────────────────────────────────────────────


def _get_db():
    conn = sqlite3.connect(DB_PATH)
    conn.row_factory = sqlite3.Row
    return conn


def send_telegram_message(chat_id: str, text: str) -> bool:
    """
    Envoie un message Telegram à un chat_id donné.

    Returns True si succès, False sinon.
    Ne lève pas d'exception pour ne pas crasher le scheduler.
    """
    if not BOT_TOKEN:
        logger.warning("[TELEGRAM] TELEGRAM_BOT_TOKEN non configuré — envoi ignoré")
        return False

    url = TELEGRAM_API_BASE.format(token=BOT_TOKEN)
    payload = {
        "chat_id": chat_id,
        "text": text,
        "parse_mode": "Markdown",
        "disable_web_page_preview": True,
    }
    try:
        resp = requests.post(url, json=payload, timeout=10)
        if resp.status_code == 200:
            return True
        logger.warning(
            "[TELEGRAM] Echec envoi chat_id=%s status=%d body=%s",
            chat_id,
            resp.status_code,
            resp.text[:200],
        )
        return False
    except requests.RequestException as exc:
        logger.error("[TELEGRAM] Exception HTTP chat_id=%s: %s", chat_id, exc)
        return False


# ── Alert builder ─────────────────────────────────────────────────────────────


def build_race_alert(race_data: dict, predictions: list) -> str:
    """
    Construit le message Markdown de l'alerte pré-course.

    Args:
        race_data: dict avec les clés 'hippo', 'num_course', 'heure', 'type_course'
        predictions: liste de dicts {'num_cheval', 'nom_cheval', 'prob_top3', 'is_value_bet', 'ml_score'}

    Returns: texte Markdown formaté
    """
    hippo = race_data.get("hippo", "?")
    num_course = race_data.get("num_course", "?")
    heure = race_data.get("heure", "?")
    type_course = race_data.get("type_course", "")

    lines = [
        f"🏇 *Alerte course — {hippo} R{num_course}*",
        f"⏰ Départ prévu : *{heure}*",
    ]
    if type_course:
        lines.append(f"📋 Type : {type_course}")
    lines.append("")

    top3 = [p for p in predictions if p.get("prob_top3", 0) > 0][:3]
    value_bets = [p for p in predictions if p.get("is_value_bet")]

    if top3:
        lines.append("📊 *Top-3 ML :*")
        for i, p in enumerate(top3, 1):
            nom = p.get("nom_cheval", f"#{p.get('num_cheval', '?')}")
            prob = p.get("prob_top3", 0)
            lines.append(f"  {i}. {nom} — {prob:.0%} prob top-3")
        lines.append("")

    if value_bets:
        lines.append("💡 *Value bets :*")
        for p in value_bets[:3]:
            nom = p.get("nom_cheval", f"#{p.get('num_cheval', '?')}")
            score = p.get("ml_score", 0)
            lines.append(f"  ✅ {nom} (score {score:.2f})")
        lines.append("")

    lines.append("_Alerte automatique Turf SaaS — 30min avant départ_")
    return "\n".join(lines)


# ── Main send function ────────────────────────────────────────────────────────


def send_pre_race_alerts(minutes_before: int = 30) -> dict:
    """
    Interroge la DB pour récupérer les courses du jour, puis envoie
    des alertes Telegram aux utilisateurs Premium/Pro éligibles.

    Args:
        minutes_before: non utilisé directement (la planification est gérée
                        par le scheduler), présent pour documentation.

    Returns: dict {'sent': int, 'skipped': int, 'errors': int}
    """
    if not BOT_TOKEN:
        logger.warning(
            "[TELEGRAM] TELEGRAM_BOT_TOKEN absent — send_pre_race_alerts ignoré"
        )
        return {"sent": 0, "skipped": 0, "errors": 0}

    stats = {"sent": 0, "skipped": 0, "errors": 0}

    try:
        conn = _get_db()
        today = datetime.now().strftime("%Y-%m-%d")

        # Récupère les courses du jour
        try:
            courses_rows = conn.execute(
                """
                SELECT DISTINCT
                    hippo, num_course, heure_depart, type_course
                FROM pmu_courses
                WHERE date_programme = ?
                  AND heure_depart IS NOT NULL
                ORDER BY heure_depart ASC
                LIMIT 20
                """,
                (today,),
            ).fetchall()
        except sqlite3.OperationalError as exc:
            logger.warning("[TELEGRAM] Table pmu_courses introuvable: %s", exc)
            conn.close()
            return stats

        if not courses_rows:
            logger.info("[TELEGRAM] Aucune course aujourd'hui — pas d'alerte")
            conn.close()
            return stats

        # Récupère les utilisateurs Premium/Pro avec chat_id configuré
        try:
            users = conn.execute(
                """
                SELECT id, telegram_chat_id,
                       alert_value_bets, alert_top1, alert_quinte_only
                FROM users
                WHERE plan IN ('premium', 'pro')
                  AND is_active = 1
                  AND telegram_chat_id IS NOT NULL
                  AND telegram_chat_id != ''
                """,
            ).fetchall()
        except sqlite3.OperationalError as exc:
            logger.warning(
                "[TELEGRAM] Colonnes Telegram absentes (migration non appliquée?): %s",
                exc,
            )
            conn.close()
            return stats

        if not users:
            logger.info("[TELEGRAM] Aucun utilisateur avec chat_id configuré")
            conn.close()
            return stats

        for course_row in courses_rows:
            hippo = course_row["hippo"] or "?"
            num_course = course_row["num_course"] or "?"
            heure_ts = course_row["heure_depart"]
            type_course = course_row["type_course"] or ""

            try:
                dt = datetime.fromtimestamp(heure_ts / 1000)
                heure_str = dt.strftime("%H:%M")
            except Exception:
                heure_str = str(heure_ts)

            race_data = {
                "hippo": hippo,
                "num_course": num_course,
                "heure": heure_str,
                "type_course": type_course,
            }

            # Récupère les prédictions ML pour cette course
            predictions = []
            try:
                pred_rows = conn.execute(
                    """
                    SELECT num_cheval, nom_cheval, prob_top3, is_value_bet, ml_score
                    FROM ml_predictions_cache
                    WHERE date = ?
                      AND hippo = ?
                      AND num_course = ?
                    ORDER BY prob_top3 DESC
                    LIMIT 10
                    """,
                    (today, hippo, num_course),
                ).fetchall()
                predictions = [dict(r) for r in pred_rows]
            except sqlite3.OperationalError:
                pass  # table absente, on envoie quand même avec données minimales

            is_quinte = (
                "quinté" in type_course.lower() or "quinte" in type_course.lower()
            )

            for user in users:
                chat_id = user["telegram_chat_id"]
                alert_quinte_only = bool(user["alert_quinte_only"])
                alert_top1 = bool(user["alert_top1"])
                alert_value_bets = bool(user["alert_value_bets"])

                # Filtre quinte_only
                if alert_quinte_only and not is_quinte:
                    stats["skipped"] += 1
                    continue

                # Construit le message selon préférences
                filtered_preds = []
                if predictions:
                    for p in predictions:
                        include = False
                        if alert_top1 and p.get("prob_top3", 0) > 0:
                            include = True
                        if alert_value_bets and p.get("is_value_bet"):
                            include = True
                        if include:
                            filtered_preds.append(p)

                text = build_race_alert(race_data, filtered_preds)
                ok = send_telegram_message(chat_id, text)
                if ok:
                    stats["sent"] += 1
                else:
                    stats["errors"] += 1

        conn.close()

    except Exception as exc:
        logger.error("[TELEGRAM] Erreur inattendue dans send_pre_race_alerts: %s", exc)
        import traceback

        traceback.print_exc()
        stats["errors"] += 1

    logger.info(
        "[TELEGRAM] Alertes pré-course: %d envoyées, %d ignorées, %d erreurs",
        stats["sent"],
        stats["skipped"],
        stats["errors"],
    )
    return stats
