# stats/views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from django.db import models
from django.db.models.functions import TruncMonth, ExtractWeek, ExtractYear

from django.db.models import (
    Q,
    Count,
    Sum,
    Avg,
    F,
    DecimalField,
    Case,
    When,
    Value,
    IntegerField,
    Max,
    Min,
)
from django.db.models.functions import TruncMonth, TruncYear, Coalesce
from django.utils import timezone
from datetime import datetime, timedelta, date
from decimal import Decimal

from people.models import Student, Teacher, Parent, StudentParent
from academics.models import (
    AcademicClass,
    AcademicYear,
    Subject,
    StudentEnrollment,
    Standard,
    Section,
    SubjectTeacher,
)
from exam.models import Exam, ExamSubject, StudentMarks, ExamResult
from fee.models import FeePayment, StudentFeeAssignment, ClassFeeStructure
from attendance.models import StudentAttendance, AttendanceSession
from tasks.models import ClassTask, TaskSubmission

from .serializers import (
    DashboardSummarySerializer,
    StudentAdmissionTrendSerializer,
    ClassPerformanceSerializer,
    SubjectPerformanceSerializer,
    TeacherPerformanceSerializer,
    TopPerformingStudentSerializer,
    FeeCollectionSerializer,
    AttendanceAnalyticsSerializer,
    GenderDistributionSerializer,
    StandardWiseDistributionSerializer,
    ReportFilterSerializer,
    RecentActivitySerializer,
    DashboardSummarySerializer,
    StudentAdmissionTrendSerializer,
)

import logging

logger = logging.getLogger(__name__)


class DashboardSummaryView(APIView):
    """
    GET /api/school-admin/stats/dashboard/

    Get main dashboard summary statistics
    """

    permission_classes = [IsAuthenticated]

    def get(self, request):
        try:
            # Get current academic year
            today = timezone.now().date()
            current_academic_year = AcademicYear.objects.filter(is_active=True).first()

            # Basic counts
            total_students = Student.objects.filter(is_active=True).count()
            total_teachers = Teacher.objects.filter(is_active=True).count()
            total_parents = Parent.objects.filter(is_active=True).count()
            total_classes = AcademicClass.objects.filter(is_active=True).count()
            total_active_classes = AcademicClass.objects.filter(
                is_active=True, current_strength__gt=0
            ).count()
            total_subjects = Subject.objects.filter(is_active=True).count()

            # Active enrollments
            active_enrollments = StudentEnrollment.objects.filter(
                is_active=True
            ).count()

            # Today's attendance (all full-day sessions for today)
            today_attendance = StudentAttendance.objects.filter(
                session__date=today,
                session__session_type="FULL_DAY",
                is_active=True,
            )
            today_present = today_attendance.filter(status="PRESENT").count()
            today_absent  = today_attendance.filter(status="ABSENT").count()
            today_late    = today_attendance.filter(status="LATE").count()
            today_leave   = today_attendance.filter(status="LEAVE").count()
            today_total   = today_present + today_absent + today_late + today_leave
            today_attendance_pct = (
                round((today_present + today_late) / today_total * 100, 1)
                if today_total > 0 else 0
            )

            # Pending tasks — tasks that have no submission yet (truly unsubmitted)
            pending_tasks = ClassTask.objects.filter(
                is_active=True,
                is_published=True,
                due_date__gte=today,
            ).count()

            # New students enrolled this calendar month
            first_of_month = today.replace(day=1)
            new_students_this_month = StudentEnrollment.objects.filter(
                is_active=True,
                created_at__date__gte=first_of_month,
            ).count()

            # Upcoming exams
            upcoming_exams = Exam.objects.filter(
                start_date__gte=today, is_active=True, status="scheduled"
            ).count()

            # Fee collection — use ClassFeeStructure as the expected total
            total_fee_expected = ClassFeeStructure.objects.filter(
                is_active=True,
            ).aggregate(total=Sum("amount"))["total"] or Decimal("0.00")

            total_fee_collected = FeePayment.objects.filter(
                status="completed"
            ).aggregate(total=Sum("amount_paid"))["total"] or Decimal("0.00")

            pending_fee = max(Decimal("0.00"), total_fee_expected - total_fee_collected)

            collection_percentage = (
                round(float(total_fee_collected) / float(total_fee_expected) * 100, 1)
                if total_fee_expected > 0 else 0
            )

            # Overall pass percentage
            total_exam_results  = ExamResult.objects.count()
            passed_exam_results = ExamResult.objects.filter(result_status="pass").count()
            overall_pass_percentage = (
                round(passed_exam_results / total_exam_results * 100, 1)
                if total_exam_results > 0 else 0
            )

            data = {
                "total_students": total_students,
                "total_teachers": total_teachers,
                "total_parents": total_parents,
                "total_classes": total_classes,
                "total_active_classes": total_active_classes,
                "total_subjects": total_subjects,
                "active_enrollments": active_enrollments,
                # Today attendance
                "today_present_students": today_present,
                "today_absent_students": today_absent,
                "today_late_students": today_late,
                "today_leave_students": today_leave,
                "today_total_marked": today_total,
                "today_attendance_percentage": today_attendance_pct,
                # Tasks / exams
                "pending_tasks": pending_tasks,
                "upcoming_exams": upcoming_exams,
                # Admissions
                "new_students_this_month": new_students_this_month,
                # Fee
                "total_fee_expected": round(float(total_fee_expected), 2),
                "total_fee_collected": round(float(total_fee_collected), 2),
                "pending_fee_amount": round(float(pending_fee), 2),
                "collection_percentage": collection_percentage,
                # Academics
                "overall_pass_percentage": overall_pass_percentage,
            }

            serializer = DashboardSummarySerializer(data)

            return Response({"success": True, "data": serializer.data})

        except Exception as e:
            logger.error(f"Error in DashboardSummaryView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
            )


