#!/usr/bin/env python3
"""
Analytics et Rapports Automatisés - Turf Scraper
Génère des rapports quotidiens, hebdomadaires et mensuels
"""
import sqlite3
import json
from datetime import datetime, timedelta
from typing import Dict, List, Optional
from pathlib import Path

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


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


def get_daily_report(date: str = None) -> dict:
    """
    Génère un rapport quotidien
    """
    if date is None:
        date = datetime.now().strftime('%Y-%m-%d')
    
    conn = get_db()
    c = conn.cursor()
    
    report = {
        'date': date,
        'generated_at': datetime.now().isoformat(),
        'races': {},
        'predictions': {},
        'results': {}
    }
    
    try:
        c.execute("""
            SELECT id, num_reunion, num_course, libelle, libelle_court, 
                   discipline, distance, heure_depart_str
            FROM pmu_courses
            WHERE date_programme = ?
            ORDER BY num_reunion, num_course
        """, (date,))
        
        races = c.fetchall()
        report['races']['count'] = len(races)
        report['races']['details'] = [dict(r) for r in races[:10]]
        
        c.execute("""
            SELECT race_name, race_hippodrome, COUNT(*) as pred_count
            FROM predictions
            WHERE date = ?
            GROUP BY race_name
        """, (date,))
        
        preds = c.fetchall()
        report['predictions']['count'] = sum(p['pred_count'] for p in preds)
        report['predictions']['by_race'] = [dict(p) for p in preds]
        
        c.execute("""
            SELECT p.nom as cheval, p.num_pmu as numero, p.ordre_arrivee as position, 
                   p.cote_direct as cote, p.driver, c.libelle as course
            FROM pmu_partants p
            JOIN pmu_courses c ON p.date_programme = c.date_programme 
                AND p.num_reunion = c.num_reunion AND p.num_course = c.num_course
            WHERE p.date_programme = ? AND p.ordre_arrivee > 0
            ORDER BY c.num_reunion, c.num_course, p.ordre_arrivee
        """, (date,))
        
        results = c.fetchall()
        report['results']['count'] = len(results)
        report['results']['details'] = [dict(r) for r in results[:20]]
        
        c.execute("""
            SELECT COUNT(*) as total, 
                   SUM(CASE WHEN ordre_arrivee = 1 THEN 1 ELSE 0 END) as wins,
                   SUM(CASE WHEN ordre_arrivee IN (1,2,3) THEN 1 ELSE 0 END) as podiums,
                   AVG(CASE WHEN ordre_arrivee > 0 THEN cote_direct ELSE NULL END) as avg_cote
            FROM pmu_partants
            WHERE date_programme = ? AND ordre_arrivee > 0
        """, (date,))
        
        stats = c.fetchone()
        total = stats['total'] or 0
        wins = stats['wins'] or 0
        podiums = stats['podiums'] or 0
        
        report['stats'] = {
            'total_partants': total,
            'wins': wins,
            'podiums': podiums,
            'win_rate': round(wins / total * 100, 1) if total > 0 else 0,
            'podium_rate': round(podiums / total * 100, 1) if total > 0 else 0,
            'avg_cote': round(stats['avg_cote'], 2) if stats['avg_cote'] else 0
        }
        
    except Exception as e:
        report['error'] = str(e)
    finally:
        conn.close()
    
    return report


