from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination
from .models import Link, ImageCollection, Image
from .serializers import LinkSerializer, ImageCollectionSerializer, ImageSerializer, ImageDescriptionSerializer
from .storage import R2Storage
import uuid
import logging
from django.conf import settings
import os


logger = logging.getLogger(__name__)


class StandardResultsSetPagination(PageNumberPagination):
    page_size = 10
    page_size_query_param = 'page_size'
    max_page_size = 100


class LinkViewSet(viewsets.ReadOnlyModelViewSet):
    serializer_class = LinkSerializer
    pagination_class = StandardResultsSetPagination

    def get_queryset(self):
        return Link.objects.prefetch_related('tags').order_by('-created_at')

    @action(detail=False, methods=['get'], url_path='most-visited')
    def most_visited(self, request):
        """Return links sorted by click_count descending."""
        queryset = Link.objects.prefetch_related('tags').filter(click_count__gt=0).order_by('-click_count')
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

class ImageCollectionViewSet(viewsets.ModelViewSet):
    queryset = ImageCollection.objects.all()
    serializer_class = ImageCollectionSerializer

    def create(self, request, *args, **kwargs):
        """Create a new collection"""
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(
            {
                'status': 'success',
                'message': 'Collection created successfully',
                'data': serializer.data
            },
            status=status.HTTP_201_CREATED,
            headers=headers
        )

    @action(detail=True, methods=['post'])
    def upload_images(self, request, pk=None):
        """Upload images to a collection"""
        collection = self.get_object()
        files = request.FILES.getlist('file')
        descriptions = request.data.getlist('descriptions', [])  # Get descriptions list
        storage = R2Storage()

        logger.debug(f"Processing upload request for collection {collection.id}")
        logger.debug(f"Number of files: {len(files)}")
        logger.debug(f"Number of descriptions: {len(descriptions)}")

        uploaded_images = []
        for idx, file in enumerate(files):
            try:
                logger.debug(f"Processing file: {file.name}")
                logger.debug(f"File size: {file.size}")
                logger.debug(f"Content type: {file.content_type}")

                # Get description for this file if available
                description = descriptions[idx] if idx < len(descriptions) else None

                # Generate unique file key
                file_key = f"images/{collection.id}/{uuid.uuid4()}/{file.name}"

                # Validate file
                if not hasattr(file, 'read'):
                    raise ValueError("Invalid file object - missing read method")

                if not file.content_type.startswith('image/'):
                    raise ValueError("Invalid file type. Only images are allowed.")

                # Upload to R2
                try:
                    storage.upload_file(file, file_key, file.content_type)
                except Exception as e:
                    logger.error(f"Storage upload failed", exc_info=True)
                    raise ValueError(f"Storage upload failed: {str(e)}")

                # Create image record
                image = Image.objects.create(
                    collection=collection,
                    title=file.name,
                    description=description,
                    file_key=file_key,
                    content_type=file.content_type,
                    size=file.size
                )

                logger.debug(f"Created image record: {image.id}")
                uploaded_images.append(ImageSerializer(image).data)

            except Exception as e:
                logger.error(f"Upload failed for {file.name}", exc_info=True)
                return Response({
                    'status': 'error',
                    'message': str(e)
                }, status=status.HTTP_400_BAD_REQUEST)

        return Response({
            'status': 'success',
            'message': f'Successfully uploaded {len(uploaded_images)} images',
            'data': uploaded_images
        }, status=status.HTTP_201_CREATED)

    @action(detail=True, methods=['delete'])
    def delete_image(self, request, pk=None):
        """Delete an image from a collection"""
        collection = self.get_object()
        image_id = request.data.get('image_id')

        try:
            image = collection.images.get(id=image_id)
            storage = R2Storage()

            # Delete from storage
            if image.file_key:
                try:
                    storage.delete_file(image.file_key)
                except Exception as e:
                    logger.error(f"Failed to delete from storage: {e}")

            # Delete from database
            image.delete()

            return Response({
                'status': 'success',
                'message': 'Image deleted successfully'
            })

        except Image.DoesNotExist:
            return Response({
                'status': 'error',
                'message': 'Image not found'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            return Response({
                'status': 'error',
                'message': str(e)
            }, status=status.HTTP_400_BAD_REQUEST)

class ImageViewSet(viewsets.ModelViewSet):
    queryset = Image.objects.all()
    serializer_class = ImageSerializer

    @action(detail=True, methods=['patch'], url_path='update-description')
    def update_description(self, request, pk=None):
        """Update the description of an image"""
        image = self.get_object()
        serializer = ImageDescriptionSerializer(image, data=request.data, partial=True)
        
        if serializer.is_valid():
            serializer.save()
            return Response({
                'status': 'success',
                'message': 'Description updated successfully',
                'data': serializer.data
            })
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def perform_destroy(self, instance):
        """Delete image from storage when deleting record"""
        storage = R2Storage()
        try:
            if instance.file_key:
                storage.delete_file(instance.file_key)
        except Exception as e:
            logger.error(f"Failed to delete from storage: {e}")
        instance.delete()

class MusicViewSet(viewsets.ViewSet):
    def list(self, request):
        static_music = [
            {'title': 'Purple Planet', 'src': '/static/music/Purple-Planet.mp3'},
            {'title': 'Just Kidding', 'src': '/static/music/mixkit-just-kidding.mp3'},
            {'title': 'Thomas', 'src': '/static/music/Thomas-the-Tank-Engine.mp3'}
        ]
        
        data_music_dir = os.path.join(settings.BASE_DIR, 'data', 'music')
        data_music = []
        for file in os.listdir(data_music_dir):
            if file.endswith('.mp3'):
                title = os.path.splitext(file)[0].replace('-', ' ').replace('_', ' ')
                data_music.append({'title': title, 'src': f'/music/{file}'})
        
        return Response(static_music + data_music)