from rest_framework import viewsets from rest_framework.decorators import api_view, permission_classes from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from django.db.models import Count, Avg, Sum, F from django.db.models.functions import Coalesce from datetime import datetime, timedelta from .models import TrainingLogEntry from .serializers import TrainingLogEntrySerializer from wrestlers.models import Wrestler class TrainingLogEntryViewSet(viewsets.ModelViewSet): permission_classes = [IsAuthenticated] serializer_class = TrainingLogEntrySerializer def get_queryset(self): queryset = TrainingLogEntry.objects.all() wrestler = self.request.query_params.get('wrestler') exercise = self.request.query_params.get('exercise') date_from = self.request.query_params.get('date_from') date_to = self.request.query_params.get('date_to') if wrestler: queryset = queryset.filter(wrestler=wrestler) if exercise: queryset = queryset.filter(exercise=exercise) if date_from: queryset = queryset.filter(logged_at__date__gte=date_from) if date_to: queryset = queryset.filter(logged_at__date__lte=date_to) return queryset.select_related('wrestler', 'exercise', 'training') @api_view(['GET']) @permission_classes([IsAuthenticated]) def training_log_stats(request): wrestler_id = request.query_params.get('wrestler') today = datetime.now().date() week_start = today - timedelta(days=today.weekday()) queryset = TrainingLogEntry.objects.all() if wrestler_id: queryset = queryset.filter(wrestler=wrestler_id) total_entries = queryset.count() unique_exercises = queryset.values('exercise').distinct().count() total_reps = queryset.aggregate(total=Coalesce(Sum(F('reps') * F('sets')), 0))['total'] or 0 avg_sets = queryset.aggregate(avg=Avg('sets'))['avg'] or 0 avg_rating = queryset.aggregate(avg=Avg('rating'))['avg'] or 0 this_week = queryset.filter(logged_at__date__gte=week_start).count() top_exercises = queryset.values('exercise__name').annotate( count=Count('id') ).order_by('-count')[:5] progress = {} exercises = queryset.values('exercise', 'exercise__name').distinct() for ex in exercises: ex_id = ex['exercise'] entries = queryset.filter(exercise=ex_id).order_by('logged_at') if entries.count() >= 2: first_reps = entries.first().reps * entries.first().sets last_reps = entries.last().reps * entries.last().sets if first_reps > 0: change = ((last_reps - first_reps) / first_reps) * 100 progress[ex['exercise__name']] = { 'before': first_reps, 'after': last_reps, 'change_percent': round(change, 1) } return Response({ 'total_entries': total_entries, 'unique_exercises': unique_exercises, 'total_reps': total_reps, 'avg_sets': round(avg_sets, 1), 'avg_rating': round(avg_rating, 1), 'this_week': this_week, 'top_exercises': [{'name': e['exercise__name'], 'count': e['count']} for e in top_exercises], 'progress': progress, }) @api_view(['GET']) @permission_classes([IsAuthenticated]) def training_log_compare(request): wrestler1_id = request.query_params.get('wrestler1') wrestler2_id = request.query_params.get('wrestler2') if not wrestler1_id or not wrestler2_id: return Response({'error': 'Both wrestler1 and wrestler2 required'}, status=400) wrestler1 = Wrestler.objects.get(id=wrestler1_id) wrestler2 = Wrestler.objects.get(id=wrestler2_id) entries1 = TrainingLogEntry.objects.filter(wrestler=wrestler1) entries2 = TrainingLogEntry.objects.filter(wrestler=wrestler2) exercises1 = entries1.values('exercise', 'exercise__name').distinct() exercises2 = entries2.values('exercise', 'exercise__name').distinct() common_exercises = set(e['exercise'] for e in exercises1) & set(e['exercise'] for e in exercises2) comparison = [] for ex_id in common_exercises: ex_name = entries1.filter(exercise=ex_id).first().exercise.name avg1 = entries1.filter(exercise=ex_id).aggregate(avg=Avg(F('reps') * F('sets')))['avg'] or 0 avg2 = entries2.filter(exercise=ex_id).aggregate(avg=Avg(F('reps') * F('sets')))['avg'] or 0 comparison.append({ 'exercise': ex_name, 'wrestler1_avg': round(avg1, 1), 'wrestler2_avg': round(avg2, 1) }) return Response({ 'wrestler1': {'id': wrestler1.id, 'name': str(wrestler1)}, 'wrestler2': {'id': wrestler2.id, 'name': str(wrestler2)}, 'exercises': comparison })