class StudentAdmissionTrendView(APIView):
    """
    GET /api/school-admin/stats/admission-trend/

    Get student admission trend over time
    Query Parameters:
    - period: 'monthly', 'yearly' (default: 'monthly')
    - year: int (optional)
    """

    permission_classes = [IsAuthenticated]

    def get(self, request):
        try:
            period = request.query_params.get("period", "monthly")
            year = request.query_params.get("year")

            queryset = Student.objects.filter(is_active=True)

            if period == "monthly":
                trend = (
                    queryset.annotate(month=TruncMonth("created_at"))
                    .values("month")
                    .annotate(count=Count("id"))
                    .order_by("month")
                )

                data = []
                for item in trend:
                    data.append(
                        {
                            "period": (
                                item["month"].strftime("%B %Y")
                                if item["month"]
                                else "Unknown"
                            ),
                            "count": item["count"],
                        }
                    )
            else:  # yearly
                if year:
                    queryset = queryset.filter(created_at__year=year)

                trend = (
                    queryset.annotate(year=TruncYear("created_at"))
                    .values("year")
                    .annotate(count=Count("id"))
                    .order_by("year")
                )

                data = []
                for item in trend:
                    data.append(
                        {
                            "period": (
                                item["year"].strftime("%Y")
                                if item["year"]
                                else "Unknown"
                            ),
                            "count": item["count"],
                        }
                    )

            serializer = StudentAdmissionTrendSerializer(data, many=True)

            return Response({"success": True, "data": serializer.data})

        except Exception as e:
            logger.error(f"Error in StudentAdmissionTrendView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
            )


class ClassPerformanceView(APIView):
    """
    GET /api/school-admin/stats/class-performance/

    Get performance metrics for classes
    Query Parameters:
    - academic_year_id: int (optional)
    - exam_id: int (optional)
    - limit: int (default: 10)
    """

    permission_classes = [IsAuthenticated]

    def get(self, request):
        try:
            academic_year_id = request.query_params.get("academic_year_id")
            exam_id = request.query_params.get("exam_id")
            limit = int(request.query_params.get("limit", 10))

            # Get academic year
            if academic_year_id:
                academic_year = AcademicYear.objects.get(id=academic_year_id)
            else:
                academic_year = AcademicYear.objects.filter(is_active=True).first()

            if not academic_year:
                return Response({"success": True, "data": []})

            # Get classes for this academic year
            classes = AcademicClass.objects.filter(
                academic_year=academic_year, is_active=True
            ).select_related("standard", "section")

            class_performance = []

            for ac in classes:
                # Get enrollments for this class
                enrollments = StudentEnrollment.objects.filter(
                    academic_class=ac, is_active=True
                ).values_list("id", flat=True)

                # Get exam results for this class
                if exam_id:
                    exam_results = ExamResult.objects.filter(
                        student_enrollment__id__in=enrollments, exam_id=exam_id
                    )
                else:
                    # Get latest exam results
                    exam_results = ExamResult.objects.filter(
                        student_enrollment__id__in=enrollments
                    )

                total_students = len(enrollments)
                total_passed = exam_results.filter(result_status="pass").count()
                total_failed = exam_results.filter(result_status="fail").count()

                avg_percentage = (
                    exam_results.aggregate(avg=Avg("percentage"))["avg"] or 0
                )

                pass_percentage = (
                    (total_passed / total_students * 100) if total_students > 0 else 0
                )

                class_performance.append(
                    {
                        "class_id": ac.id,
                        "class_name": str(ac),
                        "total_students": total_students,
                        "average_percentage": round(avg_percentage, 2),
                        "pass_count": total_passed,
                        "fail_count": total_failed,
                        "pass_percentage": round(pass_percentage, 2),
                        "rank": 0,  # Will be set after sorting
                    }
                )

            # Sort by average percentage and assign ranks
            class_performance.sort(key=lambda x: x["average_percentage"], reverse=True)
            for idx, cp in enumerate(class_performance, 1):
                cp["rank"] = idx

            # Limit results
            class_performance = class_performance[:limit]

            serializer = ClassPerformanceSerializer(class_performance, many=True)

            return Response({"success": True, "data": serializer.data})

        except Exception as e:
            logger.error(f"Error in ClassPerformanceView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
            )