def get_weekly_report(start_date: str = None, end_date: str = None) -> dict:
    """
    Génère un rapport hebdomadaire
    """
    if end_date is None:
        end_date = datetime.now()
    else:
        end_date = datetime.strptime(end_date, '%Y-%m-%d')
    
    if start_date is None:
        start_date = end_date - timedelta(days=7)
    else:
        start_date = datetime.strptime(start_date, '%Y-%m-%d')
    
    start_str = start_date.strftime('%Y-%m-%d')
    end_str = end_date.strftime('%Y-%m-%d')
    
    conn = get_db()
    c = conn.cursor()
    
    report = {
        'start_date': start_str,
        'end_date': end_str,
        'generated_at': datetime.now().isoformat()
    }
    
    try:
        c.execute("""
            SELECT COUNT(DISTINCT date_programme) as race_days,
                   COUNT(DISTINCT id) as total_races
            FROM pmu_courses
            WHERE date_programme BETWEEN ? AND ?
        """, (start_str, end_str))
        
        overview = c.fetchone()
        report['overview'] = {
            'race_days': overview['race_days'] or 0,
            'total_races': overview['total_races'] or 0
        }
        
        c.execute("""
            SELECT COUNT(*) as total,
                   SUM(CASE WHEN ordre_arrivee = 1 THEN 1 ELSE 0 END) as wins,
                   SUM(CASE WHEN ordre_arrivee IN (1,2,3) THEN 1 ELSE 0 END) as podiums,
                   AVG(CASE WHEN ordre_arrivee > 0 THEN cote_direct ELSE NULL END) as avg_cote
            FROM pmu_partants
            WHERE date_programme BETWEEN ? AND ? AND ordre_arrivee > 0
        """, (start_str, end_str))
        
        stats = c.fetchone()
        total = stats['total'] or 0
        wins = stats['wins'] or 0
        podiums = stats['podiums'] or 0
        
        report['stats'] = {
            'total_partants': total,
            'wins': wins,
            'podiums': podiums,
            'win_rate': round(wins / total * 100, 1) if total > 0 else 0,
            'podium_rate': round(podiums / total * 100, 1) if total > 0 else 0,
            'avg_cote': round(stats['avg_cote'], 2) if stats['avg_cote'] else 0
        }
        
        c.execute("""
            SELECT driver, COUNT(*) as wins,
                   AVG(CASE WHEN ordre_arrivee > 0 THEN ordre_arrivee ELSE NULL END) as avg_pos
            FROM pmu_partants
            WHERE date_programme BETWEEN ? AND ? AND ordre_arrivee = 1
            GROUP BY driver
            ORDER BY wins DESC
            LIMIT 10
        """, (start_str, end_str))
        
        report['top_jockeys'] = [dict(r) for r in c.fetchall()]
        
        c.execute("""
            SELECT discipline, COUNT(DISTINCT c.id) as races,
                   COUNT(*) as partants,
                   SUM(CASE WHEN ordre_arrivee = 1 THEN 1 ELSE 0 END) as wins
            FROM pmu_courses c
            LEFT JOIN pmu_partants p ON c.date_programme = p.date_programme 
                AND c.num_reunion = p.num_reunion AND c.num_course = p.num_course
            WHERE c.date_programme BETWEEN ? AND ?
            GROUP BY discipline
            ORDER BY races DESC
        """, (start_str, end_str))
        
        report['by_discipline'] = [dict(r) for r in c.fetchall()]
        
        c.execute("""
            SELECT date_programme, COUNT(*) as partants,
                   SUM(CASE WHEN ordre_arrivee = 1 THEN 1 ELSE 0 END) as wins
            FROM pmu_partants
            WHERE date_programme BETWEEN ? AND ?
            GROUP BY date_programme
            ORDER BY date_programme
        """, (start_str, end_str))
        
        report['by_day'] = [dict(r) for r in c.fetchall()]
        
    except Exception as e:
        report['error'] = str(e)
    finally:
        conn.close()
    
    return report


def get_monthly_report(year: int = None, month: int = None) -> dict:
    """
    Génère un rapport mensuel
    """
    if year is None:
        year = datetime.now().year
    if month is None:
        month = datetime.now().month
    
    start_date = datetime(year, month, 1)
    if month == 12:
        end_date = datetime(year + 1, 1, 1) - timedelta(days=1)
    else:
        end_date = datetime(year, month + 1, 1) - timedelta(days=1)
    
    start_str = start_date.strftime('%Y-%m-%d')
    end_str = end_date.strftime('%Y-%m-%d')
    
    conn = get_db()
    c = conn.cursor()
    
    report = {
        'year': year,
        'month': month,
        'start_date': start_str,
        'end_date': end_str,
        'generated_at': datetime.now().isoformat()
    }
    
    try:
        c.execute("""
            SELECT COUNT(DISTINCT date_programme) as race_days,
                   COUNT(DISTINCT id) as total_races,
                   COUNT(*) as total_partants
            FROM pmu_courses c
            LEFT JOIN pmu_partants p ON c.date_programme = p.date_programme 
                AND c.num_reunion = p.num_reunion AND c.num_course = p.num_course
            WHERE c.date_programme BETWEEN ? AND ?
        """, (start_str, end_str))
        
        overview = c.fetchone()
        report['overview'] = {
            'race_days': overview['race_days'] or 0,
            'total_races': overview['total_races'] or 0,
            'total_partants': overview['total_partants'] or 0
        }
        
        c.execute("""
            SELECT COUNT(*) as total,
                   SUM(CASE WHEN ordre_arrivee = 1 THEN 1 ELSE 0 END) as wins,
                   SUM(CASE WHEN ordre_arrivee IN (1,2,3) THEN 1 ELSE 0 END) as podiums,
                   AVG(CASE WHEN ordre_arrivee > 0 THEN cote_direct ELSE NULL END) as avg_cote
            FROM pmu_partants
            WHERE date_programme BETWEEN ? AND ? AND ordre_arrivee > 0
        """, (start_str, end_str))
        
        stats = c.fetchone()
        total = stats['total'] or 0
        wins = stats['wins'] or 0
        podiums = stats['podiums'] or 0
        
        report['stats'] = {
            'total_partants': total,
            'wins': wins,
            'podiums': podiums,
            'win_rate': round(wins / total * 100, 1) if total > 0 else 0,
            'podium_rate': round(podiums / total * 100, 1) if total > 0 else 0,
            'avg_cote': round(stats['avg_cote'], 2) if stats['avg_cote'] else 0
        }
        
        c.execute("""
            SELECT discipline, COUNT(DISTINCT c.id) as races,
                   SUM(CASE WHEN ordre_arrivee = 1 THEN 1 ELSE 0 END) as wins,
                   AVG(CASE WHEN ordre_arrivee > 0 THEN ordre_arrivee ELSE NULL END) as avg_pos
            FROM pmu_courses c
            LEFT JOIN pmu_partants p ON c.date_programme = p.date_programme 
                AND c.num_reunion = p.num_reunion AND c.num_course = p.num_course
            WHERE c.date_programme BETWEEN ? AND ?
            GROUP BY discipline
            ORDER BY races DESC
            LIMIT 20
        """, (start_str, end_str))
        
        report['by_discipline'] = [dict(r) for r in c.fetchall()]
        
        c.execute("""
            SELECT date_programme, COUNT(*) as partants,
                   SUM(CASE WHEN ordre_arrivee = 1 THEN 1 ELSE 0 END) as wins
            FROM pmu_partants
            WHERE date_programme BETWEEN ? AND ?
            GROUP BY date_programme
            ORDER BY date_programme
        """, (start_str, end_str))
        
        report['daily_breakdown'] = [dict(r) for r in c.fetchall()]
        
    except Exception as e:
        report['error'] = str(e)
    finally:
        conn.close()
    
    return report


