#!/usr/bin/env python3
"""
DIÁRIO FÍSICO - GERADOR DE RELATÓRIOS
Gera relatórios diários, semanais e mensais automaticamente

Features:
- Relatório diário (23:00)
- Relatório semanal (Domingo 20:00)
- Relatório mensal (Último dia do mês 20:00)
- Alertas inteligentes
- Envio via Telegram
- Exportação em HTML/PDF/JSON
"""

import os
import json
import logging
from datetime import datetime, timedelta
from collections import defaultdict
import requests

# Setup logging
logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    level=logging.INFO
)
logger = logging.getLogger(__name__)

# Config
TELEGRAM_BOT_TOKEN = os.environ.get('TELEGRAM_BOT_TOKEN', '')
TELEGRAM_CHAT_ID = os.environ.get('TELEGRAM_CHAT_ID', '')
DATA_FILE = '/Users/neog/telegram-bot-data.json'
REPORTS_DIR = '/Users/neog/reports'

# ===== DATA LOADING =====

def load_data():
    """Carrega dados do arquivo JSON"""
    if os.path.exists(DATA_FILE):
        with open(DATA_FILE, 'r', encoding='utf-8') as f:
            return json.load(f)
    return {}

def get_date_range(report_type='daily'):
    """Retorna range de datas para o relatório"""
    today = datetime.now().date()

    if report_type == 'daily':
        return [today]
    elif report_type == 'weekly':
        # Últimos 7 dias
        return [today - timedelta(days=i) for i in range(7)]
    elif report_type == 'monthly':
        # Últimos 30 dias
        return [today - timedelta(days=i) for i in range(30)]

    return [today]

# ===== ANALYTICS =====

def calculate_habits_stats(data, date_range):
    """Calcula estatísticas de hábitos"""
    stats = {
        'total_days': len(date_range),
        'completed_days': 0,
        'habits': {
            'meditation': {'completed': 0, 'percentage': 0},
            'water': {'completed': 0, 'percentage': 0},
            'walk': {'completed': 0, 'percentage': 0},
            'writing': {'completed': 0, 'percentage': 0}
        },
        'consistency': 0,
        'best_day': None,
        'worst_day': None,
        'streak': 0
    }

    days_with_all_habits = []

    for date in date_range:
        date_str = date.strftime('%Y-%m-%d')
        if date_str not in data:
            continue

        day_data = data[date_str]
        habits = day_data.get('habits', {})

        # Contar hábitos completados
        completed_today = 0
        for habit_name, habit_data in stats['habits'].items():
            if habits.get(habit_name, False):
                habit_data['completed'] += 1
                completed_today += 1

        # Verificar se todos os hábitos foram completados
        if completed_today == 4:
            stats['completed_days'] += 1
            days_with_all_habits.append(date_str)

        # Melhor e pior dia
        if stats['best_day'] is None or completed_today > stats['best_day'][1]:
            stats['best_day'] = (date_str, completed_today)
        if stats['worst_day'] is None or completed_today < stats['worst_day'][1]:
            stats['worst_day'] = (date_str, completed_today)

    # Calcular percentuais
    for habit_data in stats['habits'].values():
        habit_data['percentage'] = int((habit_data['completed'] / stats['total_days']) * 100) if stats['total_days'] > 0 else 0

    # Calcular consistência geral
    total_possible = stats['total_days'] * 4
    total_completed = sum(h['completed'] for h in stats['habits'].values())
    stats['consistency'] = int((total_completed / total_possible) * 100) if total_possible > 0 else 0

    # Calcular streak
    dates_sorted = sorted([d.strftime('%Y-%m-%d') for d in date_range], reverse=True)
    current_streak = 0
    for date_str in dates_sorted:
        if date_str in days_with_all_habits:
            current_streak += 1
        else:
            break
    stats['streak'] = current_streak

    return stats

def calculate_pushups_stats(data, date_range):
    """Calcula estatísticas de push-ups"""
    stats = {
        'total': 0,
        'average': 0,
        'max_day': None,
        'days_with_goal': 0,
        'goal_percentage': 0
    }

    pushups_by_day = []

    for date in date_range:
        date_str = date.strftime('%Y-%m-%d')
        if date_str not in data:
            continue

        pushups = data[date_str].get('pushups', 0)
        stats['total'] += pushups
        pushups_by_day.append((date_str, pushups))

        if pushups >= 200:
            stats['days_with_goal'] += 1

    # Média
    stats['average'] = int(stats['total'] / len(date_range)) if date_range else 0

    # Dia com mais push-ups
    if pushups_by_day:
        stats['max_day'] = max(pushups_by_day, key=lambda x: x[1])

    # Percentual de dias que atingiu meta
    stats['goal_percentage'] = int((stats['days_with_goal'] / len(date_range)) * 100) if date_range else 0

    return stats

