from rest_framework import serializers
from .models import (
    Catalogs,
    Categories,
    Series,
    Products,
    ProductGallery,
    NewsAndPressReleases,
    NewsGallery,
    Settings,
    FeaturedProducts,
    NewArrivalProducts,
)
from django.contrib.contenttypes.models import ContentType
import re, json


class FeaturedProductsCustomSerializer(serializers.ModelSerializer):
    class Meta:
        model = FeaturedProducts
        fields = ["product"]
        depth = 1


class FeaturedProductsSerializer(serializers.ModelSerializer):
    model = serializers.SerializerMethodField()
    content_type_cache = {}

    class Meta:
        model = FeaturedProducts
        fields = "__all__"
        depth = 1

    def get_model(self, obj):
        model_object_id = obj.model_object_id
        app_label = obj.model.app_label
        model = obj.model.model

        if (app_label, model) not in self.content_type_cache:
            try:
                self.content_type_cache[(app_label, model)] = ContentType.objects.get(
                    app_label=app_label, model=model
                )
            except ContentType.DoesNotExist:  # pragma: no cover
                return obj.model

        content_type = self.content_type_cache[(app_label, model)]

        try:
            model_object = content_type.get_object_for_this_type(id=model_object_id)
            model_data = list(model_object.__dict__.items())

            response = {"model": str(model).title()}

            for key, value in model_data:
                if not key.startswith("_"):
                    dict_pattern = re.compile(
                        r'^\{.*"delta"\s*:\s*".*".*"html"\s*:\s*".*".*\}$', re.DOTALL
                    )
                    if dict_pattern.match(str(value)):
                        dict_format = json.loads(value)
                        value = dict_format["html"]

                    response[key] = value

            return response
        except ContentType.DoesNotExist:  # pragma: no cover
            return obj.model


class FileUploadSerializer(serializers.Serializer):
    file = serializers.FileField()


class CatalogsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Catalogs
        fields = "__all__"


class CatalogsWithFileUploadSerializer(serializers.Serializer):
    title = serializers.CharField(max_length=255)
    image_path = serializers.FileField(required=False)
    link = serializers.CharField(max_length=1000)


class CategoriesSerializer(serializers.ModelSerializer):
    class Meta:
        model = Categories
        fields = "__all__"


class SeriesSerializer(serializers.ModelSerializer):
    class Meta:
        model = Series
        fields = "__all__"


class ProductGallerySerializer(serializers.ModelSerializer):
    class Meta:
        model = ProductGallery
        fields = "__all__"
        depth = 1


class ProductGalleryCustomSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProductGallery
        fields = ["id", "created_at", "updated_at", "image_path", "is_shown"]


class ProductsIdSerializer(serializers.Serializer):
    id = serializers.CharField(max_length=1000)


class BulkProductsIdSerializer(serializers.Serializer):
    ids = serializers.ListField(child=serializers.CharField(max_length=1000))


class ProductsCustomSerializer(serializers.ModelSerializer):
    class Meta:
        model = Products
        fields = [
            "id",
            "created_at",
            "updated_at",
            "name",
            "image_path",
            "edp_number",
            "article_number",
            "description",
            "finish",
            "size",
            "category",
            "price",
            "is_active",
            "sold_as_set",
            "is_discounted",
            "is_coming_soon",
            "discount_rate",
            "discount_valid_until",
            "quantity",
            "series",
            "arrival_date",
            "is_new_arrival",
        ]

    def to_representation(self, instance):
        representation = super().to_representation(instance)

        if instance.description.html:
            representation["description"] = instance.description.html

        return representation


class ProductsWithUploadImagesSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=525)
    image_path = serializers.FileField(required=False)
    edp_number = serializers.CharField(max_length=255)
    article_number = serializers.CharField(max_length=255, required=False)
    description = serializers.CharField(required=False)
    finish = serializers.CharField(max_length=255, required=False)
    size = serializers.CharField(max_length=255, required=False)
    category = serializers.CharField(max_length=525)
    price = serializers.FloatField()
    is_active = serializers.BooleanField(default=True)
    sold_as_set = serializers.BooleanField(default=False)
    is_discounted = serializers.BooleanField(default=False)
    discount_valid_until = serializers.DateTimeField(required=False)
    discount_rate = serializers.IntegerField(default=0)
    quantity = serializers.IntegerField(default=0)
    series = serializers.CharField(max_length=525, required=False)
    arrival_date = serializers.DateTimeField(required=False)
    is_coming_soon = serializers.BooleanField(default=False)
    is_new_arrival = serializers.BooleanField(default=False)
    existing_images_id = serializers.ListField(
        child=serializers.CharField(max_length=1000), required=False
    )
    lifestyle_images = serializers.ListField(
        child=serializers.FileField(), required=False
    )


class ProductsSerializer(serializers.ModelSerializer):
    product_images = ProductGalleryCustomSerializer(many=True, read_only=True)

    class Meta:
        model = Products
        fields = [
            "id",
            "created_at",
            "updated_at",
            "name",
            "image_path",
            "edp_number",
            "article_number",
            "description",
            "finish",
            "size",
            "category",
            "price",
            "is_active",
            "sold_as_set",
            "is_discounted",
            "discount_rate",
            "discount_valid_until",
            "quantity",
            "series",
            "arrival_date",
            "is_new_arrival",
            "product_images",
            "is_coming_soon",
        ]
        depth = 1

    def to_representation(self, instance):
        representation = super().to_representation(instance)

        is_price_visible = self.context.get("is_price_visible", None)
        is_authenticated = self.context.get("is_authenticated", False)

        if (
            not is_authenticated
            or is_price_visible is None
            or is_price_visible.lower() in ["false", "no"]
        ):
            representation.pop("price", None)

        if instance.description.html:
            representation["description"] = instance.description.html

        return representation


class ProductJSONSerializerWithEDPNumberAsKey(serializers.Serializer):
    data = serializers.JSONField()


class NewsGallerySerializer(serializers.ModelSerializer):
    class Meta:
        model = NewsGallery
        fields = "__all__"
        depth = 1


class NewsGalleryCustomSerializer(serializers.ModelSerializer):
    class Meta:
        model = NewsGallery
        fields = [
            "id",
            "created_at",
            "image_path",
        ]


class NewsAndPressReleasesSerializer(serializers.ModelSerializer):
    news_images = NewsGalleryCustomSerializer(many=True, read_only=True, required=False)

    class Meta:
        model = NewsAndPressReleases
        fields = [
            "id",
            "created_at",
            "updated_at",
            "title",
            "short_description",
            "long_description",
            "image_path",
            "link",
            "type",
            "news_images",
        ]

    def to_representation(self, instance):
        representation = super().to_representation(instance)

        if instance.short_description.html:
            representation["short_description"] = instance.short_description.html

        if instance.long_description.html:
            representation["long_description"] = instance.long_description.html

        return representation


class NewsAndPressReleasesCustomSerializer(serializers.Serializer):
    title = serializers.CharField(max_length=525)
    short_description = serializers.CharField(max_length=1000, required=False)
    long_description = serializers.CharField(required=False)
    image_path = serializers.FileField(required=False)
    link = serializers.CharField(required=False)
    type = serializers.CharField()
    news_images = serializers.ListField(child=serializers.FileField(), required=False)


class SettingsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Settings
        fields = "__all__"


class NewArrivalProductsSerializer(serializers.ModelSerializer):
    class Meta:
        model = NewArrivalProducts
        fields = "__all__"
        depth = 1
