from django.db.models import Q
from rest_framework import filters, parsers, viewsets

from .models import (
    Branch,
    Brand,
    GalleryImage,
    Inventory,
    Lead,
    Offer,
    Part,
    Scooter,
    ScooterAsset3D,
    ScooterImage,
    TestRideBooking,
    Testimonial,
)
from .permissions import AdminOrReadOnly, CreatePublicAdminManage
from .serializers import (
    AdminLeadSerializer,
    AdminTestRideBookingSerializer,
    BranchSerializer,
    BrandSerializer,
    GalleryImageSerializer,
    InventorySerializer,
    LeadSerializer,
    OfferSerializer,
    PartSerializer,
    ScooterAsset3DSerializer,
    ScooterImageSerializer,
    ScooterSerializer,
    TestRideBookingSerializer,
    TestimonialSerializer,
)


class UploadModelViewSet(viewsets.ModelViewSet):
    parser_classes = [parsers.MultiPartParser, parsers.FormParser, parsers.JSONParser]
    permission_classes = [AdminOrReadOnly]


class BrandViewSet(UploadModelViewSet):
    queryset = Brand.objects.all()
    serializer_class = BrandSerializer
    lookup_field = "slug"
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ["name", "short_description", "key_strength"]
    ordering_fields = ["name", "created_at", "updated_at"]


class BranchViewSet(UploadModelViewSet):
    queryset = Branch.objects.all()
    serializer_class = BranchSerializer
    lookup_field = "slug"
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ["name", "city", "district", "phone"]
    ordering_fields = ["city", "created_at", "updated_at"]


class ScooterViewSet(UploadModelViewSet):
    serializer_class = ScooterSerializer
    lookup_field = "slug"
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ["name", "short_description", "brand__name", "battery", "motor_power"]
    ordering_fields = ["name", "price", "offer_price", "range_km", "top_speed_kmph", "created_at"]

    def get_queryset(self):
        queryset = (
            Scooter.objects.select_related("brand", "asset_3d")
            .prefetch_related("gallery_images", "inventory__branch")
            .all()
        )
        if not self.request.user.is_staff:
            queryset = queryset.filter(published=True)
        brand = self.request.query_params.get("brand")
        featured = self.request.query_params.get("featured")
        if brand:
            queryset = queryset.filter(Q(brand__slug=brand) | Q(brand__id=brand))
        if featured in {"1", "true", "yes"}:
            queryset = queryset.filter(is_featured=True)
        return queryset


class ScooterImageViewSet(UploadModelViewSet):
    queryset = ScooterImage.objects.select_related("scooter").all()
    serializer_class = ScooterImageSerializer


class ScooterAsset3DViewSet(UploadModelViewSet):
    queryset = ScooterAsset3D.objects.select_related("scooter", "scooter__brand").all()
    serializer_class = ScooterAsset3DSerializer


class InventoryViewSet(UploadModelViewSet):
    queryset = Inventory.objects.select_related("scooter", "branch").all()
    serializer_class = InventorySerializer
    filter_backends = [filters.SearchFilter]
    search_fields = ["scooter__name", "branch__city", "status"]


class PartViewSet(UploadModelViewSet):
    queryset = Part.objects.all()
    serializer_class = PartSerializer
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ["name", "category", "compatibility"]
    ordering_fields = ["name", "category", "price", "created_at"]

    def get_queryset(self):
        queryset = super().get_queryset()
        category = self.request.query_params.get("category")
        if category:
            queryset = queryset.filter(category__iexact=category)
        return queryset


class OfferViewSet(UploadModelViewSet):
    serializer_class = OfferSerializer
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ["title", "description", "category", "discount_label"]
    ordering_fields = ["valid_until", "created_at"]

    def get_queryset(self):
        queryset = Offer.objects.select_related("brand", "scooter", "branch").all()
        if not self.request.user.is_staff:
            queryset = queryset.filter(active=True)
        return queryset


class GalleryImageViewSet(UploadModelViewSet):
    queryset = GalleryImage.objects.select_related("branch", "scooter").all()
    serializer_class = GalleryImageSerializer
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ["title", "alt", "category"]
    ordering_fields = ["featured", "created_at", "updated_at"]

    def get_queryset(self):
        queryset = super().get_queryset()
        category = self.request.query_params.get("category")
        if category:
            queryset = queryset.filter(category__iexact=category)
        return queryset


class TestimonialViewSet(UploadModelViewSet):
    queryset = Testimonial.objects.all()
    serializer_class = TestimonialSerializer
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ["customer_name", "location", "comment", "scooter_name"]
    ordering_fields = ["rating", "created_at"]


class TestRideBookingViewSet(viewsets.ModelViewSet):
    queryset = TestRideBooking.objects.select_related("branch", "scooter").all()
    permission_classes = [CreatePublicAdminManage]

    def get_serializer_class(self):
        if self.request.user and self.request.user.is_staff:
            return AdminTestRideBookingSerializer
        return TestRideBookingSerializer


class LeadViewSet(viewsets.ModelViewSet):
    queryset = Lead.objects.select_related("branch", "scooter").all()
    permission_classes = [CreatePublicAdminManage]

    def get_serializer_class(self):
        if self.request.user and self.request.user.is_staff:
            return AdminLeadSerializer
        return LeadSerializer
