from rest_framework import viewsets, filters, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from django.shortcuts import get_object_or_404
from django.db import models
from django.db.models import Sum, Count, Q
from django.db import IntegrityError
from decimal import Decimal, InvalidOperation
from .models import (
    TransportType,
    TransportVehicle,
    Route,
    Stop,
    StudentTransport,
    TeacherTransport,
)
from .serializers import (
    TransportTypeSerializer,
    TransportVehicleSerializer,
    RouteSerializer,
    StopSerializer,
    StudentTransportSerializer,
    StudentTransportCreateUpdateSerializer,
    TeacherTransportSerializer,
    TeacherTransportCreateUpdateSerializer,
    TransportDashboardSerializer,
    StudentEnrollmentDetailSerializer,
)
from academics.models import StudentEnrollment, AcademicYear, AcademicClass


class TransportTypeViewSet(viewsets.ModelViewSet):
    """
    ViewSet for Transport Type CRUD operations
    """

    queryset = TransportType.objects.all()
    serializer_class = TransportTypeSerializer
    permission_classes = [IsAuthenticated, IsAdminUser]
    filterset_fields = ["name"]
    search_fields = ["name"]
    ordering_fields = ["name", "id"]
    ordering = ["name"]

    def get_queryset(self):
        queryset = super().get_queryset()

        # Filter by search query
        search = self.request.query_params.get("search", "")
        if search:
            queryset = queryset.filter(name__icontains=search)

        return queryset


