from rest_framework import serializers
from developer.models import Developer
from rest_framework import serializers
from rest_framework.pagination import PageNumberPagination
from django.db.models import Q

from math import ceil
from .models import Developer, DeveloperTranslate

class DeveloperSerializer(serializers.ModelSerializer):
    class Meta:
        model = Developer
        fields = ["name", "slug"]
        
from rest_framework import serializers
from .models import Developer, DeveloperTranslate
# from development.serializers import DevelopmentSerializer

class AggregateRatingSerializer(serializers.Serializer):
    type = serializers.CharField(default='AggregateRating')
    rating_value = serializers.CharField(default='10') 
    best_rating = serializers.CharField(default='10')
    rating_count = serializers.CharField()

class MetaTagsSerializer(serializers.Serializer):
    title = serializers.CharField()
    description = serializers.CharField()
    keywords = serializers.CharField()
    og_title = serializers.CharField()
    og_description = serializers.CharField() 
    og_image = serializers.CharField()
    og_type = serializers.CharField()
    twitter_card = serializers.CharField()
    twitter_title = serializers.CharField()
    twitter_description = serializers.CharField()
    twitter_image = serializers.CharField()
    canonical_url = serializers.CharField()

class DeveloperTranslateSerializer(serializers.ModelSerializer):
    web_address = serializers.CharField()
    rate = serializers.IntegerField()
    property_num = serializers.IntegerField()
    is_featured = serializers.BooleanField()
    image = serializers.CharField()
    micro_data = serializers.JSONField()
    meta_tags = MetaTagsSerializer()
    # developments = DevelopmentSerializer(many=True, read_only=True)

    class Meta:
        model = DeveloperTranslate
        fields = ['id', 'name', 'slug', 'property_num', 'web_address', 
                 'is_featured', 'summary', 'description', 'image', 
                 'rate', 'created_at', 'developments', 'micro_data', 
                 'meta_tags']

class FilterDeveloperSerializer(serializers.Serializer):
    node = DeveloperTranslateSerializer(many=True)
    page_info = serializers.JSONField()
    micro_data = serializers.JSONField()
    meta_tags = MetaTagsSerializer()








class DeveloperPagination(PageNumberPagination):
    page_size = 10
    page_size_query_param = 'page_size'
    max_page_size = 50


class MetaTagsSerializer(serializers.Serializer):
    """SEO Meta Tags Serializer"""
    title = serializers.CharField()
    description = serializers.CharField()
    keywords = serializers.CharField()
    og_title = serializers.CharField()
    og_description = serializers.CharField()
    og_image = serializers.CharField()
    og_type = serializers.CharField()
    twitter_card = serializers.CharField()
    twitter_title = serializers.CharField()
    twitter_description = serializers.CharField()
    twitter_image = serializers.CharField()
    canonical_url = serializers.CharField()


class AggregateRatingSerializer(serializers.Serializer):
    type = serializers.CharField(default="AggregateRating")
    rating_value = serializers.CharField(default="10")
    best_rating = serializers.CharField(default="10")
    ratingCount = serializers.CharField()

    def to_representation(self, instance):
        data = super().to_representation(instance)
        data['rating_value'] = f"{instance.developer.rate}"
        data['ratingCount'] = f"{instance.developer.developments.filter(is_active=True, is_deleted=False).count()}"
        return data


class DeveloperMicroDataSerializer(serializers.Serializer):
    type = serializers.CharField(default="Organization")
    name = serializers.CharField()
    description = serializers.CharField()
    url = serializers.CharField()
    image = serializers.CharField()
    aggregate_rating = AggregateRatingSerializer()

    def to_representation(self, instance):
        data = super().to_representation(instance)
        data['name'] = instance.developer.name
        data['description'] = instance.summary
        data['url'] = instance.developer.web_address
        data['image'] = f"https://file.entralon.com/{instance.developer.image}"
        data['aggregate_rating'] = AggregateRatingSerializer(instance).data
        return data


class DevelopmentSerializer(serializers.Serializer):
    node = serializers.ListField()
    page_info = serializers.DictField()