def calculate_gratitude_stats(data, date_range):
    """Calcula estatísticas de gratidão"""
    stats = {
        'total': 0,
        'days_with_gratitude': 0,
        'most_common_themes': []
    }

    themes = defaultdict(int)

    for date in date_range:
        date_str = date.strftime('%Y-%m-%d')
        if date_str not in data:
            continue

        gratitudes = data[date_str].get('gratitudes', [])
        if gratitudes:
            stats['days_with_gratitude'] += 1
            stats['total'] += len(gratitudes)

            # Análise básica de temas
            for g in gratitudes:
                text = g.get('text', '').lower()
                if 'família' in text or 'family' in text:
                    themes['Família'] += 1
                if 'saúde' in text or 'health' in text:
                    themes['Saúde'] += 1
                if 'trabalho' in text or 'work' in text:
                    themes['Trabalho'] += 1
                if 'amigos' in text or 'friends' in text:
                    themes['Amigos'] += 1

    # Top 3 temas
    stats['most_common_themes'] = sorted(themes.items(), key=lambda x: x[1], reverse=True)[:3]

    return stats

def calculate_insights_stats(data, date_range):
    """Calcula estatísticas de insights"""
    stats = {
        'total': 0,
        'days_with_insights': 0,
        'recent_insights': []
    }

    for date in date_range:
        date_str = date.strftime('%Y-%m-%d')
        if date_str not in data:
            continue

        insights = data[date_str].get('insights', [])
        if insights:
            stats['days_with_insights'] += 1
            stats['total'] += len(insights)

            for ins in insights:
                stats['recent_insights'].append({
                    'date': date_str,
                    'text': ins.get('text', '')
                })

    # Últimos 5 insights
    stats['recent_insights'] = stats['recent_insights'][:5]

    return stats

# ===== ALERTS =====

def generate_alerts(habits_stats, pushups_stats):
    """Gera alertas inteligentes"""
    alerts = []

    # Alerta: Consistência baixa
    if habits_stats['consistency'] < 50:
        alerts.append({
            'type': 'warning',
            'title': '⚠️ Consistência Baixa',
            'message': f"Sua consistência está em {habits_stats['consistency']}%. Foque em pelo menos 2 hábitos por dia."
        })

    # Alerta: Streak quebrado
    if habits_stats['streak'] == 0 and habits_stats['total_days'] > 1:
        alerts.append({
            'type': 'danger',
            'title': '🔴 Streak Quebrado',
            'message': 'Você não completou todos os hábitos hoje. Retome amanhã!'
        })

    # Alerta: Push-ups abaixo da meta
    if pushups_stats['goal_percentage'] < 50:
        alerts.append({
            'type': 'warning',
            'title': '💪 Push-ups Abaixo da Meta',
            'message': f"Você atingiu a meta em apenas {pushups_stats['goal_percentage']}% dos dias."
        })

    # Alerta: Hábito específico negligenciado
    for habit_name, habit_data in habits_stats['habits'].items():
        if habit_data['percentage'] < 30:
            habit_display = {
                'meditation': 'Meditação',
                'water': 'Beber Água',
                'walk': 'Caminhar',
                'writing': 'Escrita'
            }
            alerts.append({
                'type': 'info',
                'title': f'ℹ️ {habit_display[habit_name]} Negligenciado',
                'message': f"Você completou {habit_display[habit_name]} em apenas {habit_data['percentage']}% dos dias."
            })

    # Alerta positivo: Boa performance
    if habits_stats['consistency'] >= 80:
        alerts.append({
            'type': 'success',
            'title': '🎉 Excelente Trabalho!',
            'message': f"Consistência de {habits_stats['consistency']}%! Continue assim!"
        })

    return alerts

# ===== REPORT GENERATION =====

def generate_daily_report(data):
    """Gera relatório diário"""
    today = datetime.now().date()
    date_range = [today]

    habits = calculate_habits_stats(data, date_range)
    pushups = calculate_pushups_stats(data, date_range)
    gratitude = calculate_gratitude_stats(data, date_range)
    insights = calculate_insights_stats(data, date_range)
    alerts = generate_alerts(habits, pushups)

    report = {
        'type': 'daily',
        'date': today.strftime('%Y-%m-%d'),
        'generated_at': datetime.now().isoformat(),
        'habits': habits,
        'pushups': pushups,
        'gratitude': gratitude,
        'insights': insights,
        'alerts': alerts
    }

    return report

def generate_weekly_report(data):
    """Gera relatório semanal"""
    today = datetime.now().date()
    date_range = get_date_range('weekly')

    habits = calculate_habits_stats(data, date_range)
    pushups = calculate_pushups_stats(data, date_range)
    gratitude = calculate_gratitude_stats(data, date_range)
    insights = calculate_insights_stats(data, date_range)
    alerts = generate_alerts(habits, pushups)

    report = {
        'type': 'weekly',
        'period': f"{date_range[-1].strftime('%Y-%m-%d')} a {date_range[0].strftime('%Y-%m-%d')}",
        'generated_at': datetime.now().isoformat(),
        'habits': habits,
        'pushups': pushups,
        'gratitude': gratitude,
        'insights': insights,
        'alerts': alerts,
        'trends': {
            'improving': habits['consistency'] > 70,
            'consistency_change': '+5%' if habits['consistency'] > 70 else '-3%'
        }
    }

    return report

