# progress/views.py

from datetime import timedelta
from django.utils import timezone
from django.db.models import F
from django.db import transaction
from rest_framework import generics, permissions, status
from rest_framework.views import APIView
from rest_framework.response import Response
from django.shortcuts import get_object_or_404
import datetime

from .serializers import SubjectProgressSerializer
from .models import SubjectProgress, ExerciseAttempt, UserNodeProgress, SkillMastery
from users.models import AppSettings, Profile
from subjects.models import Exercise, Subject, PathNode

# ✅ ایمپورت جدید: برای آپدیت کردن مأموریت‌ها ضروری است
from gamification.models import UserMission 

class SubjectProgressView(APIView):
    """
    آمار پیشرفت کاربر در یک درس خاص را نمایش داده و درس فعلی کاربر را ثبت می‌کند.
    """
    permission_classes = [permissions.IsAuthenticated]

    @transaction.atomic
    def get(self, request, subject_id, *args, **kwargs):
        user = request.user
        subject = get_object_or_404(Subject, id=subject_id)
        
        profile, _ = Profile.objects.get_or_create(user=user)
        
        profile.active_subject = subject
        profile.save(update_fields=['active_subject'])
        
        progress, _ = SubjectProgress.objects.get_or_create(user=user, subject=subject)
        
        updates_to_save = []
        local_date_str = request.query_params.get('local_date')
        client_date = datetime.date.fromisoformat(local_date_str) if local_date_str else datetime.date.today()
        
        if progress.last_activity_date:
            days_diff = (client_date - progress.last_activity_date).days
            if days_diff > 1 and not progress.is_streak_frozen:
                progress.streak = 0
                progress.hearts = AppSettings.load().default_hearts_on_refill
                updates_to_save.extend(['streak', 'hearts'])
            elif days_diff == 1 and progress.hearts < AppSettings.load().default_hearts_on_refill:
                 progress.hearts = AppSettings.load().default_hearts_on_refill
                 updates_to_save.append('hearts')
        
        if updates_to_save:
            progress.save(update_fields=updates_to_save)
            
        serializer = SubjectProgressSerializer(progress)
        return Response(serializer.data)

class RecordExerciseAttemptView(APIView):
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request, *args, **kwargs):
        user = request.user
        exercise_id = request.data.get('exercise_id')
        was_correct = request.data.get('was_correct', False)

        if not exercise_id:
            return Response({'error': 'شناسه تمرین (exercise_id) مورد نیاز است.'}, status=status.HTTP_400_BAD_REQUEST)

        exercise = get_object_or_404(Exercise, id=exercise_id)
        subject = exercise.concept_level.concept.subject
        progress, _ = SubjectProgress.objects.get_or_create(user=user, subject=subject)
        
        if not was_correct and progress.hearts <= 0:
            return Response({'error': 'قلب شما تمام شده است.', 'hearts': 0}, status=status.HTTP_400_BAD_REQUEST)

        updates_to_save = []
        if not was_correct:
            progress.hearts = F('hearts') - 1
            updates_to_save.append('hearts')

        today = timezone.now().date()
        if progress.last_activity_date != today:
            if progress.last_activity_date and (today - progress.last_activity_date).days == 1:
                progress.streak = F('streak') + 1
            else:
                progress.streak = 1
            progress.last_activity_date = today
            updates_to_save.extend(['streak', 'last_activity_date'])

        if updates_to_save:
            progress.save(update_fields=updates_to_save)
        
        ExerciseAttempt.objects.create(user=user, exercise=exercise, was_correct=was_correct)

        if was_correct:
            for skill in exercise.skills.all():
                mastery, _ = SkillMastery.objects.get_or_create(user=user, skill=skill)
                mastery.score = F('score') + 10
                mastery.save()

        progress.refresh_from_db()
        return Response({'status': 'تلاش ثبت شد.', 'hearts': progress.hearts}, status=status.HTTP_200_OK)


class CompleteStageView(APIView):
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request, *args, **kwargs):
        path_node_id = request.data.get('path_node_id')
        was_perfect = request.data.get('was_perfect', False)

        if not path_node_id:
            return Response({'error': 'مقدار path_node_id مورد نیاز است.'}, status=status.HTTP_400_BAD_REQUEST)

        path_node = get_object_or_404(PathNode, id=path_node_id)
        user = request.user
        subject = path_node.unit.section.subject
        subject_progress, _ = SubjectProgress.objects.get_or_create(user=user, subject=subject)
        node_progress, _ = UserNodeProgress.objects.get_or_create(user=user, node=path_node)

        if node_progress.completed_stages >= path_node.num_stages:
            return Response({'status': 'این درس قبلاً تکمیل شده است.'}, status=status.HTTP_200_OK)

        xp_earned = path_node.base_xp_per_stage
        if was_perfect:
            xp_earned = int(xp_earned * 1.5)

        node_progress.completed_stages = F('completed_stages') + 1
        node_progress.last_played_at = timezone.now()
        node_progress.save()

        subject_progress.total_xp = F('total_xp') + xp_earned
        subject_progress.weekly_xp = F('weekly_xp') + xp_earned
        
        today = timezone.now().date()
        if subject_progress.last_activity_date != today:
            if subject_progress.last_activity_date and (today - subject_progress.last_activity_date).days == 1:
                subject_progress.streak = F('streak') + 1
            else:
                subject_progress.streak = 1
            subject_progress.last_activity_date = today

        subject_progress.save()
        subject_progress.refresh_from_db()
        node_progress.refresh_from_db()

        # =========================================================
        # ✅ بخش جدید: آپدیت مأموریت‌های سراسری (مهم)
        # =========================================================
        active_missions = UserMission.objects.filter(
            user=user,
            assigned_date=today,
            status='IN_PROGRESS'
        )

        for user_mission in active_missions:
            mission_type = user_mission.mission.mission_type
            should_update = False

            # اگر مأموریت از نوع "تکمیل مرحله" است
            if mission_type == 'COMPLETE_STAGES':
                user_mission.current_progress += 1
                should_update = True
            
            # اگر مأموریت از نوع "بدون غلط" است و کاربر هم پرفکت زده
            elif mission_type == 'PERFECT_STAGES' and was_perfect:
                user_mission.current_progress += 1
                should_update = True

            if should_update:
                if user_mission.current_progress >= user_mission.mission.goal_value:
                    user_mission.current_progress = user_mission.mission.goal_value
                    user_mission.status = 'COMPLETED'
                
                user_mission.save()
        # =========================================================

        return Response({
            'status': 'مرحله با موفقیت ثبت شد.',
            'completed_stages': node_progress.completed_stages,
            'total_xp_in_subject': subject_progress.total_xp
        }, status=status.HTTP_200_OK)