#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
metrics_alerts.py - Alertes Telegram + Email pour les métriques de performance

Usage:
    python3 metrics_alerts.py --daily          # Alerte quotidienne (si notable)
    python3 metrics_alerts.py --weekly         # Rapport hebdomadaire
    python3 metrics_alerts.py --test           # Test formatage
    python3 metrics_alerts.py --daily --email  # Alerte + email si ROI > 1.0€
    python3 metrics_alerts.py --weekly --email # Rapport hebdo par email
"""

import sqlite3
import argparse
import requests
from datetime import datetime, timedelta
from pathlib import Path

DB_PATH = "/home/h3r7/turf_scraper/turf.db"
TELEGRAM_DIR = "/home/h3r7/turf_scraper"

# Email alert configuration (via combined_api Resend endpoint on port 8765)
COMBINED_API_URL = "http://localhost:8765"
ALERT_EMAIL_TO = "ronanyves26@gmail.com"   # destinataire des alertes email

# Seuil ROI pour déclencher une alerte email automatique (euros par mise)
ROI_ALERT_THRESHOLD = 1.0

# =============================================================================
# FONCTIONS UTILITAIRES
# =============================================================================

def get_db():
    """Connexion a la base de donnees"""
    conn = sqlite3.connect(DB_PATH)
    conn.row_factory = sqlite3.Row
    return conn

def save_telegram_message(message, filename):
    """Sauvegarde le message Telegram dans un fichier"""
    filepath = Path(TELEGRAM_DIR) / filename
    with open(filepath, 'w', encoding='utf-8') as f:
        f.write(message)
    print("Message Telegram sauvegarde: {}".format(filepath))
    return filepath


def send_email_alert(subject, message_text):
    """
    Envoie une alerte email via le endpoint /api/send-email de combined_api (port 8765).
    Convertit le message texte en HTML style.
    Retourne True si envoi reussi, False sinon.
    """
    # Convertir le texte brut en HTML lisible
    html_lines = []
    for line in message_text.splitlines():
        stripped = line.strip()
        if not stripped:
            html_lines.append("<br>")
        else:
            # Echapper les caracteres HTML basiques
            escaped = stripped.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
            html_lines.append(
                "<p style='margin:3px 0;font-family:monospace;font-size:14px;'>{}</p>".format(escaped)
            )

    html_body = """
    <div style="background:#0f0f23;color:#eee;padding:24px;border-radius:8px;
                font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
                max-width:620px;margin:0 auto;">
        <h2 style="color:#00d9ff;border-bottom:1px solid #30363d;
                   padding-bottom:12px;margin-bottom:16px;font-size:20px;">
            H3R7Tech — Alerte Performance Turf
        </h2>
        <div style="margin-top:12px;background:#161b22;padding:16px;border-radius:6px;
                    border:1px solid #30363d;">
            {}
        </div>
        <hr style="border:none;border-top:1px solid #30363d;margin:20px 0;">
        <p style="color:#555;font-size:12px;margin:0;">
            Alerte automatique generee par metrics_alerts.py — H3R7Tech<br>
            Dashboard: <a href="http://localhost:8765/turf/" style="color:#00d9ff;">Turf Dashboard</a>
        </p>
    </div>
    """.format("".join(html_lines))

    try:
        resp = requests.post(
            "{}/api/send-email".format(COMBINED_API_URL),
            json={
                "to": ALERT_EMAIL_TO,
                "subject": subject,
                "html": html_body,
            },
            timeout=15,
        )
        if resp.status_code in (200, 201):
            result = resp.json()
            print("Email envoye a {} — id: {}".format(ALERT_EMAIL_TO, result.get("id", "?")))
            return True
        else:
            try:
                data = resp.json()
                error_msg = data.get("error", data.get("details", resp.text[:300]))
            except Exception:
                error_msg = resp.text[:300]
            print("Erreur Resend ({}): {}".format(resp.status_code, error_msg))
            return False
    except Exception as e:
        print("Impossible d'envoyer l'email: {}".format(e))
        return False


# =============================================================================
# ALERTE QUOTIDIENNE
# =============================================================================

def check_daily_alerts(date_str):
    """Verifie les evenements notables du jour. Retourne (message, has_roi_alert) ou None."""
    conn = get_db()
    
    # Recuperer les metriques du jour
    metrics = conn.execute("""
        SELECT 
            source,
            SUM(nb_predictions) as total_pred,
            SUM(nb_gagnants) as total_gagn,
            SUM(nb_places) as total_place,
            SUM(nb_top5) as total_top5,
            AVG(taux_gagnant) as taux_g,
            AVG(taux_place) as taux_p,
            AVG(roi_sg_net) as roi_sg,
            SUM(quinte_5sur5) as q5
        FROM prediction_metrics
        WHERE date = ?
        GROUP BY source
    """, (date_str,)).fetchall()
    
    if not metrics:
        print("Aucune metrique pour {}".format(date_str))
        return None
    
    # Verifier les criteres d'alerte
    alerts = []
    has_roi_alert = False
    
    for m in metrics:
        # Quinte 5/5
        if m['q5'] and m['q5'] > 0:
            alerts.append("QUINTE 5/5 {}: Quinte 5/5 trouve!".format(m['source']))
        
        # ROI exceptionnel (> seuil ROI_ALERT_THRESHOLD)
        if m['roi_sg'] and m['roi_sg'] > ROI_ALERT_THRESHOLD:
            alerts.append("ROI ELEVE {}: ROI SG +{:.2f}€/mise".format(m['source'], m['roi_sg']))
            has_roi_alert = True
        
        # Taux place excellent
        if m['taux_p'] and m['taux_p'] > 70:
            alerts.append("TAUX PLACE {}: {:.1f}% place (excellent)".format(m['source'], m['taux_p']))
    
    if not alerts:
        print("Aucun evenement notable aujourd'hui")
        return None
    
    # Formater le message
    date_fmt = datetime.strptime(date_str, '%Y-%m-%d').strftime('%d/%m/%Y')
    message = "ALERTE PERFORMANCE\nDate: {}\n{}\n\n{}\n\nDetails: Dashboard Turf".format(
        date_fmt,
        "=" * 30,
        "\n".join(alerts)
    )
    
    conn.close()
    return message, has_roi_alert


# =============================================================================
# RAPPORT HEBDOMADAIRE
# =============================================================================

def generate_weekly_report():
    """Genere le rapport hebdomadaire de performance. Retourne (message, total_roi_sg)."""
    conn = get_db()
    
    # Dates de la semaine
    today = datetime.now()
    start_date = (today - timedelta(days=7)).strftime('%Y-%m-%d')
    end_date = today.strftime('%Y-%m-%d')
    
    # Periode precedente pour comparaison
    prev_start = (today - timedelta(days=14)).strftime('%Y-%m-%d')
    prev_end = start_date
    
    # Metriques de la semaine
    current_metrics = conn.execute("""
        SELECT 
            source,
            COUNT(*) as nb_courses,
            SUM(nb_predictions) as total_pred,
            SUM(nb_gagnants) as total_gagn,
            SUM(nb_places) as total_place,
            ROUND(AVG(taux_gagnant), 1) as taux_g,
            ROUND(AVG(taux_place), 1) as taux_p,
            ROUND(SUM(roi_sg_net), 3) as roi_sg_cumul,
            ROUND(SUM(roi_sp_net), 3) as roi_sp_cumul,
            SUM(quinte_5sur5) as q5,
            SUM(quinte_4sur5) as q4
        FROM prediction_metrics
        WHERE date BETWEEN ? AND ?
        GROUP BY source
        ORDER BY taux_p DESC
    """, (start_date, end_date)).fetchall()
    
    # Metriques semaine precedente
    prev_metrics = conn.execute("""
        SELECT 
            source,
            ROUND(AVG(taux_gagnant), 1) as taux_g,
            ROUND(AVG(taux_place), 1) as taux_p
        FROM prediction_metrics
        WHERE date BETWEEN ? AND ?
        GROUP BY source
    """, (prev_start, prev_end)).fetchall()
    
    prev_dict = {m['source']: m for m in prev_metrics}
    
    # Formater le message
    start_fmt = datetime.strptime(start_date, '%Y-%m-%d').strftime('%d/%m')
    end_fmt = datetime.strptime(end_date, '%Y-%m-%d').strftime('%d/%m')
    
    message = "RAPPORT PERFORMANCE\nSemaine {} - {}\n{}\n\n".format(
        start_fmt, end_fmt, "=" * 30
    )
    
    # Bilan global
    total_roi_sg = sum(m['roi_sg_cumul'] or 0 for m in current_metrics)
    total_roi_sp = sum(m['roi_sp_cumul'] or 0 for m in current_metrics)
    total_q5 = sum(m['q5'] or 0 for m in current_metrics)
    total_q4 = sum(m['q4'] or 0 for m in current_metrics)
    
    # Detail par source
    for m in current_metrics:
        source_name = m['source'].replace('canalturf_', '').replace('_', ' ').title()
        
        # Comparaison avec semaine precedente
        prev = prev_dict.get(m['source'])
        diff_g = 0
        diff_p = 0
        if prev:
            diff_g = m['taux_g'] - prev['taux_g']
            diff_p = m['taux_p'] - prev['taux_p']
        
        arrow_g = 'hausse' if diff_g > 0 else 'baisse' if diff_g < 0 else 'stable'
        arrow_p = 'hausse' if diff_p > 0 else 'baisse' if diff_p < 0 else 'stable'
        
        message += "{}\n  Courses: {}\n  Taux gagnant: {}% ({})\n  Taux place: {}% ({})\n  ROI SG: {:+.2f}€\n  ROI SP: {:+.2f}€\n\n".format(
            source_name,
            m['nb_courses'],
            m['taux_g'], arrow_g,
            m['taux_p'], arrow_p,
            m['roi_sg_cumul'],
            m['roi_sp_cumul']
        )
    
    # Bilan global
    bilan = "Semaine positive" if total_roi_sg > 0 else "Semaine negative"
    
    message += "{}\nQuinte: 5/5 = {} courses | 4/5 = {} courses\n\nBilan global:\n  ROI SG cumule: {:+.2f}€\n  ROI SP cumule: {:+.2f}€\n\n{}\n{}".format(
        "=" * 30,
        total_q5, total_q4,
        total_roi_sg, total_roi_sp,
        bilan, "=" * 30
    )
    
    conn.close()
    return message, total_roi_sg

# =============================================================================
# POINT D'ENTREE
# =============================================================================

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Alertes metriques de performance")
    parser.add_argument("--daily", "-d", action="store_true", help="Alerte quotidienne")
    parser.add_argument("--weekly", "-w", action="store_true", help="Rapport hebdomadaire")
    parser.add_argument("--test", "-t", action="store_true", help="Test formatage")
    parser.add_argument(
        "--email", "-e", action="store_true",
        help="Envoyer par email (auto si ROI > {:.1f}€)".format(ROI_ALERT_THRESHOLD)
    )
    parser.add_argument("--date", help="Date YYYY-MM-DD (defaut: hier)")
    
    args = parser.parse_args()
    
    if args.test:
        date_str = args.date or (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%d')
        result = check_daily_alerts(date_str)
        if result:
            msg, has_roi = result
            print(msg)
            if args.email:
                print("\n--- Test envoi email ---")
                send_email_alert("[TEST] Alerte Performance Turf — {}".format(date_str), msg)
        result_w = generate_weekly_report()
        if result_w:
            msg_w, roi_w = result_w
            print(msg_w)

    elif args.daily:
        date_str = args.date or (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%d')
        result = check_daily_alerts(date_str)
        if result:
            msg, has_roi = result
            filename = "telegram_metrics_daily_{}.txt".format(date_str.replace('-', ''))
            save_telegram_message(msg, filename)

            # Envoi email si ROI > seuil (automatique) OU si flag --email passe
            if args.email or has_roi:
                date_fmt = datetime.strptime(date_str, '%Y-%m-%d').strftime('%d/%m/%Y')
                subject = "Alerte Turf — ROI exceptionnel {}".format(date_fmt)
                sent = send_email_alert(subject, msg)
                if not sent:
                    print("Email non envoye (voir logs ci-dessus)")

    elif args.weekly:
        result = generate_weekly_report()
        if result:
            msg, total_roi = result
            filename = "telegram_metrics_weekly_{}.txt".format(datetime.now().strftime('%Y%m%d'))
            save_telegram_message(msg, filename)

            # Envoi email du rapport hebdo si --email active
            if args.email:
                start_fmt = (datetime.now() - timedelta(days=7)).strftime('%d/%m')
                end_fmt = datetime.now().strftime('%d/%m')
                roi_status = "positif" if total_roi > 0 else "negatif"
                subject = "Rapport Hebdo Turf {}-{} — ROI {} ({:+.2f}€)".format(
                    start_fmt, end_fmt, roi_status, total_roi
                )
                sent = send_email_alert(subject, msg)
                if not sent:
                    print("Email non envoye (voir logs ci-dessus)")
    else:
        parser.print_help()
