from django.apps import apps

from rest_framework import serializers
from rest_framework.settings import api_settings
from drf_queryfields import QueryFieldsMixin

from icekit.api.base_serializers import WritableSerializerHelperMixin, \
    WritableRelatedFieldSettings


Image = apps.get_model('icekit_plugins_image.Image')
MediaCategory = apps.get_model('icekit.MediaCategory')


class MediaCategorySerializer(serializers.ModelSerializer):
    # Redefine `name` field here to avoid `unique=True` constraint that will
    # be unavoidably applied by DRF validators if we leave the field to be
    # autogenerated based on the model.
    name = serializers.CharField(
        max_length=255,
        read_only=False,
        required=False,
    )

    class Meta:
        model = MediaCategory
        fields = ['id', 'name']
        extra_kwargs = {
            'id': {
                'read_only': False,
                'required': False,
            },
        }


class ImageSerializer(
    WritableSerializerHelperMixin,
    QueryFieldsMixin,
    serializers.HyperlinkedModelSerializer
):
    """
    A serializer for an ICEkit Image.
    """
    categories = MediaCategorySerializer(
        many=True,
    )

    class Meta:
        model = Image
        fields = [
            api_settings.URL_FIELD_NAME,
            'id',
            'image',
            'width',
            'height',
            'title',
            'alt_text',
            'caption',
            'credit',
            'source',
            'external_ref',
            'categories',
            'license',
            'notes',
            'date_created',
            'date_modified',
            'is_ok_for_web',
            'is_cropping_allowed',
        ]
        extra_kwargs = {
            'url': {
                'lookup_field': 'pk',
                'view_name': 'api:image-api-detail',
            },
        }
        writable_related_fields = {
            'categories': WritableRelatedFieldSettings(
                lookup_field=['id', 'name'], can_create=True),
        }


# TODO It is probably not a good idea to allow API user to set auto-gen ID
# field, but this is the only way I have found (so far) to allow ID to be
# passed through API to relate existing images.
class RelatedImageSerializer(ImageSerializer):
    """
    A serializer for an ICEkit Image relationships that exposes the ID primary
    key field to permit referring to existing images by ID, instead of needing
    to upload an actual image file every time.
    """
    class Meta(ImageSerializer.Meta):
        extra_kwargs = {
            'id': {
                'read_only': False,
                'required': False,
            },
            'image': {
                'required': False,
            }
        }
