"""
Push-Up Counter - Gerador de Relatórios
Consolida logs e gera estatísticas detalhadas
"""

import json
import os
from pathlib import Path
from datetime import datetime
from collections import defaultdict


def load_all_sessions(logs_dir="pushup_logs"):
    """Carrega todos os arquivos de sessão"""
    logs_path = Path(logs_dir)

    if not logs_path.exists():
        print(f"❌ Diretório {logs_dir} não encontrado!")
        return []

    sessions = []
    session_files = list(logs_path.glob("session_*.json"))

    for session_file in session_files:
        try:
            with open(session_file, 'r', encoding='utf-8') as f:
                session_data = json.load(f)
                sessions.append(session_data)
        except Exception as e:
            print(f"⚠️ Erro ao carregar {session_file.name}: {e}")

    return sessions


def analyze_sessions(sessions):
    """Analisa todas as sessões e gera estatísticas"""
    if not sessions:
        return None

    stats = {
        "total_sessions": len(sessions),
        "total_pushups": 0,
        "total_duration_seconds": 0,
        "total_frames": 0,
        "record_pushups": 0,
        "record_session_id": None,
        "avg_pushups_per_session": 0,
        "avg_duration_per_session": 0,
        "avg_fps_overall": 0,
        "sessions_by_date": defaultdict(int),
        "pushups_by_date": defaultdict(int),
        "trends": {},
        "best_performance": {},
        "consistency": {}
    }

    fps_samples = []
    session_durations = []
    pushup_counts = []

    for session in sessions:
        # Contadores básicos
        stats["total_pushups"] += session.get("total_pushups", 0)
        stats["total_duration_seconds"] += session.get("duration_seconds", 0)
        stats["total_frames"] += session.get("metrics", {}).get("total_frames", 0)

        # Recorde
        session_pushups = session.get("total_pushups", 0)
        if session_pushups > stats["record_pushups"]:
            stats["record_pushups"] = session_pushups
            stats["record_session_id"] = session.get("session_id")

        # Médias
        fps_samples.append(session.get("avg_fps", 0))
        session_durations.append(session.get("duration_seconds", 0))
        pushup_counts.append(session_pushups)

        # Agrupar por data
        try:
            start_time = datetime.fromisoformat(session.get("start_time", ""))
            date_key = start_time.strftime("%Y-%m-%d")
            stats["sessions_by_date"][date_key] += 1
            stats["pushups_by_date"][date_key] += session_pushups
        except:
            pass

    # Calcular médias
    if len(sessions) > 0:
        stats["avg_pushups_per_session"] = stats["total_pushups"] / len(sessions)
        stats["avg_duration_per_session"] = stats["total_duration_seconds"] / len(sessions)
        stats["avg_fps_overall"] = sum(fps_samples) / len(fps_samples) if fps_samples else 0

    # Análise de tendências
    stats["trends"] = analyze_trends(sessions)

    # Melhor desempenho
    stats["best_performance"] = {
        "most_pushups": max(pushup_counts) if pushup_counts else 0,
        "longest_session": max(session_durations) if session_durations else 0,
        "shortest_session": min(session_durations) if session_durations else 0,
        "best_fps": max(fps_samples) if fps_samples else 0
    }

    # Consistência (desvio padrão das flexões)
    if len(pushup_counts) > 1:
        mean = sum(pushup_counts) / len(pushup_counts)
        variance = sum((x - mean) ** 2 for x in pushup_counts) / len(pushup_counts)
        std_dev = variance ** 0.5
        stats["consistency"]["std_deviation"] = std_dev
        stats["consistency"]["coefficient_variation"] = (std_dev / mean * 100) if mean > 0 else 0

    return stats


def analyze_trends(sessions):
    """Analisa tendências ao longo do tempo"""
    if len(sessions) < 2:
        return {"message": "Dados insuficientes para análise de tendência"}

    # Ordenar por data
    sorted_sessions = sorted(
        sessions,
        key=lambda s: s.get("start_time", "")
    )

    # Comparar primeira metade vs segunda metade
    mid = len(sorted_sessions) // 2
    first_half = sorted_sessions[:mid]
    second_half = sorted_sessions[mid:]

    avg_first = sum(s.get("total_pushups", 0) for s in first_half) / len(first_half)
    avg_second = sum(s.get("total_pushups", 0) for s in second_half) / len(second_half)

    improvement = ((avg_second - avg_first) / avg_first * 100) if avg_first > 0 else 0

    return {
        "avg_first_half": round(avg_first, 2),
        "avg_second_half": round(avg_second, 2),
        "improvement_percent": round(improvement, 2),
        "trend": "melhorando" if improvement > 5 else "estável" if improvement > -5 else "piorando"
    }