class TopPerformingStudentsView(APIView):
    """
    GET /api/school-admin/stats/top-students/

    Get top performing students
    Query Parameters:
    - academic_year_id: int (optional)
    - exam_id: int (optional)
    - class_id: int (optional)
    - limit: int (default: 10)
    """

    permission_classes = [IsAuthenticated]

    def get(self, request):
        try:
            academic_year_id = request.query_params.get("academic_year_id")
            exam_id = request.query_params.get("exam_id")
            class_id = request.query_params.get("class_id")
            limit = int(request.query_params.get("limit", 10))

            # Base queryset for exam results
            exam_results = ExamResult.objects.filter(is_active=True)

            if exam_id:
                exam_results = exam_results.filter(exam_id=exam_id)
            elif academic_year_id:
                exam_results = exam_results.filter(
                    exam__academic_year_id=academic_year_id
                )
            else:
                # Get latest exam results
                latest_exam = (
                    Exam.objects.filter(is_active=True).order_by("-start_date").first()
                )
                if latest_exam:
                    exam_results = exam_results.filter(exam=latest_exam)

            if class_id:
                exam_results = exam_results.filter(
                    student_enrollment__academic_class_id=class_id
                )

            # Get top students
            top_students = exam_results.select_related(
                "student_enrollment__student", "student_enrollment__academic_class"
            ).order_by("-percentage")[:limit]

            data = []
            rank = 1
            for result in top_students:
                data.append(
                    {
                        "student_id": result.student_enrollment.student.id,
                        "student_name": result.student_enrollment.student.full_name,
                        "roll_number": result.student_enrollment.roll_number,
                        "class_name": str(result.student_enrollment.academic_class),
                        "total_marks": (
                            float(result.total_marks) if result.total_marks else 0
                        ),
                        "percentage": (
                            float(result.percentage) if result.percentage else 0
                        ),
                        "rank": rank,
                    }
                )
                rank += 1

            serializer = TopPerformingStudentSerializer(data, many=True)

            return Response({"success": True, "data": serializer.data})

        except Exception as e:
            logger.error(f"Error in TopPerformingStudentsView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
            )


class SubjectPerformanceView(APIView):
    """
    GET /api/school-admin/stats/subject-performance/

    Get subject wise performance
    Query Parameters:
    - exam_id: int (required)
    - class_id: int (optional)
    """

    permission_classes = [IsAuthenticated]

    def get(self, request):
        try:
            exam_id = request.query_params.get("exam_id")
            class_id = request.query_params.get("class_id")

            if not exam_id:
                return Response(
                    {"success": False, "message": "exam_id is required"},
                    status=status.HTTP_400_BAD_REQUEST,
                )

            # Get exam subjects
            exam_subjects = ExamSubject.objects.filter(
                exam_id=exam_id, is_active=True
            ).select_related("subject", "exam__academic_class")

            if class_id:
                exam_subjects = exam_subjects.filter(exam__academic_class_id=class_id)

            subject_performance = []

            for es in exam_subjects:
                # Get marks for this subject
                marks = StudentMarks.objects.filter(
                    exam_subject=es, is_absent=False, obtained_marks__isnull=False
                )

                marks_values = [float(m.obtained_marks) for m in marks]

                if marks_values:
                    avg_marks = sum(marks_values) / len(marks_values)
                    highest = max(marks_values)
                    lowest = min(marks_values)

                    # Calculate pass percentage
                    passing_marks = es.passing_marks
                    passed = len([m for m in marks if m.is_passed])
                    pass_percentage = (
                        (passed / len(marks) * 100) if len(marks) > 0 else 0
                    )
                else:
                    avg_marks = 0
                    highest = 0
                    lowest = 0
                    pass_percentage = 0

                subject_performance.append(
                    {
                        "subject_id": es.subject.id,
                        "subject_name": es.subject.name,
                        "subject_code": es.subject.code,
                        "class_name": str(es.exam.academic_class),
                        "average_marks": round(avg_marks, 2),
                        "highest_marks": round(highest, 2),
                        "lowest_marks": round(lowest, 2),
                        "pass_percentage": round(pass_percentage, 2),
                    }
                )

            # Sort by average marks
            subject_performance.sort(key=lambda x: x["average_marks"], reverse=True)

            serializer = SubjectPerformanceSerializer(subject_performance, many=True)

            return Response({"success": True, "data": serializer.data})

        except Exception as e:
            logger.error(f"Error in SubjectPerformanceView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
            )


