#!/usr/bin/env python3
"""
Agent Turf Autonome - Prédictions quotidiennes
Usage: python3 agent_turf.py [--dry-run]
"""

import sqlite3
import subprocess
import sys
import json
import os
from datetime import datetime, timedelta
from pathlib import Path

DB_PATH = "/home/h3r7/turf_scraper/turf.db"
LOG_FILE = "/home/h3r7/turf_scraper/logs/agent_turf.log"
VPS_HOST = "10.0.1.1"


def log(msg: str):
    """Log avec timestamp"""
    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    line = f"[{timestamp}] {msg}"
    print(line)

    os.makedirs(os.path.dirname(LOG_FILE), exist_ok=True)
    with open(LOG_FILE, "a") as f:
        f.write(line + "\n")


def sync_database():
    """Sync base de données depuis VPS"""
    log("=== SYNC DATABASE ===")

    # Check remote size
    cmd = f"sshpass -p 'Cronstadt35*' ssh -o StrictHostKeyChecking=no h3r7@{VPS_HOST} stat -c %s {DB_PATH}"
    result = subprocess.run(cmd, shell=True, capture_output=True, text=True)

    if result.returncode != 0:
        log(f"ERROR: Cannot connect to VPS")
        return False

    remote_size = int(result.stdout.strip())
    local_size = os.path.getsize(DB_PATH) if os.path.exists(DB_PATH) else 0

    if remote_size == local_size:
        log(f"Database up to date ({remote_size} bytes)")
        return True

    log(f"Syncing database (remote: {remote_size}, local: {local_size})...")

    cmd = f"sshpass -p 'Cronstadt35*' scp -o StrictHostKeyChecking=no h3r7@{VPS_HOST}:{DB_PATH} {DB_PATH}.tmp"
    result = subprocess.run(cmd, shell=True, capture_output=True)

    if result.returncode == 0:
        os.rename(DB_PATH + ".tmp", DB_PATH)
        log(f"Database synced successfully")
        return True
    else:
        log(f"ERROR: Sync failed")
        return False


def generate_predictions():
    """Génère les prédictions du jour"""
    log("=== GENERATE PREDICTIONS ===")

    conn = sqlite3.connect(DB_PATH)
    conn.row_factory = sqlite3.Row
    cursor = conn.cursor()

    today = datetime.now().strftime("%Y-%m-%d")

    # Get today's races
    cursor.execute(
        """
        SELECT DISTINCT c.date_programme, c.num_reunion, c.num_course, 
               c.libelle, c.heure_depart_str, r.hippodrome_court
        FROM pmu_courses c
        JOIN pmu_reunions r ON r.date_programme = c.date_programme AND r.num_reunion = c.num_reunion
        WHERE c.date_programme = ? AND r.pays_code = 'FRA'
        ORDER BY c.heure_depart_str
    """,
        (today,),
    )

    races = cursor.fetchall()
    log(f"Found {len(races)} races today")

    predictions = []

    for race in races:
        date, num_reunion, num_course, libelle, heure, hippodrome = race

        # Get scoring
        cursor.execute(
            """
            SELECT horse_name, horse_number, score, cote, rang_scoring
            FROM scoring
            WHERE date = ? AND race_name LIKE ?
            ORDER BY rang_scoring
            LIMIT 4
        """,
            (date, f"%{libelle}%"),
        )

        scores = cursor.fetchall()

        if scores:
            pred = {
                "race": f"{heure} - {hippodrome} - {libelle}",
                "top4": [dict(s) for s in scores],
            }
            predictions.append(pred)
            log(
                f"  {pred['race'][:50]} -> {', '.join([s['horse_name'] for s in scores[:3]])}"
            )

    conn.close()
    return predictions


def save_recommendations(predictions):
    """Sauvegarde les recommandations en base"""
    log("=== SAVE RECOMMENDATIONS ===")

    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()

    today = datetime.now().strftime("%Y-%m-%d")

    # Clear today's recommendations
    cursor.execute("DELETE FROM recommendations WHERE date = ?", (today,))

    for pred in predictions:
        race_name = pred["race"]

        # Add top 4
        for i, horse in enumerate(pred["top4"]):
            if i < 4:  # TOP 4
                cursor.execute(
                    """
                    INSERT INTO recommendations 
                    (date, race_name, type_pari, cheval1, numero1, cote, mise, confiance, justification)
                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
                """,
                    (
                        today,
                        race_name,
                        f"top{i + 1}",
                        horse["horse_name"],
                        horse["horse_number"],
                        horse["cote"],
                        2.0,
                        f"TOP {i + 1}",
                        f"Score: {horse['score']}, Rang scoring: {horse['rang_scoring']}",
                    ),
                )

        # Add simple winner (top 1)
        top1 = pred["top4"][0]
        cursor.execute(
            """
            INSERT INTO recommendations 
            (date, race_name, type_pari, cheval1, numero1, cote, mise, confiance, justification)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
        """,
            (
                today,
                race_name,
                "simple_gagnant",
                top1["horse_name"],
                top1["horse_number"],
                top1["cote"],
                2.0,
                "🔥 FORTE" if top1["score"] > 60 else "✅ BONNE",
                f"Score: {top1['score']}, Favorite prediction",
            ),
        )

    conn.commit()
    conn.close()
    log(f"Saved {len(predictions)} race recommendations")


