from django.shortcuts import render, get_object_or_404
from django.contrib.auth.decorators import user_passes_test
from django.utils import timezone
from django.db.models import Count
from django.views.decorators.cache import cache_page
from django.contrib.auth.models import User
from courses.models import Course, Lesson
from blog.models import Post
from progression.models import Progression
import json

def home(request):
    courses = Course.objects.order_by('-created_at')[:6]
    return render(request, 'home.html', {'courses': courses}) 

def premium(request, course_id):
    """Landing page présentant les avantages du Premium."""
    course = get_object_or_404(Course, pk=course_id)
    return render(request, 'premium.html', {'course': course})


# 15 minutes de cache sur la page complète (sauf si décochée plus tard pour des blocs en direct)
@user_passes_test(lambda u: u.is_superuser)
@cache_page(60 * 15)
def stats_dashboard(request):
    """ Tableau de bord statistiques réservé aux superadministrateurs.
    Périodes supportées: 7, 30, 90, 180 jours (GET param 'p'). """

    # Période
    period_options = [7, 30, 90, 180]
    try:
        p = int(request.GET.get('p', 30))
    except ValueError:
        p = 30
    if p not in period_options:
        p = 30

    now = timezone.now()
    start_dt = now - timezone.timedelta(days=p-1)  # inclut aujourd'hui

    # Utilisateurs
    total_users = User.objects.count()
    new_users_qs = User.objects.filter(date_joined__date__gte=start_dt.date(), date_joined__date__lte=now.date())
    # Séries quotidiennes nouveaux utilisateurs
    new_users_by_day = (
        new_users_qs
        .extra(select={'day': "date(date_joined)"})
        .values('day')
        .annotate(c=Count('id'))
    )

    # Activité approximée via Progression mise à jour
    active_users_qs = (
        Progression.objects.filter(updated_at__date__gte=start_dt.date(), updated_at__date__lte=now.date())
        .values('user').distinct()
    )
    active_users_count = active_users_qs.count()

    # Cours
    total_courses = Course.objects.count()
    total_courses_enabled = Course.objects.filter(enable=True).count()
    new_courses_by_day = (
        Course.objects.filter(created_at__date__gte=start_dt.date(), created_at__date__lte=now.date())
        .extra(select={'day': "date(created_at)"})
        .values('day').annotate(c=Count('id'))
    )

    # Leçons
    total_lessons = Lesson.objects.count()

    # Achèvements de leçons (via table de liaison M2M)
    through = Progression.completed_lessons.through
    lesson_completions_by_day = (
        through.objects.filter(
            progression__updated_at__date__gte=start_dt.date(),
            progression__updated_at__date__lte=now.date(),
        )
        .extra(select={'day': "date(progression_updated_at)"}) if 'progression_updated_at' in [f.name for f in through._meta.fields]
        else through.objects.extra(select={'day': "date(created_at)"})  # fallback si champs créé n'existe pas
    )
    # Si la table M2M n'a pas de timestamps, on utilisera updated_at de Progression pour l'activité par jour
    # donc on refait une série quotidienne d'activité progression
    progress_activity_by_day = (
        Progression.objects.filter(updated_at__date__gte=start_dt.date(), updated_at__date__lte=now.date())
        .extra(select={'day': "date(updated_at)"})
        .values('day').annotate(c=Count('id'))
    )

    # Blog
    total_posts = Post.objects.count()
    new_posts_by_day = (
        Post.objects.filter(created_at__date__gte=start_dt.date(), created_at__date__lte=now.date())
        .extra(select={'day': "date(created_at)"})
        .values('day').annotate(c=Count('id'))
    )

    # Revenus/Paiements & Technique (placeholders faute de sources)
    revenus_disponibles = False
    technique_disponible = False

    # Helper pour avoir toutes les dates de la période et remplir les trous
    def build_series_dict(qs, date_key='day', count_key='c'):
        counts = {str(item[date_key]): item[count_key] for item in qs}
        days = []
        values = []
        d = start_dt.date()
        while d <= now.date():
            key = str(d)
            days.append(key)
            values.append(counts.get(key, 0))
            d += timezone.timedelta(days=1)
        return days, values

    days_users, values_new_users = build_series_dict(new_users_by_day)
    days_courses, values_new_courses = build_series_dict(new_courses_by_day)
    days_posts, values_new_posts = build_series_dict(new_posts_by_day)
    days_activity, values_activity = build_series_dict(progress_activity_by_day)

    # Tables simples (jour, valeur)
    new_users_table = list(zip(days_users, values_new_users))
    new_courses_table = list(zip(days_courses, values_new_courses))

    context = {
        'period_options': period_options,
        'p': p,
        'start_date': start_dt.date(),
        'end_date': now.date(),

        # KPI
        'kpi': {
            'total_users': total_users,
            'new_users_period': sum(values_new_users),
            'active_users_period': active_users_count,
            'total_courses': total_courses,
            'courses_enabled': total_courses_enabled,
            'total_lessons': total_lessons,
            'total_posts': total_posts,
        },

        # Séries pour graphiques
        'series': {
            'days': days_users,  # mêmes intervalles pour tous
            'new_users': values_new_users,
            'new_courses': values_new_courses,
            'new_posts': values_new_posts,
            'activity_progress': values_activity,
        },

        # Disponibilité des sections
        'revenus_disponibles': revenus_disponibles,
        'technique_disponible': technique_disponible,

        # Tables
        'new_users_table': new_users_table,
        'new_courses_table': new_courses_table,
    }

    # Sérialisation JSON pour Chart.js
    context['series_json'] = json.dumps(context['series'])
    context['labels_json'] = json.dumps(context['series']['days'])

    return render(request, 'home/stats_dashboard.html', context)