class TeacherPerformanceView(APIView):
    """
    GET /api/school-admin/stats/teacher-performance/

    Get teacher performance metrics based on student marks
    Query Parameters:
    - exam_id: int (required)
    - subject_id: int (optional)
    """

    permission_classes = [IsAuthenticated]

    def get(self, request):
        try:
            exam_id = request.query_params.get("exam_id")
            subject_id = request.query_params.get("subject_id")

            if not exam_id:
                return Response(
                    {"success": False, "message": "exam_id is required"},
                    status=status.HTTP_400_BAD_REQUEST,
                )

            # Get subject teachers for this exam
            exam = Exam.objects.get(id=exam_id)
            academic_class = exam.academic_class

            # Get subject teachers for this class
            subject_teachers = SubjectTeacher.objects.filter(
                academic_class=academic_class, is_active=True
            ).select_related("teacher", "subject")

            if subject_id:
                subject_teachers = subject_teachers.filter(subject_id=subject_id)

            teacher_performance = []

            for st in subject_teachers:
                # Get exam subject
                exam_subject = ExamSubject.objects.filter(
                    exam=exam, subject=st.subject, is_active=True
                ).first()

                if not exam_subject:
                    continue

                # Get marks for this subject
                marks = StudentMarks.objects.filter(
                    exam_subject=exam_subject,
                    is_absent=False,
                    obtained_marks__isnull=False,
                )

                marks_values = [float(m.obtained_marks) for m in marks]

                if marks_values:
                    avg_marks = sum(marks_values) / len(marks_values)
                    passed = len([m for m in marks if m.is_passed])
                    pass_percentage = (
                        (passed / len(marks) * 100) if len(marks) > 0 else 0
                    )
                else:
                    avg_marks = 0
                    pass_percentage = 0

                teacher_performance.append(
                    {
                        "teacher_id": st.teacher.id,
                        "teacher_name": st.teacher.full_name,
                        "employee_id": st.teacher.employee_id or "N/A",
                        "subject_name": st.subject.name,
                        "class_name": str(academic_class),
                        "students_count": marks.count(),
                        "average_marks": round(avg_marks, 2),
                        "pass_percentage": round(pass_percentage, 2),
                    }
                )

            # Sort by average marks
            teacher_performance.sort(key=lambda x: x["average_marks"], reverse=True)

            serializer = TeacherPerformanceSerializer(teacher_performance, many=True)

            return Response({"success": True, "data": serializer.data})

        except Exception as e:
            logger.error(f"Error in TeacherPerformanceView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
            )


class FeeCollectionAnalyticsView(APIView):
    """
    GET /api/school-admin/stats/fee-collection/

    Get fee collection analytics
    Query Parameters:
    - period: 'monthly', 'yearly' (default: 'monthly')
    - year: int (optional)
    """

    permission_classes = [IsAuthenticated]

    def get(self, request):
        try:
            period = request.query_params.get("period", "monthly")
            year = int(request.query_params.get("year", timezone.now().year))

            payments = FeePayment.objects.filter(
                status="completed", payment_date__year=year
            )

            if period == "monthly":
                # Group by month
                fee_data = []
                for month in range(1, 13):
                    month_payments = payments.filter(payment_date__month=month)

                    total_collected = month_payments.aggregate(
                        total=Sum("amount_paid")
                    )["total"] or Decimal("0.00")

                    # Expected fee for this month (from assignments)
                    expected_payments = StudentFeeAssignment.objects.filter(
                        is_active=True,
                        class_fee_structure__due_date__month=month,
                        class_fee_structure__due_date__year=year,
                    ).aggregate(total=Sum("class_fee_structure__amount"))[
                        "total"
                    ] or Decimal(
                        "0.00"
                    )

                    pending = expected_payments - total_collected
                    collection_percentage = (
                        (total_collected / expected_payments * 100)
                        if expected_payments > 0
                        else 0
                    )

                    fee_data.append(
                        {
                            "period": datetime(year, month, 1).strftime("%B %Y"),
                            "total_collected": round(total_collected, 2),
                            "total_expected": round(expected_payments, 2),
                            "pending_amount": round(pending, 2),
                            "collection_percentage": round(collection_percentage, 2),
                        }
                    )
            else:  # yearly
                fee_data = []
                years = payments.dates("payment_date", "year", order="ASC")

                for yr in years:
                    yr_payments = payments.filter(payment_date__year=yr.year)
                    total_collected = yr_payments.aggregate(total=Sum("amount_paid"))[
                        "total"
                    ] or Decimal("0.00")

                    expected_payments = StudentFeeAssignment.objects.filter(
                        is_active=True, class_fee_structure__due_date__year=yr.year
                    ).aggregate(total=Sum("class_fee_structure__amount"))[
                        "total"
                    ] or Decimal(
                        "0.00"
                    )

                    pending = expected_payments - total_collected
                    collection_percentage = (
                        (total_collected / expected_payments * 100)
                        if expected_payments > 0
                        else 0
                    )

                    fee_data.append(
                        {
                            "period": str(yr.year),
                            "total_collected": round(total_collected, 2),
                            "total_expected": round(expected_payments, 2),
                            "pending_amount": round(pending, 2),
                            "collection_percentage": round(collection_percentage, 2),
                        }
                    )

            serializer = FeeCollectionSerializer(fee_data, many=True)

            return Response({"success": True, "data": serializer.data})

        except Exception as e:
            logger.error(f"Error in FeeCollectionAnalyticsView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
            )


