from drf_spectacular.utils import extend_schema, OpenApiTypes
from drf_spectacular.utils import OpenApiParameter
from core.views import BaseListCreateView
from rest_framework import generics, status, parsers
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.filters import SearchFilter, OrderingFilter
from rest_framework.permissions import AllowAny, IsAdminUser
from django_filters.rest_framework import DjangoFilterBackend
from django.core.files.storage import default_storage
from .models import GalleryImage, Album
from .serializers import GalleryImageSerializer, AlbumSerializer
from core.filters import GalleryFilter, AlbumFilter


@extend_schema(tags=["Gallery"])
class GalleryImageListView(BaseListCreateView):
    serializer_class = GalleryImageSerializer
    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    filterset_class = GalleryFilter
    ordering_fields = ["order", "created_at"]
    ordering = ["-is_featured", "order"]

    def initialize_request(self, request, *args, **kwargs):
        self._http_method = request.method
        return super().initialize_request(request, *args, **kwargs)

    def get_permissions(self):
        if self._http_method == "GET":
            return [AllowAny()]
        return []

    def get_authenticators(self):
        if self._http_method == "GET":
            return []
        return super().get_authenticators()

    def get_queryset(self):
        return GalleryImage.objects.all()


@extend_schema(tags=["Gallery"])
class GalleryImageDetailView(generics.RetrieveUpdateDestroyAPIView):
    serializer_class = GalleryImageSerializer
    permission_classes = [IsAdminUser]
    queryset = GalleryImage.objects.all()
    lookup_field = "pk"
    http_method_names = ['get', 'patch', 'delete']


@extend_schema(
    tags=["Gallery"],
    request={
        "multipart/form-data": {
            "type": "object",
            "properties": {
                "images": {
                    "type": "array",
                    "items": {"type": "string", "format": "binary"},
                },
                "album": {"type": "string", "format": "uuid"},
                "category": {"type": "string"},
                "is_published": {"type": "boolean"},
            },
        }
    },
    responses={201: GalleryImageSerializer(many=True)},
)
class GalleryBulkUploadView(APIView):
    """Upload multiple images at once. Creates one GalleryImage per file."""
    permission_classes = [IsAdminUser]
    parser_classes = [parsers.MultiPartParser, parsers.FormParser]

    def post(self, request, *args, **kwargs):
        files = request.FILES.getlist("images")
        if not files:
            return Response(
                {"detail": "No files provided. Use the 'images' field with one or more files."},
                status=status.HTTP_400_BAD_REQUEST,
            )

        album_id = request.data.get("album") or None
        category = request.data.get("category") or GalleryImage._meta.get_field("category").default
        is_published = request.data.get("is_published", "true")
        is_published = str(is_published).lower() in ("true", "1", "yes")

        created = []
        errors = []

        for f in files:
            if not f.content_type or not f.content_type.startswith("image/"):
                errors.append({"file": f.name, "error": "Not an image file."})
                continue

            try:
                path = default_storage.save(f"gallery/{f.name}", f)
                url = request.build_absolute_uri(default_storage.url(path))

            except Exception as e:
                errors.append({"file": f.name, "error": str(e)})
                continue

            image = GalleryImage.objects.create(
                image_url=url,
                album_id=album_id,
                category=category,
                is_published=is_published,
                created_by=request.user if hasattr(GalleryImage, "created_by") else None,
            )
            created.append(image)

        serializer = GalleryImageSerializer(created, many=True)
        response_status = status.HTTP_201_CREATED if created else status.HTTP_400_BAD_REQUEST

        return Response(
            {"created": serializer.data, "errors": errors, "created_count": len(created)},
            status=response_status,
        )



@extend_schema(tags=["Gallery"])
class AlbumListView(BaseListCreateView):
    serializer_class = AlbumSerializer
    permission_classes = [IsAdminUser]
    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    filterset_class = AlbumFilter
    ordering_fields = ["date", "created_at"]
    ordering = ["-is_featured", "-date"]

    def get_queryset(self):
        return Album.objects.all()


@extend_schema(tags=["Gallery"])
class AlbumDetailView(generics.RetrieveUpdateDestroyAPIView):
    serializer_class = AlbumSerializer
    permission_classes = [IsAdminUser]
    queryset = Album.objects.all()
    lookup_field = "pk"
    http_method_names = ['get', 'patch', 'delete']