def generate_text_report(stats):
    """Gera relatório em texto formatado"""
    report = []
    report.append("=" * 60)
    report.append("📊 RELATÓRIO DE DESEMPENHO - PUSH-UP COUNTER")
    report.append("=" * 60)
    report.append("")

    report.append("📈 ESTATÍSTICAS GERAIS")
    report.append("-" * 60)
    report.append(f"Total de Sessões:        {stats['total_sessions']}")
    report.append(f"Total de Flexões:        {stats['total_pushups']}")
    report.append(f"Total de Frames:         {stats['total_frames']:,}")
    report.append(f"Duração Total:           {format_duration(stats['total_duration_seconds'])}")
    report.append("")

    report.append("🏆 RECORDES")
    report.append("-" * 60)
    report.append(f"Recorde de Flexões:      {stats['record_pushups']} flexões")
    report.append(f"Sessão do Recorde:       {stats['record_session_id']}")
    report.append(f"Maior Duração:           {format_duration(stats['best_performance']['longest_session'])}")
    report.append(f"Melhor FPS:              {stats['best_performance']['best_fps']:.1f}")
    report.append("")

    report.append("📊 MÉDIAS")
    report.append("-" * 60)
    report.append(f"Flexões por Sessão:      {stats['avg_pushups_per_session']:.1f}")
    report.append(f"Duração por Sessão:      {format_duration(stats['avg_duration_per_session'])}")
    report.append(f"FPS Geral:               {stats['avg_fps_overall']:.1f}")
    report.append("")

    if "trends" in stats and "improvement_percent" in stats["trends"]:
        report.append("📈 ANÁLISE DE TENDÊNCIA")
        report.append("-" * 60)
        report.append(f"Média 1ª Metade:         {stats['trends']['avg_first_half']} flexões")
        report.append(f"Média 2ª Metade:         {stats['trends']['avg_second_half']} flexões")
        report.append(f"Melhoria:                {stats['trends']['improvement_percent']:+.1f}%")
        report.append(f"Tendência:               {stats['trends']['trend'].upper()}")
        report.append("")

    if "consistency" in stats and "std_deviation" in stats["consistency"]:
        report.append("📉 CONSISTÊNCIA")
        report.append("-" * 60)
        report.append(f"Desvio Padrão:           {stats['consistency']['std_deviation']:.2f}")
        report.append(f"Coef. de Variação:       {stats['consistency']['coefficient_variation']:.1f}%")
        interpretation = "alta" if stats['consistency']['coefficient_variation'] < 20 else "média" if stats['consistency']['coefficient_variation'] < 40 else "baixa"
        report.append(f"Interpretação:           Consistência {interpretation}")
        report.append("")

    report.append("📅 SESSÕES POR DATA")
    report.append("-" * 60)
    for date, count in sorted(stats['sessions_by_date'].items()):
        pushups = stats['pushups_by_date'][date]
        report.append(f"{date}:   {count} sessões, {pushups} flexões")

    report.append("")
    report.append("=" * 60)
    report.append(f"Relatório gerado em: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    report.append("=" * 60)

    return "\n".join(report)


def format_duration(seconds):
    """Formata duração em horas:minutos:segundos"""
    hours = int(seconds // 3600)
    minutes = int((seconds % 3600) // 60)
    secs = int(seconds % 60)

    if hours > 0:
        return f"{hours}h {minutes}m {secs}s"
    elif minutes > 0:
        return f"{minutes}m {secs}s"
    else:
        return f"{secs}s"


def main():
    """Função principal"""
    print("🔍 Gerando relatório de desempenho...\n")

    # Carregar sessões
    sessions = load_all_sessions()

    if not sessions:
        print("❌ Nenhuma sessão encontrada!")
        print("Execute o pushup_counter.py para gerar dados primeiro.")
        return

    print(f"✅ {len(sessions)} sessões carregadas\n")

    # Analisar
    stats = analyze_sessions(sessions)

    # Gerar relatório texto
    text_report = generate_text_report(stats)

    # Exibir no console
    print(text_report)

    # Salvar em arquivo
    report_path = Path("pushup_logs") / "report.txt"
    with open(report_path, 'w', encoding='utf-8') as f:
        f.write(text_report)

    print(f"\n💾 Relatório salvo em: {report_path}")

    # Salvar estatísticas em JSON
    stats_path = Path("pushup_logs") / "statistics.json"
    with open(stats_path, 'w', encoding='utf-8') as f:
        # Converter defaultdict para dict normal para JSON
        stats_json = {
            **stats,
            "sessions_by_date": dict(stats["sessions_by_date"]),
            "pushups_by_date": dict(stats["pushups_by_date"])
        }
        json.dump(stats_json, f, indent=2, ensure_ascii=False)

    print(f"📊 Estatísticas JSON salvas em: {stats_path}")


if __name__ == "__main__":
    main()