class AttendanceAnalyticsView(APIView):
    """
    GET /api/school-admin/stats/attendance/

    Get attendance analytics
    Query Parameters:
    - period: 'daily', 'weekly', 'monthly' (default: 'monthly')
    - start_date: date (optional)
    - end_date: date (optional)
    - class_id: int (optional)
    """

    permission_classes = [IsAuthenticated]

    def get(self, request):
        try:
            period = request.query_params.get("period", "monthly")
            start_date = request.query_params.get("start_date")
            end_date = request.query_params.get("end_date")
            class_id = request.query_params.get("class_id")

            # Get attendance sessions
            sessions = AttendanceSession.objects.filter(
                session_type="FULL_DAY", is_active=True
            ).select_related("academic_class")

            if class_id:
                sessions = sessions.filter(academic_class_id=class_id)

            if start_date:
                sessions = sessions.filter(date__gte=start_date)
            if end_date:
                sessions = sessions.filter(date__lte=end_date)

            attendance_data = []

            if period == "daily":
                # Group by day
                for session in sessions.order_by("date"):
                    # FIXED: Use 'student_attendances' instead of 'attendance_records'
                    attendances = session.student_attendances.filter(is_active=True)

                    total = attendances.count()
                    present = attendances.filter(status="PRESENT").count()
                    absent = attendances.filter(status="ABSENT").count()
                    late = attendances.filter(status="LATE").count()
                    leave = attendances.filter(status="LEAVE").count()
                    half = attendances.filter(status="HALF_DAY").count()

                    attendance_percentage = (
                        (present + late + (half * 0.5)) / total * 100
                        if total > 0
                        else 0
                    )

                    attendance_data.append(
                        {
                            "period": session.date.strftime("%d %b %Y"),
                            "total_students": total,
                            "present_count": present,
                            "absent_count": absent,
                            "late_count": late,
                            "leave_count": leave,
                            "attendance_percentage": round(attendance_percentage, 2),
                        }
                    )

            elif period == "weekly":
                # Group by week
                from django.db.models.functions import ExtractWeek

                weekly_data = (
                    sessions.annotate(
                        week=ExtractWeek("date"), year=ExtractYear("date")
                    )
                    .values("year", "week")
                    .annotate(
                        total_sessions=Count("id"),
                        # FIXED: Use 'student_attendances' instead of 'attendance_records'
                        total_attendance=Count(
                            "student_attendances",
                            filter=Q(student_attendances__is_active=True),
                        ),
                        present=Count(
                            "student_attendances",
                            filter=Q(
                                student_attendances__status="PRESENT",
                                student_attendances__is_active=True,
                            ),
                        ),
                        late=Count(
                            "student_attendances",
                            filter=Q(
                                student_attendances__status="LATE",
                                student_attendances__is_active=True,
                            ),
                        ),
                        leave=Count(
                            "student_attendances",
                            filter=Q(
                                student_attendances__status="LEAVE",
                                student_attendances__is_active=True,
                            ),
                        ),
                        half=Count(
                            "student_attendances",
                            filter=Q(
                                student_attendances__status="HALF_DAY",
                                student_attendances__is_active=True,
                            ),
                        ),
                    )
                    .order_by("year", "week")
                )

                for item in weekly_data:
                    total = item["total_attendance"]
                    effective_present = (
                        item["present"] + item["late"] + (item["half"] * 0.5)
                    )
                    attendance_percentage = (
                        (effective_present / total * 100) if total > 0 else 0
                    )

                    attendance_data.append(
                        {
                            "period": f"Week {item['week']}, {item['year']}",
                            "total_students": total,
                            "present_count": item["present"],
                            "absent_count": total
                            - item["present"]
                            - item["late"]
                            - item["leave"],
                            "late_count": item["late"],
                            "leave_count": item["leave"],
                            "attendance_percentage": round(attendance_percentage, 2),
                        }
                    )

            else:  # monthly
                from django.db.models.functions import TruncMonth, ExtractYear

                monthly_data = (
                    sessions.annotate(month=TruncMonth("date"))
                    .values("month")
                    .annotate(
                        total_sessions=Count("id"),
                        # FIXED: Use 'student_attendances' instead of 'attendance_records'
                        total_attendance=Count(
                            "student_attendances",
                            filter=Q(student_attendances__is_active=True),
                        ),
                        present=Count(
                            "student_attendances",
                            filter=Q(
                                student_attendances__status="PRESENT",
                                student_attendances__is_active=True,
                            ),
                        ),
                        late=Count(
                            "student_attendances",
                            filter=Q(
                                student_attendances__status="LATE",
                                student_attendances__is_active=True,
                            ),
                        ),
                        leave=Count(
                            "student_attendances",
                            filter=Q(
                                student_attendances__status="LEAVE",
                                student_attendances__is_active=True,
                            ),
                        ),
                        half=Count(
                            "student_attendances",
                            filter=Q(
                                student_attendances__status="HALF_DAY",
                                student_attendances__is_active=True,
                            ),
                        ),
                    )
                    .order_by("month")
                )

                for item in monthly_data:
                    total = item["total_attendance"]
                    effective_present = (
                        item["present"] + item["late"] + (item["half"] * 0.5)
                    )
                    attendance_percentage = (
                        (effective_present / total * 100) if total > 0 else 0
                    )

                    attendance_data.append(
                        {
                            "period": (
                                item["month"].strftime("%B %Y")
                                if item["month"]
                                else "Unknown"
                            ),
                            "total_students": total,
                            "present_count": item["present"],
                            "absent_count": total
                            - item["present"]
                            - item["late"]
                            - item["leave"],
                            "late_count": item["late"],
                            "leave_count": item["leave"],
                            "attendance_percentage": round(attendance_percentage, 2),
                        }
                    )

            serializer = AttendanceAnalyticsSerializer(attendance_data, many=True)

            return Response({"success": True, "data": serializer.data})

        except Exception as e:
            logger.error(f"Error in AttendanceAnalyticsView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
            )