def format_report_markdown(report: dict, report_type: str = 'daily') -> str:
    """
    Formate un rapport en Markdown
    """
    lines = []
    
    if report_type == 'daily':
        lines.append(f"# 📊 Rapport Quotidien - {report.get('date', 'N/A')}")
        lines.append("")
        lines.append(f"*Généré le {report.get('generated_at', '')}*")
        lines.append("")
        
        if 'error' in report:
            lines.append(f"❌ Erreur: {report['error']}")
            return "\n".join(lines)
        
        races = report.get('races', {})
        stats = report.get('stats', {})
        
        lines.append("## Résumé")
        lines.append(f"- 🏇 Courses: {races.get('count', 0)}")
        lines.append(f"- 🎯 Partants: {stats.get('total_partants', 0)}")
        lines.append(f"- 🏆 Victoires: {stats.get('wins', 0)} ({stats.get('win_rate', 0)}%)")
        lines.append(f"- 🥉 Podiums: {stats.get('podiums', 0)} ({stats.get('podium_rate', 0)}%)")
        lines.append("")
    
    elif report_type == 'weekly':
        lines.append(f"# 📈 Rapport Hebdomadaire")
        lines.append(f"**{report.get('start_date', '')}** au **{report.get('end_date', '')}**")
        lines.append("")
        
        if 'error' in report:
            lines.append(f"❌ Erreur: {report['error']}")
            return "\n".join(lines)
        
        overview = report.get('overview', {})
        stats = report.get('stats', {})
        
        lines.append("## Résumé")
        lines.append(f"- Jours de course: {overview.get('race_days', 0)}")
        lines.append(f"- Courses totales: {overview.get('total_races', 0)}")
        lines.append(f"- Victoires: {stats.get('wins', 0)} ({stats.get('win_rate', 0)}%)")
        lines.append(f"- Podiums: {stats.get('podiums', 0)} ({stats.get('podium_rate', 0)}%)")
        lines.append(f"- Cote moyenne: {stats.get('avg_cote', 0)}")
        lines.append("")
        
        if report.get('top_jockeys'):
            lines.append("## Top Jockeys")
            for j in report['top_jockeys'][:5]:
                lines.append(f"- {j['driver']}: {j['wins']} victoires")
            lines.append("")
    
    elif report_type == 'monthly':
        month_name = ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin',
                      'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre']
        m = report.get('month', 1)
        lines.append(f"# 📅 Rapport Mensuel - {month_name[m-1]} {report.get('year', '')}")
        lines.append("")
        
        if 'error' in report:
            lines.append(f"❌ Erreur: {report['error']}")
            return "\n".join(lines)
        
        overview = report.get('overview', {})
        stats = report.get('stats', {})
        
        lines.append("## Résumé du Mois")
        lines.append(f"- Jours de course: {overview.get('race_days', 0)}")
        lines.append(f"- Courses: {overview.get('total_races', 0)}")
        lines.append(f"- Partants: {overview.get('total_partants', 0)}")
        lines.append(f"- Victoires: {stats.get('wins', 0)} ({stats.get('win_rate', 0)}%)")
        lines.append(f"- Podiums: {stats.get('podiums', 0)} ({stats.get('podium_rate', 0)}%)")
        lines.append(f"- Cote moyenne: {stats.get('avg_cote', 0)}")
        lines.append("")
    
    return "\n".join(lines)


if __name__ == '__main__':
    import sys
    
    if len(sys.argv) < 2:
        print("Usage: python analytics_reports.py [daily|weekly|monthly] [date]")
        sys.exit(1)
    
    report_type = sys.argv[1]
    date_arg = sys.argv[2] if len(sys.argv) > 2 else None
    
    if report_type == 'daily':
        report = get_daily_report(date_arg)
        print(format_report_markdown(report, 'daily'))
    elif report_type == 'weekly':
        report = get_weekly_report(date_arg)
        print(format_report_markdown(report, 'weekly'))
    elif report_type == 'monthly':
        if date_arg:
            year, month = map(int, date_arg.split('-'))
        else:
            year, month = None, None
        report = get_monthly_report(year, month)
        print(format_report_markdown(report, 'monthly'))
    else:
        print(f"Type de rapport inconnu: {report_type}")