class DeveloperTranslateSerializer(serializers.ModelSerializer):
    web_address = serializers.CharField(source='developer.web_address')
    rate = serializers.IntegerField(source='developer.rate')
    property_num = serializers.SerializerMethodField()
    is_featured = serializers.BooleanField(source='developer.is_featured')
    image = serializers.SerializerMethodField()
    micro_data = serializers.SerializerMethodField()
    meta_tags = serializers.SerializerMethodField()
    development = serializers.SerializerMethodField()

    class Meta:
        model = DeveloperTranslate
        fields = ["id", "name", "slug", 'property_num', "web_address", 'is_featured',
                  'summary', 'description', "image", "rate", "created_at", "development"]

    def get_property_num(self, obj):
        return obj.developer.developments.filter(is_active=True, is_deleted=False).count()

    def get_image(self, obj):
        try:
            return obj.developer.image
        except:
            return ""

    def get_micro_data(self, obj):
        return {
            "@context": "https://schema.org",
            "@type": "Organization",
            "name": obj.developer.name,
            "url": f"https://entralon.com/en/developers/developer-{obj.slug}",
            "logo": f"https://file.entralon.com/{obj.developer.image}",
            "address": {
                "@type": "PostalAddress",
                # "streetAddress": "Office 42, London Tower",
                "addressLocality": obj.developer.city.name if obj.developer.city else "",
                "addressCountry": obj.developer.country.code if obj.developer.country else "",
            },
            # "contactPoint": {
            #     "@type": "ContactPoint",
            #     "telephone": "+44 20 5678 1234",
            #     "contactType": "sales"
            # }
        }

    def get_meta_tags(self, obj):
        keywords = f"{obj.developer.name}, {obj.name}, developer, home builder, real estate"
        base_url = "https://entralon.com"
        canonical = f"{base_url}/{obj.language.code}/developers/{obj.developer.slug}"
        title = obj.developer.name
        summary = obj.summary[:160] if obj.summary else ""
        image = obj.developer.image
        return {
            "title": title,
            "description": summary,
            "keywords": keywords,
            "og_title": title,
            "og_description": summary,
            "og_image": f"https://file.entralon.com/{image}",
            "og_type": "website",
            "twitter_card": "summary_large_image",
            "twitter_title": title,
            "twitter_description": summary,
            "twitter_image": f"https://file.entralon.com/{image}",
            "canonical_url": canonical
        }

    def get_development(self, obj):
        request = self.context.get('request')
        page = int(request.query_params.get('page', 1))
        page_size = int(request.query_params.get('page_size', 10))
        search = request.query_params.get('search')
        featured = request.query_params.get('featured')
        sort_by = request.query_params.get('sort_by', '-created_at')
        
        if page_size > 20:
            page_size = 20
            
        f = Q(development__is_active=True) & Q(development__is_deleted=False)
        if featured is not None:
            f &= Q(development__is_featured=featured)
        if search is not None and search != "":
            f &= Q(development__title__icontains=search) | Q(
                development__translates__title__icontains=search)
                
        qs = obj.development_translate.filter(f).order_by(
            "development__is_sold_out", "development__completed_date", sort_by)
        qs = qs.distinct()
        count = qs.count()
        pages_count = ceil(count / page_size)
        if page > pages_count:
            page = pages_count
        if page < 1:
            page = 1
        start = 0 + (page - 1) * page_size
        end = start + page_size
        has_next_page = end < count
        
        return {
            "node": qs[start:end],
            "page_info": {
                "has_next_page": has_next_page,
                "has_previous_page": page > 1,
                "current_page": page,
                "page_size": page_size,
                "count": count,
                "pages_count": pages_count,
            }
        }

    def to_representation(self, instance):
        data = super().to_representation(instance)
        data['id'] = instance.developer.id
        data['name'] = instance.developer.name
        data['slug'] = f"developer-{instance.developer.slug}"
        return data


class FilterDeveloperSerializer(serializers.Serializer):
    node = DeveloperTranslateSerializer(many=True)
    page_info = serializers.DictField()
    micro_data = serializers.SerializerMethodField()
    meta_tags = MetaTagsSerializer()

    def get_micro_data(self, obj):
        item_list = []
        for item in obj['node']:
            item_list.append({
                "@type": "ListItem",
                "position": item.id,
                "url": f"https://entralon.com/{item.language.code}/developers/developer-{item.developer.slug}",
                "name": f"{item.developer.name}",
                "image": f"https://file.entralon.com/{item.developer.image}",
                "description": item.summary,
                "item": {
                    "@context": "https://schema.org",
                    "@type": "Organization",
                    "name": item.developer.name,
                    "url": f"https://entralon.com/en/developers/developer-{item.slug}",
                    "logo": f"https://file.entralon.com/{item.developer.image}",
                    "address": {
                        "@type": "PostalAddress",
                        # "streetAddress": "Office 42, London Tower",
                        "addressLocality": item.developer.city.name if item.developer.city else "",
                        "addressCountry": item.developer.country.code if item.developer.country else "",
                    },
                    # "contactPoint": {
                    #     "@type": "ContactPoint",
                    #     "telephone": "+44 20 5678 1234",
                    #     "contactType": "sales"
                    # }
                }
            })
        micro_data = {
            "@context": "https://schema.org",
            "@type": "ItemList",
            "itemListElement": item_list,
        }
        return micro_data