class GenderDistributionView(APIView):
    """
    GET /api/school-admin/stats/gender-distribution/

    Get gender distribution across school
    Query Parameters:
    - standard_id: int (optional)
    - class_id: int (optional)
    """

    permission_classes = [IsAuthenticated]

    def get(self, request):
        try:
            standard_id = request.query_params.get("standard_id")
            class_id = request.query_params.get("class_id")

            students = Student.objects.filter(is_active=True)

            if standard_id:
                students = students.filter(
                    enrollments__academic_class__standard_id=standard_id,
                    enrollments__is_active=True,
                ).distinct()

            if class_id:
                students = students.filter(
                    enrollments__academic_class_id=class_id, enrollments__is_active=True
                ).distinct()

            male_count = students.filter(gender="MALE").count()
            female_count = students.filter(gender="FEMALE").count()
            other_count = students.filter(
                gender__in=["OTHER", "PREFER_NOT_TO_SAY"]
            ).count()

            total = male_count + female_count + other_count

            male_percentage = (male_count / total * 100) if total > 0 else 0
            female_percentage = (female_count / total * 100) if total > 0 else 0
            other_percentage = (other_count / total * 100) if total > 0 else 0

            data = {
                "male_count": male_count,
                "female_count": female_count,
                "other_count": other_count,
                "male_percentage": round(male_percentage, 2),
                "female_percentage": round(female_percentage, 2),
                "other_percentage": round(other_percentage, 2),
            }

            serializer = GenderDistributionSerializer(data)

            return Response({"success": True, "data": serializer.data})

        except Exception as e:
            logger.error(f"Error in GenderDistributionView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
            )


class StandardWiseDistributionView(APIView):
    """
    GET /api/school-admin/stats/standard-distribution/

    Get standard wise student distribution
    """

    permission_classes = [IsAuthenticated]

    def get(self, request):
        try:
            # Get all standards
            standards = Standard.objects.filter(is_active=True).order_by("order")

            distribution = []

            for standard in standards:
                # Get classes for this standard
                classes = AcademicClass.objects.filter(
                    standard=standard, is_active=True
                )

                # Get enrollments for these classes
                enrollments = StudentEnrollment.objects.filter(
                    academic_class__in=classes, is_active=True
                ).select_related("student")

                total_students = enrollments.count()
                boys_count = enrollments.filter(student__gender="MALE").count()
                girls_count = enrollments.filter(student__gender="FEMALE").count()
                sections_count = classes.count()

                distribution.append(
                    {
                        "standard_id": standard.id,
                        "standard_name": standard.name,
                        "total_students": total_students,
                        "sections_count": sections_count,
                        "boys_count": boys_count,
                        "girls_count": girls_count,
                    }
                )

            serializer = StandardWiseDistributionSerializer(distribution, many=True)

            return Response({"success": True, "data": serializer.data})

        except Exception as e:
            logger.error(f"Error in StandardWiseDistributionView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
            )