def notify_telegram(predictions):
    """Envoie les prédictions du jour via Telegram"""
    import urllib.request

    config_path = "/home/h3r7/turf_scraper/config_telegram.json"
    if not os.path.exists(config_path):
        log("No Telegram config found, skipping notification")
        return

    try:
        with open(config_path, "r") as f:
            cfg = json.load(f)
        token = cfg.get("token", "")
        chat_id = cfg.get("chat_id", "")
        if not token or not chat_id:
            log("Telegram config missing token or chat_id")
            return
    except Exception as e:
        log(f"Error reading Telegram config: {e}")
        return

    today = datetime.now().strftime("%d/%m/%Y")
    lines = [f"🏇 *Prédictions Turf — {today}*", ""]

    if not predictions:
        lines.append("Aucune prédiction disponible aujourd'hui.")
    else:
        for pred in predictions:
            race_label = pred.get("race", "Course inconnue")
            top4 = pred.get("top4", [])
            lines.append(f"📍 *{race_label}*")
            for i, horse in enumerate(top4, 1):
                name = horse.get("horse_name", "?")
                score = horse.get("score", 0)
                cote = horse.get("cote", "?")
                icon = "🥇" if i == 1 else ("🥈" if i == 2 else ("🥉" if i == 3 else "4️⃣"))
                lines.append(f"  {icon} {name} — score: {score} — cote: {cote}")
            lines.append("")

    text = "\n".join(lines)

    url = f"https://api.telegram.org/bot{token}/sendMessage"
    payload = json.dumps({
        "chat_id": chat_id,
        "text": text,
        "parse_mode": "Markdown"
    }).encode("utf-8")

    try:
        req = urllib.request.Request(
            url,
            data=payload,
            headers={"Content-Type": "application/json"},
            method="POST"
        )
        with urllib.request.urlopen(req, timeout=10) as resp:
            result = json.loads(resp.read().decode("utf-8"))
            if result.get("ok"):
                log(f"Telegram notification sent ({len(predictions)} races)")
            else:
                log(f"Telegram API error: {result}")
    except Exception as e:
        log(f"Error sending Telegram notification: {e}")


def run_backtest_yesterday():
    """Lance le backtest sur les résultats d'hier"""
    log("=== RUN BACKTEST ===")

    yesterday = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d")

    # Check if we have results for yesterday
    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()

    cursor.execute(
        """
        SELECT COUNT(*) FROM pmu_partants
        WHERE date_programme = ? AND ordre_arrivee > 0
        """,
        (yesterday,),
    )

    count = cursor.fetchone()[0]
    conn.close()

    if count > 0:
        log(f"Running backtest for {yesterday}...")
        # Run backtest script
        cmd = f"cd /home/h3r7/turf_scraper && python3 backtest_analyzer.py --date {yesterday}"
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
        if result.returncode == 0:
            log("Backtest completed")
        else:
            log(f"Backtest failed: {result.stderr}")
    else:
        log(f"No results for {yesterday}, skipping backtest")


def update_paris_results():
    """Met à jour les paris avec les résultats PMU"""
    log("=== UPDATE PARIS RESULTS ===")

    today = datetime.now().strftime("%Y-%m-%d")

    cmd = (
        f"cd /home/h3r7/turf_scraper && python3 update_paris_results.py --date {today}"
    )
    result = subprocess.run(cmd, shell=True, capture_output=True, text=True)

    if result.returncode == 0:
        log(f"Paris updated: {result.stdout.strip()}")
    else:
        log(f"Paris update failed: {result.stderr}")


def main():
    """Point d'entrée principal"""
    dry_run = "--dry-run" in sys.argv

    log("=" * 50)
    log("🤖 AGENT TURF AUTONOME - DEMARRAGE")
    log("=" * 50)

    try:
        # 1. Sync database
        if not dry_run:
            sync_database()

        # 2. Generate predictions
        predictions = generate_predictions()

        # 3. Save recommendations
        if not dry_run and predictions:
            save_recommendations(predictions)

        # 3b. Send Telegram notification
        if not dry_run:
            notify_telegram(predictions)

        # 4. Create paris from recommendations
        if not dry_run and predictions:
            update_paris_results()

        # 5. Run backtest on yesterday
        if not dry_run:
            run_backtest_yesterday()

        log("=" * 50)
        log("✅ AGENT TURF - TERMINÉ")
        log("=" * 50)

    except Exception as e:
        log(f"❌ ERREUR: {e}")
        import traceback

        traceback.print_exc()
        sys.exit(1)


if __name__ == "__main__":
    main()