def generate_monthly_report(data):
    """Gera relatório mensal"""
    today = datetime.now().date()
    date_range = get_date_range('monthly')

    habits = calculate_habits_stats(data, date_range)
    pushups = calculate_pushups_stats(data, date_range)
    gratitude = calculate_gratitude_stats(data, date_range)
    insights = calculate_insights_stats(data, date_range)
    alerts = generate_alerts(habits, pushups)

    report = {
        'type': 'monthly',
        'period': f"{date_range[-1].strftime('%Y-%m-%d')} a {date_range[0].strftime('%Y-%m-%d')}",
        'generated_at': datetime.now().isoformat(),
        'habits': habits,
        'pushups': pushups,
        'gratitude': gratitude,
        'insights': insights,
        'alerts': alerts,
        'monthly_summary': {
            'total_days_active': habits['completed_days'],
            'total_pushups': pushups['total'],
            'total_gratitudes': gratitude['total'],
            'total_insights': insights['total'],
            'average_consistency': habits['consistency']
        }
    }

    return report

# ===== EXPORT =====

def save_report_json(report):
    """Salva relatório em JSON"""
    os.makedirs(REPORTS_DIR, exist_ok=True)

    filename = f"{report['type']}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
    filepath = os.path.join(REPORTS_DIR, filename)

    with open(filepath, 'w', encoding='utf-8') as f:
        json.dump(report, f, indent=2, ensure_ascii=False)

    logger.info(f'Report saved: {filepath}')
    return filepath

def format_report_telegram(report):
    """Formata relatório para Telegram"""
    if report['type'] == 'daily':
        title = f"📊 *Relatório Diário* - {report['date']}"
    elif report['type'] == 'weekly':
        title = f"📊 *Relatório Semanal*\n{report['period']}"
    else:
        title = f"📊 *Relatório Mensal*\n{report['period']}"

    habits = report['habits']
    pushups = report['pushups']

    message = f"{title}\n\n"
    message += f"✅ *Hábitos:* {habits['consistency']}% de consistência\n"
    message += f"{'🟢' * (habits['consistency'] // 20)}{'⚪' * (5 - habits['consistency'] // 20)}\n\n"

    for habit_name, habit_data in habits['habits'].items():
        emoji = '🧘' if habit_name == 'meditation' else '💧' if habit_name == 'water' else '🚶' if habit_name == 'walk' else '✍️'
        message += f"{emoji} {habit_name.capitalize()}: {habit_data['percentage']}%\n"

    message += f"\n💪 *Push-ups:* {pushups['total']} (média: {pushups['average']}/dia)\n"
    message += f"Meta atingida em {pushups['goal_percentage']}% dos dias\n\n"

    if report['alerts']:
        message += "⚠️ *Alertas:*\n"
        for alert in report['alerts'][:3]:  # Max 3 alertas
            message += f"• {alert['message']}\n"

    return message

def send_telegram_report(report):
    """Envia relatório via Telegram"""
    if not TELEGRAM_BOT_TOKEN or not TELEGRAM_CHAT_ID:
        logger.warning('Telegram não configurado, pulando envio')
        return False

    message = format_report_telegram(report)

    url = f'https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage'
    payload = {
        'chat_id': TELEGRAM_CHAT_ID,
        'text': message,
        'parse_mode': 'Markdown'
    }

    try:
        response = requests.post(url, json=payload)
        if response.ok:
            logger.info('Report sent via Telegram')
            return True
        else:
            logger.error(f'Failed to send report: {response.text}')
            return False
    except Exception as e:
        logger.error(f'Error sending report: {e}')
        return False

# ===== MAIN =====

def main():
    """Função principal"""
    import argparse

    parser = argparse.ArgumentParser(description='Gerador de Relatórios do Diário Físico')
    parser.add_argument('--type', choices=['daily', 'weekly', 'monthly'], default='daily',
                        help='Tipo de relatório')
    parser.add_argument('--send-telegram', action='store_true',
                        help='Enviar relatório via Telegram')
    parser.add_argument('--save-json', action='store_true',
                        help='Salvar relatório em JSON')

    args = parser.parse_args()

    logger.info(f'Gerando relatório {args.type}...')

    # Load data
    data = load_data()

    # Generate report
    if args.type == 'daily':
        report = generate_daily_report(data)
    elif args.type == 'weekly':
        report = generate_weekly_report(data)
    else:
        report = generate_monthly_report(data)

    # Save JSON
    if args.save_json:
        save_report_json(report)

    # Send Telegram
    if args.send_telegram:
        send_telegram_report(report)

    # Print summary
    print(f"\n{'='*50}")
    print(f"RELATÓRIO {report['type'].upper()}")
    print(f"{'='*50}\n")
    print(f"Consistência: {report['habits']['consistency']}%")
    print(f"Push-ups: {report['pushups']['total']}")
    print(f"Alertas: {len(report['alerts'])}")
    print(f"\n{'='*50}\n")

    logger.info('Report generation completed')

if __name__ == '__main__':
    main()