class ComprehensiveReportView(APIView):
    """
    GET /api/school-admin/stats/comprehensive-report/

    Get comprehensive report with multiple metrics
    Query Parameters:
    - academic_year_id: int (optional)
    - start_date: date (optional)
    - end_date: date (optional)
    """

    permission_classes = [IsAuthenticated]

    def get(self, request):
        try:
            start_date = request.query_params.get("start_date")
            end_date = request.query_params.get("end_date")
            academic_year_id = request.query_params.get("academic_year_id")

            filter_serializer = ReportFilterSerializer(data=request.query_params)
            filter_serializer.is_valid()
            filters = filter_serializer.validated_data

            # Get academic year
            if academic_year_id:
                academic_year = AcademicYear.objects.get(id=academic_year_id)
            else:
                academic_year = AcademicYear.objects.filter(is_active=True).first()

            # Student Statistics
            total_students = Student.objects.filter(is_active=True).count()
            total_enrollments = StudentEnrollment.objects.filter(is_active=True).count()
            if academic_year:
                total_enrollments = StudentEnrollment.objects.filter(
                    academic_class__academic_year=academic_year, is_active=True
                ).count()

            # Teacher Statistics
            total_teachers = Teacher.objects.filter(is_active=True).count()

            # Academic Performance
            latest_exam = (
                Exam.objects.filter(is_active=True).order_by("-start_date").first()
            )
            overall_pass_percentage = 0
            if latest_exam:
                exam_results = ExamResult.objects.filter(exam=latest_exam)
                total_results = exam_results.count()
                passed = exam_results.filter(result_status="pass").count()
                overall_pass_percentage = (
                    (passed / total_results * 100) if total_results > 0 else 0
                )

            # Fee Statistics
            total_fee_collected = FeePayment.objects.filter(
                status="completed"
            ).aggregate(total=Sum("amount_paid"))["total"] or Decimal("0.00")

            total_fee_expected = StudentFeeAssignment.objects.filter(
                is_active=True
            ).aggregate(total=Sum("class_fee_structure__amount"))["total"] or Decimal(
                "0.00"
            )

            # Attendance Statistics (last 30 days)
            last_30_days = timezone.now().date() - timedelta(days=30)
            attendance_sessions = AttendanceSession.objects.filter(
                date__gte=last_30_days, session_type="FULL_DAY", is_active=True
            )

            total_attendance_records = 0
            total_present = 0
            total_late = 0

            for session in attendance_sessions:
                records = StudentAttendance.objects.filter(
                    session=session, is_active=True
                )
                total_attendance_records += records.count()
                total_present += records.filter(status="PRESENT").count()
                total_late += records.filter(status="LATE").count()

            avg_attendance = (
                (total_present + total_late) / total_attendance_records * 100
                if total_attendance_records > 0
                else 0
            )

            # Top performing class
            top_class = None
            if latest_exam:
                class_performance_data = []
                classes = AcademicClass.objects.filter(is_active=True)
                if academic_year:
                    classes = classes.filter(academic_year=academic_year)

                for ac in classes[:5]:
                    enrollments = StudentEnrollment.objects.filter(
                        academic_class=ac, is_active=True
                    ).values_list("id", flat=True)

                    exam_results = ExamResult.objects.filter(
                        student_enrollment__id__in=enrollments, exam=latest_exam
                    )

                    avg_percentage = (
                        exam_results.aggregate(avg=Avg("percentage"))["avg"] or 0
                    )

                    class_performance_data.append(
                        {
                            "class_name": str(ac),
                            "average_percentage": round(avg_percentage, 2),
                        }
                    )

                if class_performance_data:
                    class_performance_data.sort(
                        key=lambda x: x["average_percentage"], reverse=True
                    )
                    top_class = (
                        class_performance_data[0] if class_performance_data else None
                    )

            report = {
                "report_generated_at": timezone.now(),
                "filters_applied": {
                    "academic_year_id": academic_year_id,
                    "start_date": start_date,
                    "end_date": end_date,
                },
                "summary": {
                    "total_students": total_students,
                    "total_enrollments": total_enrollments,
                    "total_teachers": total_teachers,
                    "overall_pass_percentage": round(overall_pass_percentage, 2),
                    "total_fee_collected": round(total_fee_collected, 2),
                    "total_fee_expected": round(total_fee_expected, 2),
                    "average_attendance_last_30_days": round(avg_attendance, 2),
                    "top_performing_class": top_class,
                },
            }

            return Response({"success": True, "data": report})

        except Exception as e:
            logger.error(f"Error in ComprehensiveReportView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
            )