class TransportVehicleViewSet(viewsets.ModelViewSet):
    """
    ViewSet for Transport Vehicle CRUD operations
    """

    queryset = TransportVehicle.objects.all()
    serializer_class = TransportVehicleSerializer
    permission_classes = [IsAuthenticated, IsAdminUser]
    filterset_fields = ["transport_type", "bus_number", "vehicle_number"]
    search_fields = ["bus_number", "vehicle_number", "driver_name", "driver_phone"]
    ordering_fields = ["bus_number", "capacity"]
    ordering = ["bus_number"]

    def get_queryset(self):
        queryset = super().get_queryset()

        # Filter by transport type
        transport_type = self.request.query_params.get("transport_type")
        if transport_type:
            queryset = queryset.filter(transport_type_id=transport_type)

        # Filter by search query
        search = self.request.query_params.get("search", "")
        if search:
            queryset = queryset.filter(
                Q(bus_number__icontains=search)
                | Q(vehicle_number__icontains=search)
                | Q(driver_name__icontains=search)
            )

        # Filter vehicles with available seats
        has_available_seats = self.request.query_params.get("has_available_seats")
        if has_available_seats and has_available_seats.lower() == "true":
            vehicle_ids = []
            for vehicle in queryset:
                current_occupancy = (
                    StudentTransport.objects.filter(
                        vehicle=vehicle, is_active=True
                    ).count()
                    + TeacherTransport.objects.filter(
                        vehicle=vehicle, is_active=True
                    ).count()
                )
                if current_occupancy < vehicle.capacity:
                    vehicle_ids.append(vehicle.id)
            queryset = queryset.filter(id__in=vehicle_ids)

        return queryset

    @action(detail=True, methods=["get"])
    def current_occupancy(self, request, pk=None):
        """
        Get current occupancy of a vehicle
        """
        vehicle = self.get_object()
        student_count = StudentTransport.objects.filter(
            vehicle=vehicle, is_active=True
        ).count()
        teacher_count = TeacherTransport.objects.filter(
            vehicle=vehicle, is_active=True
        ).count()

        return Response(
            {
                "vehicle_id": vehicle.id,
                "bus_number": vehicle.bus_number,
                "capacity": vehicle.capacity,
                "students_assigned": student_count,
                "teachers_assigned": teacher_count,
                "total_assigned": student_count + teacher_count,
                "available_seats": vehicle.capacity - (student_count + teacher_count),
                "utilization_percentage": (
                    round(((student_count + teacher_count) / vehicle.capacity * 100), 2)
                    if vehicle.capacity > 0
                    else 0
                ),
            }
        )

    @action(detail=True, methods=["get"])
    def assigned_students(self, request, pk=None):
        """
        Get all students assigned to this vehicle
        """
        vehicle = self.get_object()
        students = StudentTransport.objects.filter(
            vehicle=vehicle, is_active=True
        ).select_related("student__user", "route", "stop")

        return Response(
            {
                "vehicle": {"id": vehicle.id, "bus_number": vehicle.bus_number},
                "total_students": students.count(),
                "students": StudentTransportSerializer(students, many=True).data,
            }
        )

    @action(detail=True, methods=["post"])
    def upload_document(self, request, pk=None):
        """
        Upload a specific document for the vehicle
        """
        vehicle = self.get_object()
        document_type = request.data.get("document_type")
        file = request.FILES.get("file")

        if not document_type or not file:
            return Response(
                {"error": "document_type and file are required"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        document_fields = {
            "vehicle_photo": "vehicle_photo",
            "registration_certificate": "registration_certificate",
            "insurance_document": "insurance_document",
            "pollution_certificate": "pollution_certificate",
            "permit_document": "permit_document",
            "fitness_certificate": "fitness_certificate",
        }

        if document_type not in document_fields:
            return Response(
                {
                    "error": f"Invalid document_type. Choose from: {list(document_fields.keys())}"
                },
                status=status.HTTP_400_BAD_REQUEST,
            )

        setattr(vehicle, document_fields[document_type], file)
        vehicle.save()

        return Response(
            {
                "message": f"{document_type} uploaded successfully",
                "file_url": (
                    getattr(vehicle, document_fields[document_type]).url
                    if getattr(vehicle, document_fields[document_type])
                    else None
                ),
            },
            status=status.HTTP_200_OK,
        )

    @action(detail=True, methods=["delete"])
    def delete_document(self, request, pk=None):
        """
        Delete a specific document from the vehicle
        """
        vehicle = self.get_object()
        document_type = request.data.get("document_type")

        document_fields = {
            "vehicle_photo": "vehicle_photo",
            "registration_certificate": "registration_certificate",
            "insurance_document": "insurance_document",
            "pollution_certificate": "pollution_certificate",
            "permit_document": "permit_document",
            "fitness_certificate": "fitness_certificate",
        }

        if document_type not in document_fields:
            return Response(
                {
                    "error": f"Invalid document_type. Choose from: {list(document_fields.keys())}"
                },
                status=status.HTTP_400_BAD_REQUEST,
            )

        # Delete the file from storage
        file_field = getattr(vehicle, document_fields[document_type])
        if file_field:
            file_field.delete(save=False)
            setattr(vehicle, document_fields[document_type], None)
            vehicle.save()
            return Response(
                {"message": f"{document_type} deleted successfully"},
                status=status.HTTP_200_OK,
            )

        return Response(
            {"error": f"No {document_type} found to delete"},
            status=status.HTTP_404_NOT_FOUND,
        )


class RouteViewSet(viewsets.ModelViewSet):
    """
    ViewSet for Route CRUD operations
    """

    queryset = Route.objects.all()
    serializer_class = RouteSerializer
    permission_classes = [IsAuthenticated, IsAdminUser]
    filterset_fields = ["vehicle", "route_name", "start_location", "destination"]
    search_fields = ["route_name", "start_location", "destination"]
    ordering_fields = ["route_name", "distance_km", "created_at"]
    ordering = ["route_name"]

    def get_queryset(self):
        queryset = super().get_queryset()

        # Filter by vehicle
        vehicle = self.request.query_params.get("vehicle")
        if vehicle:
            queryset = queryset.filter(vehicle_id=vehicle)

        # Filter by search query
        search = self.request.query_params.get("search", "")
        if search:
            queryset = queryset.filter(
                Q(route_name__icontains=search)
                | Q(start_location__icontains=search)
                | Q(destination__icontains=search)
            )

        return queryset

    @action(detail=True, methods=["get"])
    def stops_in_order(self, request, pk=None):
        """
        Get all stops for this route in order
        """
        route = self.get_object()
        stops = route.stops.all().order_by("stop_order")
        serializer = StopSerializer(stops, many=True)
        return Response(
            {
                "route": RouteSerializer(route).data,
                "stops": serializer.data,
                "total_stops": stops.count(),
            }
        )

    @action(detail=True, methods=["get"])
    def assigned_students(self, request, pk=None):
        """
        Get all students assigned to this route
        """
        route = self.get_object()
        students = StudentTransport.objects.filter(
            route=route, is_active=True
        ).select_related("student__user", "vehicle", "stop")

        return Response(
            {
                "route": {"id": route.id, "route_name": route.route_name},
                "total_students": students.count(),
                "students": StudentTransportSerializer(students, many=True).data,
            }
        )


class StopViewSet(viewsets.ModelViewSet):
    """
    ViewSet for Stop CRUD operations
    """

    queryset = Stop.objects.all()
    serializer_class = StopSerializer
    permission_classes = [IsAuthenticated, IsAdminUser]
    filterset_fields = ["route", "stop_name", "stop_order"]
    search_fields = ["stop_name"]
    ordering_fields = ["stop_order", "arrival_time"]
    ordering = ["route", "stop_order"]

    def get_queryset(self):
        queryset = super().get_queryset()

        # Filter by route
        route = self.request.query_params.get("route")
        if route:
            queryset = queryset.filter(route_id=route)

        # Filter by search query
        search = self.request.query_params.get("search", "")
        if search:
            queryset = queryset.filter(stop_name__icontains=search)

        return queryset.order_by("route", "stop_order")

    def create(self, request, *args, **kwargs):
        """Override create to handle stop order validation"""
        route_id = request.data.get("route")
        stop_order = request.data.get("stop_order")

        if Stop.objects.filter(route_id=route_id, stop_order=stop_order).exists():
            return Response(
                {"error": f"Stop order {stop_order} already exists for this route"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        try:
            return super().create(request, *args, **kwargs)
        except IntegrityError as e:
            return Response(
                {"error": "A stop with this order already exists for this route"},
                status=status.HTTP_400_BAD_REQUEST,
            )

    def update(self, request, *args, **kwargs):
        """Override update to handle stop order validation"""
        try:
            return super().update(request, *args, **kwargs)
        except IntegrityError as e:
            return Response(
                {"error": "A stop with this order already exists for this route"},
                status=status.HTTP_400_BAD_REQUEST,
            )

    @action(detail=False, methods=["post"], url_path="bulk-update-fees")
    def bulk_update_fees(self, request):
        """
        Route-wise / stop-wise fee setting: save a fee_amount for many stops
        (typically every stop on one route) in a single request.
        Body: { "stops": [{"id": 1, "fee_amount": 500}, ...] }
        """
        stops_data = request.data.get("stops")
        if not isinstance(stops_data, list) or not stops_data:
            return Response(
                {"error": "stops must be a non-empty list of {id, fee_amount}"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        updated = []
        for entry in stops_data:
            stop_id = entry.get("id")
            fee_amount = entry.get("fee_amount")
            if stop_id is None or fee_amount is None:
                continue
            try:
                fee_amount = Decimal(str(fee_amount))
            except (InvalidOperation, ValueError):
                continue
            if fee_amount < 0:
                continue
            updated.append(Stop(id=stop_id, fee_amount=fee_amount))

        if not updated:
            return Response(
                {"error": "No valid stop entries provided"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        Stop.objects.bulk_update(updated, ["fee_amount"])

        stop_ids = [s.id for s in updated]
        refreshed = Stop.objects.filter(id__in=stop_ids)
        return Response(
            {
                "message": f"Updated fees for {len(updated)} stop(s)",
                "stops": StopSerializer(refreshed, many=True).data,
            },
            status=status.HTTP_200_OK,
        )


from rest_framework import viewsets, filters, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from django.shortcuts import get_object_or_404
from django.db import models
from django.db.models import Sum, Count, Q
from django.db import IntegrityError
from .models import (
    TransportType,
    TransportVehicle,
    Route,
    Stop,
    StudentTransport,
    TeacherTransport,
)
from .serializers import (
    TransportTypeSerializer,
    TransportVehicleSerializer,
    RouteSerializer,
    StopSerializer,
    StudentTransportSerializer,
    StudentTransportCreateUpdateSerializer,
    TeacherTransportSerializer,
    TeacherTransportCreateUpdateSerializer,
    TransportDashboardSerializer,
    StudentEnrollmentDetailSerializer,
)
from academics.models import StudentEnrollment, AcademicYear, AcademicClass


class StudentTransportViewSet(viewsets.ModelViewSet):
    """
    ViewSet for Student Transport CRUD operations
    """

    queryset = StudentTransport.objects.all()
    permission_classes = [IsAuthenticated, IsAdminUser]
    filterset_fields = ["student", "vehicle", "route", "stop", "is_active"]
    search_fields = [
        "student__first_name",
        "student__last_name",
        "student__admission_number",
        "enrollment__roll_number",
        "enrollment__academic_class__standard__name",
    ]
    ordering_fields = ["student__first_name", "fee_amount", "due_date"]
    ordering = ["student__first_name"]

    def get_serializer_class(self):
        """Return appropriate serializer class based on action"""
        if self.action in ["create", "update", "partial_update"]:
            return StudentTransportCreateUpdateSerializer
        return StudentTransportSerializer

    def get_queryset(self):
        queryset = super().get_queryset()

        # Filter by student
        student = self.request.query_params.get("student")
        if student:
            queryset = queryset.filter(student_id=student)

        # Filter by enrollment
        enrollment = self.request.query_params.get("enrollment")
        if enrollment:
            queryset = queryset.filter(enrollment_id=enrollment)

        # Filter by vehicle
        vehicle = self.request.query_params.get("vehicle")
        if vehicle:
            queryset = queryset.filter(vehicle_id=vehicle)

        # Filter by route
        route = self.request.query_params.get("route")
        if route:
            queryset = queryset.filter(route_id=route)

        # Filter by academic year — accepts either an AcademicYear id (preferred,
        # resolved via the enrollment's class) or the legacy denormalized
        # "academic_year" text field (e.g. "2024-2025") for older records.
        academic_year = self.request.query_params.get("academic_year")
        if academic_year:
            if academic_year.isdigit():
                queryset = queryset.filter(
                    enrollment__academic_class__academic_year_id=academic_year
                )
            else:
                queryset = queryset.filter(academic_year=academic_year)

        # Filter by class
        class_id = self.request.query_params.get("class_id")
        if class_id:
            queryset = queryset.filter(enrollment__academic_class_id=class_id)

        # Filter by active status
        is_active = self.request.query_params.get("is_active")
        if is_active is not None:
            queryset = queryset.filter(is_active=is_active.lower() == "true")

        # Optimize queries with select_related
        return queryset.select_related(
            "student",
            "enrollment",
            "enrollment__academic_class",
            "enrollment__academic_class__standard",
            "enrollment__academic_class__section",
            "vehicle",
            "route",
            "stop",
        )

    @action(detail=False, methods=["post"])
    def bulk_create(self, request):
        """
        Bulk create student transport assignments
        """
        assignments_data = request.data.get("assignments", [])
        created_assignments = []
        errors = []

        for idx, assignment in enumerate(assignments_data):
            serializer = self.get_serializer(data=assignment)
            if serializer.is_valid():
                serializer.save()
                created_assignments.append(serializer.data)
            else:
                errors.append({"index": idx, "errors": serializer.errors})

        return Response(
            {
                "created": created_assignments,
                "errors": errors,
                "total_processed": len(assignments_data),
                "total_created": len(created_assignments),
            },
            status=status.HTTP_207_MULTI_STATUS if errors else status.HTTP_201_CREATED,
        )

    @action(detail=True, methods=["post"])
    def toggle_active(self, request, pk=None):
        """
        Toggle is_active status
        """
        transport = self.get_object()
        transport.is_active = not transport.is_active
        transport.save()
        serializer = self.get_serializer(transport)
        return Response(serializer.data)

    @action(detail=False, methods=["get"])
    def by_enrollment(self, request):
        """
        Get transport assignments by enrollment
        """
        enrollment_id = request.query_params.get("enrollment_id")
        if not enrollment_id:
            return Response(
                {"error": "enrollment_id parameter is required"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        queryset = self.get_queryset().filter(enrollment_id=enrollment_id)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    @action(detail=False, methods=["get"])
    def available_enrollments(self, request):
        """
        Get enrollments without active transport
        """
        academic_year_id = request.query_params.get("academic_year")
        class_id = request.query_params.get("class_id")

        queryset = StudentEnrollment.objects.filter(is_active=True)

        if academic_year_id:
            queryset = queryset.filter(
                academic_class__academic_year_id=academic_year_id
            )

        if class_id:
            queryset = queryset.filter(academic_class_id=class_id)

        # Exclude enrollments with active transport
        enrolled_transport_ids = StudentTransport.objects.filter(
            is_active=True
        ).values_list("enrollment_id", flat=True)

        available = queryset.exclude(id__in=enrolled_transport_ids)

        # Create a simple serializer for response
        available_data = []
        for enrollment in available:
            available_data.append(
                {
                    "id": enrollment.id,
                    "student_id": enrollment.student.id,
                    "student_name": f"{enrollment.student.first_name or ''} {enrollment.student.last_name or ''}".strip(),
                    "roll_number": enrollment.roll_number,
                    "class_name": (
                        enrollment.academic_class.standard.name
                        if enrollment.academic_class
                        else None
                    ),
                    "section_name": (
                        enrollment.academic_class.section.code
                        if enrollment.academic_class
                        else None
                    ),
                    "academic_year": (
                        str(enrollment.academic_class.academic_year)
                        if enrollment.academic_class
                        else None
                    ),
                }
            )

        return Response(available_data)


class TeacherTransportViewSet(viewsets.ModelViewSet):
    """
    ViewSet for Teacher Transport CRUD operations
    """

    queryset = TeacherTransport.objects.all()
    permission_classes = [IsAuthenticated, IsAdminUser]
    filterset_fields = ["teacher", "vehicle", "route", "stop", "is_active"]
    search_fields = [
        "teacher__first_name",
        "teacher__last_name",
        "teacher__employee_id",
        "teacher__email",
        "teacher__phone_number",
    ]
    ordering_fields = ["teacher__first_name", "created_at"]
    ordering = ["teacher__first_name"]

    def get_serializer_class(self):
        """Return appropriate serializer class based on action"""
        if self.action in ["create", "update", "partial_update"]:
            return TeacherTransportCreateUpdateSerializer
        return TeacherTransportSerializer

    def get_queryset(self):
        queryset = super().get_queryset()

        # Filter by teacher
        teacher = self.request.query_params.get("teacher")
        if teacher:
            queryset = queryset.filter(teacher_id=teacher)

        # Filter by vehicle
        vehicle = self.request.query_params.get("vehicle")
        if vehicle:
            queryset = queryset.filter(vehicle_id=vehicle)

        # Filter by route
        route = self.request.query_params.get("route")
        if route:
            queryset = queryset.filter(route_id=route)

        # Filter by stop
        stop = self.request.query_params.get("stop")
        if stop:
            queryset = queryset.filter(stop_id=stop)

        # Filter by active status
        is_active = self.request.query_params.get("is_active")
        if is_active is not None:
            queryset = queryset.filter(is_active=is_active.lower() == "true")

        # Optimize queries with select_related
        return queryset.select_related(
            "teacher",
            "vehicle",
            "route",
            "stop",
        )

    @action(detail=False, methods=["post"])
    def bulk_create(self, request):
        """
        Bulk create teacher transport assignments
        """
        assignments_data = request.data.get("assignments", [])
        created_assignments = []
        errors = []

        for idx, assignment in enumerate(assignments_data):
            serializer = self.get_serializer(data=assignment)
            if serializer.is_valid():
                serializer.save()
                created_assignments.append(serializer.data)
            else:
                errors.append({"index": idx, "errors": serializer.errors})

        return Response(
            {
                "created": created_assignments,
                "errors": errors,
                "total_processed": len(assignments_data),
                "total_created": len(created_assignments),
            },
            status=status.HTTP_207_MULTI_STATUS if errors else status.HTTP_201_CREATED,
        )

    @action(detail=True, methods=["post"])
    def toggle_active(self, request, pk=None):
        """
        Toggle is_active status
        """
        transport = self.get_object()
        transport.is_active = not transport.is_active
        transport.save()
        serializer = self.get_serializer(transport)
        return Response(serializer.data)

    @action(detail=False, methods=["get"])
    def available_teachers(self, request):
        """
        Get teachers without active transport assignment
        """
        from people.models import Teacher

        vehicle_id = request.query_params.get("vehicle")

        queryset = Teacher.objects.filter(is_active=True)

        # Get teachers that already have active transport
        assigned_teacher_ids = TeacherTransport.objects.filter(
            is_active=True
        ).values_list("teacher_id", flat=True)

        # Exclude teachers with active transport
        available = queryset.exclude(id__in=assigned_teacher_ids)

        # Optional: Filter by vehicle capacity
        if vehicle_id:
            try:
                vehicle = TransportVehicle.objects.get(id=vehicle_id)
                current_count = TeacherTransport.objects.filter(
                    vehicle_id=vehicle_id, is_active=True
                ).count()

                # Calculate available slots
                available_slots = vehicle.capacity - current_count

                # Limit available teachers if needed
                if available_slots > 0:
                    available = available[:available_slots]
            except TransportVehicle.DoesNotExist:
                pass

        # Create response data
        available_data = []
        for teacher in available:
            available_data.append(
                {
                    "id": teacher.id,
                    "first_name": teacher.first_name,
                    "last_name": teacher.last_name,
                    "full_name": f"{teacher.first_name or ''} {teacher.last_name or ''}".strip(),
                    "employee_id": teacher.employee_id,
                    "email": teacher.email,
                    "phone_number": teacher.phone_number,
                }
            )

        return Response(available_data)

    @action(detail=True, methods=["get"])
    def route_details(self, request, pk=None):
        """
        Get route details for a teacher's transport assignment
        """
        transport = self.get_object()
        route = transport.route

        if not route:
            return Response(
                {"error": "No route assigned to this transport"},
                status=status.HTTP_404_NOT_FOUND,
            )

        stops = route.stops.all().order_by("stop_order")

        return Response(
            {
                "route": {
                    "id": route.id,
                    "name": route.route_name,
                    "start_location": route.start_location,
                    "destination": route.destination,
                    "distance_km": route.distance_km,
                },
                "vehicle": {
                    "id": transport.vehicle.id,
                    "bus_number": transport.vehicle.bus_number,
                    "vehicle_number": transport.vehicle.vehicle_number,
                    "driver_name": transport.vehicle.driver_name,
                    "driver_phone": transport.vehicle.driver_phone,
                },
                "stops": [
                    {
                        "id": stop.id,
                        "name": stop.stop_name,
                        "order": stop.stop_order,
                        "arrival_time": stop.arrival_time,
                    }
                    for stop in stops
                ],
                "assigned_stop": (
                    {
                        "id": transport.stop.id if transport.stop else None,
                        "name": (
                            transport.stop.stop_name
                            if transport.stop
                            else transport.pickup_point
                        ),
                        "pickup_point": transport.pickup_point,
                    }
                    if (transport.stop or transport.pickup_point)
                    else None
                ),
            }
        )


# =====================================================
# DASHBOARD & REPORTING ACTIONS
# =====================================================


class TransportDashboardViewSet(viewsets.GenericViewSet):
    """
    ViewSet for Transport Dashboard and Reports
    """

    permission_classes = [IsAuthenticated, IsAdminUser]

    @action(detail=False, methods=["get"])
    def stats(self, request):
        """
        Get transport dashboard statistics
        """
        total_vehicles = TransportVehicle.objects.count()
        total_routes = Route.objects.count()
        total_stops = Stop.objects.count()
        active_students = StudentTransport.objects.filter(is_active=True).count()
        active_teachers = TeacherTransport.objects.filter(is_active=True).count()

        total_capacity = (
            TransportVehicle.objects.aggregate(total=Sum("capacity"))["total"] or 0
        )
        total_occupied = active_students + active_teachers

        # Vehicles by type
        vehicles_by_type = {}
        for vehicle in TransportVehicle.objects.all():
            type_name = vehicle.transport_type.name
            vehicles_by_type[type_name] = vehicles_by_type.get(type_name, 0) + 1

        # Students by class
        students_by_class = {}
        for transport in StudentTransport.objects.filter(is_active=True).select_related(
            "enrollment__academic_class__standard"
        ):
            if transport.enrollment:
                class_name = transport.enrollment.academic_class.standard.name
                students_by_class[class_name] = students_by_class.get(class_name, 0) + 1

        return Response(
            {
                "total_vehicles": total_vehicles,
                "total_routes": total_routes,
                "total_stops": total_stops,
                "active_students": active_students,
                "active_teachers": active_teachers,
                "total_occupied_seats": total_occupied,
                "total_capacity": total_capacity,
                "utilization_percentage": (
                    (total_occupied / total_capacity * 100) if total_capacity > 0 else 0
                ),
                "vehicles_by_type": vehicles_by_type,
                "students_by_class": students_by_class,
            }
        )

    @action(detail=False, methods=["get"])
    def capacity_report(self, request):
        """
        Get vehicle capacity utilization report
        """
        vehicles = TransportVehicle.objects.all()
        report = []

        for vehicle in vehicles:
            student_count = StudentTransport.objects.filter(
                vehicle=vehicle, is_active=True
            ).count()
            teacher_count = TeacherTransport.objects.filter(
                vehicle=vehicle, is_active=True
            ).count()
            total_assigned = student_count + teacher_count

            report.append(
                {
                    "vehicle_id": vehicle.id,
                    "bus_number": vehicle.bus_number,
                    "vehicle_number": vehicle.vehicle_number,
                    "driver_name": vehicle.driver_name,
                    "driver_phone": vehicle.driver_phone,
                    "capacity": vehicle.capacity,
                    "students_assigned": student_count,
                    "teachers_assigned": teacher_count,
                    "total_assigned": total_assigned,
                    "available_seats": vehicle.capacity - total_assigned,
                    "utilization_percentage": (
                        round((total_assigned / vehicle.capacity * 100), 2)
                        if vehicle.capacity > 0
                        else 0
                    ),
                }
            )

        report.sort(key=lambda x: x["utilization_percentage"], reverse=True)

        return Response(
            {
                "vehicles": report,
                "summary": {
                    "total_vehicles": len(report),
                    "total_capacity": sum(v["capacity"] for v in report),
                    "total_assigned": sum(v["total_assigned"] for v in report),
                    "overall_utilization": (
                        round(
                            (
                                sum(v["total_assigned"] for v in report)
                                / sum(v["capacity"] for v in report)
                                * 100
                            ),
                            2,
                        )
                        if sum(v["capacity"] for v in report) > 0
                        else 0
                    ),
                },
            }
        )

    @action(detail=False, methods=["get"])
    def route_wise_report(self, request):
        """
        Get route-wise student transport report
        """
        routes = Route.objects.all()
        report = []

        for route in routes:
            students = StudentTransport.objects.filter(
                route=route, is_active=True
            ).select_related("student__user", "enrollment__academic_class")

            report.append(
                {
                    "route_id": route.id,
                    "route_name": route.route_name,
                    "start_location": route.start_location,
                    "destination": route.destination,
                    "vehicle": {
                        "bus_number": route.vehicle.bus_number,
                        "capacity": route.vehicle.capacity,
                    },
                    "total_students": students.count(),
                    "students": [
                        {
                            "id": s.id,
                            "name": s.student.user.get_full_name(),
                            "class": (
                                s.enrollment.academic_class.standard.name
                                if s.enrollment
                                else None
                            ),
                            "stop": s.stop.stop_name if s.stop else s.pickup_point,
                            "fee_amount": str(s.fee_amount),
                        }
                        for s in students
                    ],
                }
            )

        return Response(report)

    @action(detail=False, methods=["get"])
    def fee_report(self, request):
        """
        Get transport fee collection report
        """
        academic_year = request.query_params.get("academic_year")

        queryset = StudentTransport.objects.filter(is_active=True)
        if academic_year:
            queryset = queryset.filter(academic_year=academic_year)

        total_fee = queryset.aggregate(total=Sum("fee_amount"))["total"] or 0

        # Group by class
        fee_by_class = {}
        for transport in queryset.select_related(
            "enrollment__academic_class__standard"
        ):
            if transport.enrollment:
                class_name = transport.enrollment.academic_class.standard.name
                fee_by_class[class_name] = fee_by_class.get(class_name, 0) + float(
                    transport.fee_amount
                )

        return Response(
            {
                "total_students": queryset.count(),
                "total_fee_collected": float(total_fee),
                "average_fee_per_student": (
                    float(total_fee / queryset.count()) if queryset.count() > 0 else 0
                ),
                "fee_by_class": fee_by_class,
                "students": StudentTransportSerializer(queryset, many=True).data,
            }
        )