# stats/views.py - Fixed RecentActivitiesView


class RecentActivitiesView(APIView):
    """Get recent activities for dashboard"""

    permission_classes = [IsAuthenticated]

    def get(self, request):
        try:
            from fee.models import FeePayment
            from attendance.models import AttendanceLeave
            from academics.models import StudentEnrollment
            from django.utils import timezone
            from datetime import datetime

            # Get recent fee payments
            recent_payments = FeePayment.objects.filter(status="completed").order_by(
                "-payment_date"
            )[:5]

            # Get recent enrollments
            recent_enrollments = StudentEnrollment.objects.filter(
                is_active=True
            ).order_by("-created_at")[:5]

            # Get recent leave requests
            recent_leaves = AttendanceLeave.objects.filter(is_active=True).order_by(
                "-created_at"
            )[:5]

            activities = []
            now = timezone.now()

            # Process fee payments (date fields)
            for payment in recent_payments:
                # Convert date to datetime for consistent comparison
                payment_datetime = datetime.combine(
                    payment.payment_date, datetime.min.time()
                )
                payment_datetime = timezone.make_aware(payment_datetime)

                diff = now - payment_datetime

                if diff.days > 0:
                    time_ago = f"{diff.days} day{'s' if diff.days > 1 else ''} ago"
                elif diff.seconds > 3600:
                    hours = diff.seconds // 3600
                    time_ago = f"{hours} hour{'s' if hours > 1 else ''} ago"
                elif diff.seconds > 60:
                    minutes = diff.seconds // 60
                    time_ago = f"{minutes} minute{'s' if minutes > 1 else ''} ago"
                else:
                    time_ago = "Just now"

                activities.append(
                    {
                        "id": payment.id,
                        "title": "Fee Payment Received",
                        "description": f"₹{payment.amount_paid} from {payment.student.full_name}",
                        "timeAgo": time_ago,
                        "timestamp": payment_datetime.timestamp(),  # For sorting
                        "status": "PAID",
                        "icon": "AttachMoneyIcon",
                    }
                )

            # Process enrollments (datetime fields)
            for enrollment in recent_enrollments:
                dt = enrollment.created_at
                if timezone.is_naive(dt):
                    dt = timezone.make_aware(dt)

                diff = now - dt

                if diff.days > 0:
                    time_ago = f"{diff.days} day{'s' if diff.days > 1 else ''} ago"
                elif diff.seconds > 3600:
                    hours = diff.seconds // 3600
                    time_ago = f"{hours} hour{'s' if hours > 1 else ''} ago"
                elif diff.seconds > 60:
                    minutes = diff.seconds // 60
                    time_ago = f"{minutes} minute{'s' if minutes > 1 else ''} ago"
                else:
                    time_ago = "Just now"

                activities.append(
                    {
                        "id": enrollment.id,
                        "title": "New Student Admission",
                        "description": f"{enrollment.student.full_name} joined {enrollment.academic_class}",
                        "timeAgo": time_ago,
                        "timestamp": dt.timestamp(),
                        "status": "NEW",
                        "icon": "PersonAddIcon",
                    }
                )

            # Process leave requests (datetime fields)
            for leave in recent_leaves:
                dt = leave.created_at
                if timezone.is_naive(dt):
                    dt = timezone.make_aware(dt)

                diff = now - dt

                if diff.days > 0:
                    time_ago = f"{diff.days} day{'s' if diff.days > 1 else ''} ago"
                elif diff.seconds > 3600:
                    hours = diff.seconds // 3600
                    time_ago = f"{hours} hour{'s' if hours > 1 else ''} ago"
                elif diff.seconds > 60:
                    minutes = diff.seconds // 60
                    time_ago = f"{minutes} minute{'s' if minutes > 1 else ''} ago"
                else:
                    time_ago = "Just now"

                activities.append(
                    {
                        "id": leave.id,
                        "title": "Leave Request",
                        "description": f"{leave.student.full_name} - {leave.get_leave_type_display()}",
                        "timeAgo": time_ago,
                        "timestamp": dt.timestamp(),
                        "status": leave.status,
                        "icon": "AssignmentIcon",
                    }
                )

            # Sort by timestamp - DESCENDING (most recent first)
            activities.sort(key=lambda x: x["timestamp"], reverse=True)

            # Remove timestamp from response (clean output)
            for activity in activities:
                del activity["timestamp"]

            # Return top 10 most recent activities
            serializer = RecentActivitySerializer(activities[:10], many=True)

            return Response({"success": True, "data": serializer.data})

        except Exception as e:
            logger.error(f"Error in RecentActivitiesView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
            )
