from rest_framework.serializers import ModelSerializer
from admin_panel.models import *
from rest_framework import serializers
from django.db.models import Avg, Q, Count   # <-- add Count
class ProductCategorySerializer(serializers.ModelSerializer):
    children = serializers.SerializerMethodField()

    class Meta:
        model = ProductCategory
        fields = "__all__"

    def get_children(self, obj):
        children = obj.children.filter(is_active=True)

        return ProductCategorySerializer(
            children,
            many=True
        ).data

class ProductCategorySerializerPATCH(ModelSerializer):
    class Meta:
        model = ProductCategory
        fields = '__all__'
        
from rest_framework import serializers


class ProductPlatformSerializer(serializers.ModelSerializer):
    class Meta:
        model = Platform
        fields = [
            "id",
            "name",
            "price",
            "url",
            "rating",
            "is_active",
        ]
class ProductSerializer(serializers.ModelSerializer):

    category = ProductCategorySerializer(
        read_only=True
    )

    platforms = serializers.SerializerMethodField()

    lowest_price_platform = serializers.SerializerMethodField()

    class Meta:
        model = Product

        fields = [
            "id",
            "product_name",
            "category",
            "platforms",
            "lowest_price_platform",
            "rating",
        ]

    def get_platforms(self, obj):

        platforms = obj.platforms.filter(
            is_active=True
        ).order_by("price")

        return ProductPlatformSerializer(
            platforms,
            many=True
        ).data

    def get_lowest_price_platform(self, obj):

        platform = (
            obj.platforms
            .filter(is_active=True)
            .order_by("price")
            .first()
        )

        if not platform:
            return None

        return ProductPlatformSerializer(
            platform
        ).data
        
class ProductSerializerPOST(ModelSerializer):
    key_highlights = serializers.ListField(child=serializers.CharField(), required=False)
    specifications = serializers.DictField(child=serializers.CharField(), required=False)
    sizes = serializers.ListField(child=serializers.CharField(), required=False)
    colors = serializers.ListField(child=serializers.CharField(), required=False)

    class Meta:
        model = Product
        fields = '__all__'
        
class PlatformSerializer(ModelSerializer):
    product = ProductSerializer(read_only=True)
    class Meta:
        model = Platform
        fields = '__all__'

class PlatformSerializerPOST(ModelSerializer):
    class Meta:
        model = Platform
        fields = '__all__'
        read_only_fields = ['product']
        
class ProductImageSerializer(ModelSerializer):
    product = ProductSerializer(read_only=True)
    class Meta:
        model = ProductImage
        fields = '__all__'

class ProductImageSerializerPOST(ModelSerializer):
    class Meta:
        model = ProductImage
        fields = ['image', 'is_active']

class ProductClickSerializer(ModelSerializer):
    product = ProductSerializer(read_only=True)
    total_clicks = serializers.IntegerField(source='clicks.count', read_only=True)
    class Meta:
        model = ProductClick
        fields = ['id', 'product', 'clicked_on', 'total_clicks']

class PlatformSerializer(ModelSerializer):
    product = ProductSerializer(read_only=True)
    clicks = serializers.SerializerMethodField()
    class Meta:
        model = Platform
        fields = '__all__'
    def get_clicks(self, obj):
        return MarketplaceClick.objects.filter(platform__product=obj.product).count()

class MarketplaceClickSerializerPOST(ModelSerializer):
    class Meta:
        model = MarketplaceClick
        fields = ['id', 'clicked_on']
        read_only_fields = ['id', 'clicked_on']

class TagSerializer(serializers.ModelSerializer):
    class Meta:
        model = Tag
        fields = '__all__'


class BlogSerializer(serializers.ModelSerializer):
    class Meta:
        model = Blog
        fields = '__all__'


class TestimonialSerializer(serializers.ModelSerializer):
    class Meta:
        model = Testimonial
        fields = '__all__'

class NewsletterSubscriberSerializer(serializers.ModelSerializer):
    class Meta:
        model = NewsletterSubscriber
        fields = '__all__'
        
class ContactMessageSerializer(serializers.ModelSerializer):
    class Meta:
        model = ContactMessage
        fields = "__all__"
        read_only_fields = ["id", "submitted_on"]

    def validate(self, data):
        # At least one contact info must be provided
        if not data.get("email") and not data.get("mobile_number"):
            raise serializers.ValidationError(
                "Either email or mobile number is required."
            )
        return data

class MessagesToSubscribersSerializer(serializers.ModelSerializer):
    class Meta:
        model = MessagesToSubscribers
        fields = "__all__"
        

#-------------------------------------------Page Manager Serializers-------------------------------------------#

# ---------------- COLLECTION LIST ----------------
class CollectionListSerializer(ModelSerializer):
    class Meta:
        model = CollectionList
        fields = '__all__'


class CollectionListSerializerPOST(ModelSerializer):
    class Meta:
        model = CollectionList
        fields = '__all__'


# ---------------- BAND STORY ----------------
class BandStorySerializer(ModelSerializer):
    image_instance = CollectionListSerializer(read_only=True)

    class Meta:
        model = BandStory
        fields = '__all__'


class BandStorySerializerPOST(ModelSerializer):
    class Meta:
        model = BandStory
        fields = '__all__'

# ---------------- MARKETPLACE LINK ----------------
class MarketplaceLinkSerializer(ModelSerializer):
    class Meta:
        model = MarketplaceLink
        fields = '__all__'


class MarketplaceLinkSerializerPOST(ModelSerializer):
    class Meta:
        model = MarketplaceLink
        fields = '__all__'


# ---------------- INSTAGRAM GALLERY ----------------
class InstagramGallerySerializer(ModelSerializer):
    class Meta:
        model = Instagramgallery
        fields = '__all__'


class InstagramGallerySerializerPOST(ModelSerializer):
    class Meta:
        model = Instagramgallery
        fields = '__all__'
        read_only_fields = ['is_active','place']
        
        
class BlogLikesSerializer(serializers.ModelSerializer):
    class Meta:
        model = BlogLikes
        fields = ['id', 'blog', 'liked_on']


class LeadSerializer(serializers.ModelSerializer):
    class Meta:
        model = Lead
        fields = '__all__'
        read_only_fields = ["coupon"]
        
    def create(self, validated_data):
        source = validated_data.get("source")

        coupon_code = None

        if source:
            strategy = source.removeprefix("promotion_modal_")

            modal_setting = (
                ModalSetting.objects
                .filter(strategy=strategy)
                .select_related("coupon")
                .first()
            )

            if modal_setting and modal_setting.coupon:
                coupon_code = modal_setting.coupon.coupon_code

        validated_data["coupon"] = coupon_code

        return Lead.objects.create(**validated_data)

from rest_framework import serializers


class SpecialOfferPlatformSerializer(serializers.ModelSerializer):
    class Meta:
        model = Platform
        fields = ["name", "url", "price"]
from decimal import Decimal
class SpecialOfferProductSerializer(serializers.ModelSerializer):
    category = ProductCategorySerializer(read_only=True)

    platforms = serializers.SerializerMethodField()
    best_platform = serializers.SerializerMethodField()

    discounted_price = serializers.SerializerMethodField()
    discounted_price_store = serializers.SerializerMethodField()

    class Meta:
        model = Product
        fields = "__all__"

    def get_platforms(self, obj):
        platforms = obj.platforms.filter(is_active=True)

        return SpecialOfferPlatformSerializer(
            platforms,
            many=True
        ).data

    def get_best_platform(self, obj):
        platform = obj.platforms.filter(
            is_active=True
        ).order_by("price").first()

        if not platform:
            return None

        return {
            "name": platform.name,
            "url": platform.url,
            "price": platform.price
        }

    def get_discounted_price(self, obj):
        if not obj.is_special_offer:
            return None
    
        discount = obj.special_discount_percentage
    
        if discount is None or discount <= 0:
            return None
    
        best_platform = obj.platforms.filter(
            is_active=True
        ).order_by("price").first()
    
        if not best_platform:
            return None
    
        best_price = best_platform.price
    
        discount = Decimal(str(discount))
    
        discounted_price = best_price / (
            Decimal("1") - (discount / Decimal("100"))
        )
    
        return round(discounted_price, 2)
    
    
    def get_discounted_price_store(self, obj):
        if not obj.is_special_offer_store:
            return None
    
        discount = obj.special_discount_percentage_store
    
        if discount is None or discount <= 0:
            return None
    
        best_platform = obj.platforms.filter(
            is_active=True
        ).order_by("price").first()
    
        if not best_platform:
            return None
    
        best_price = best_platform.price
    
        discount = Decimal(str(discount))
    
        discounted_price_store = best_price / (
            Decimal("1") - (discount / Decimal("100"))
        )
    
        return round(discounted_price_store, 2)

class SpecialOfferUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = [
            "is_special_offer",
            "special_discount_percentage"
        ]

class SpecialOfferUpdateSerializerStore(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = [
            "is_special_offer_store",
            "special_discount_percentage_store"
        ]

class PromisesSerializer(serializers.ModelSerializer):
    class Meta:
        model = Promises
        fields = '__all__'
        
class HeroBannerPageSerializer(serializers.ModelSerializer):
    class Meta:
        model = Herobanner
        fields = '__all__'
        

class HeroBannerPageSerializerPOST(serializers.ModelSerializer):
    class Meta:
        model = Herobanner
        fields = '__all__'
        read_only_fields = ['place', 'is_active']


#----------------------About Us Management Serializers------------------------------------------------------

class DescriptionAboutUsSerializer(serializers.ModelSerializer):
    class Meta:
        model = DescriptionAboutUs
        fields = '__all__'
        
class TeamMemberSerializer(serializers.ModelSerializer):
    class Meta:
        model = TeamMember
        fields = '__all__'
        
class FactorsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Factors
        fields = '__all__'
    def validate(self, data):
        factors_value = data.get('factors_value')
        if len(factors_value)>6:
            raise serializers.ValidationError("The number of core values must not exceed 6.")
        return data
    
class LogoTextSerializer(serializers.ModelSerializer):
    class Meta:
        model = LogoText
        fields = '__all__'

class Satisfied_CustomerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Satisfied_Customer
        fields = '__all__'
class ContactInfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = ContactInfo
        fields = '__all__'
class SocialLinksSerializer(serializers.ModelSerializer):
    class Meta:
        model = SocialLinks
        fields = '__all__'
from rest_framework import serializers
from .models import Widget


class WidgetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Widget
        fields = ['id', 'name', 'data']

    def validate_name(self, value):
        if not value.strip():
            raise serializers.ValidationError("Name cannot be empty")
        return value

    def validate_data(self, value):
        # Must be list
        if not isinstance(value, list):
            raise serializers.ValidationError("Data must be a list")

        # Validate each item
        for item in value:
            if not isinstance(item, dict):
                raise serializers.ValidationError("Each item must be an object")

            if "label" not in item or "url" not in item:
                raise serializers.ValidationError(
                    "Each item must contain 'label' and 'url'"
                )

            if not item["label"] or not item["url"]:
                raise serializers.ValidationError(
                    "Label and URL cannot be empty"
                )

        return value
#----------------------Admin Management Serializers------------------------------------------------------
class RoleSerializer(serializers.ModelSerializer):
    permissions = serializers.PrimaryKeyRelatedField(
        queryset=Permission.objects.all(),
        many=True
    )

    class Meta:
        model = Role
        fields = ['id', 'name', 'description', 'permissions']
        

class PermissionSerializer(serializers.ModelSerializer):

    class Meta:
        model = Permission
        fields = ['id', 'module', 'action']

    def validate(self, data):
        # ðŸ”¥ Handle both POST and PATCH
        module = data.get('module', self.instance.module if self.instance else None)
        action = data.get('action', self.instance.action if self.instance else None)

        # ðŸ”¥ Check duplicate
        qs = Permission.objects.filter(module=module, action=action)

        if self.instance:
            qs = qs.exclude(id=self.instance.id)

        if qs.exists():
            raise serializers.ValidationError("Permission already exists")

        return data
    



#======================Puskar Serializers===================
#======================Puskar Serializers===================

from django.contrib.auth.models import User

# âœ… FIRST define AdminUserSimpleSerializer
class AdminUserSimpleSerializer(serializers.ModelSerializer):
    class Meta:
        model = AdminUser
        fields = ['id', 'username', 'email', 'is_super_admin']

# âœ… THEN define ChatSerializer that uses it
class ChatSerializer(serializers.ModelSerializer):
    sender_detail = AdminUserSimpleSerializer(source='sender', read_only=True)
    receiver_detail = AdminUserSimpleSerializer(source='receiver', read_only=True)

    class Meta:
        model = Chat
        fields = ['id', 'sender', 'receiver', 'sender_detail', 'receiver_detail', 'message', 'created_at', 'is_read']
        read_only_fields = ['sender', 'created_at', 'is_read']

class CouponSerializer(serializers.ModelSerializer):
    class Meta:
        model = Coupon
        fields = "__all__"

# Add this to admin_panel/serializers.py, near the ChatSerializer

class AdminUserSimpleSerializer(serializers.ModelSerializer):
    class Meta:
        model = AdminUser
        fields = ['id', 'username', 'email', 'is_super_admin']

# serializers.py
# serializers.py

class ModalSettingSerializer(serializers.ModelSerializer):
    coupon_code = serializers.CharField(source='coupon.coupon_code', read_only=True)
    offer_value = serializers.CharField(source='coupon.offer_value', read_only=True)  # ✅ ADD THIS
    coupon_id = serializers.PrimaryKeyRelatedField(source='coupon', queryset=Coupon.objects.all(), allow_null=True)

    class Meta:
        model = ModalSetting
        fields = ['strategy', 'is_enabled', 'trigger_type', 'delay_seconds',
                  'show_once_per_session', 'coupon_id', 'coupon_code', 'offer_value',"id"]  # add offer_value
        
class GroupChatMessageSerializer(serializers.ModelSerializer):
    sender_name = serializers.CharField(source='sender.username', read_only=True)
    sender_avatar = serializers.SerializerMethodField()

    class Meta:
        model = GroupChatMessage
        fields = ['id', 'sender', 'sender_name', 'sender_avatar', 'message', 'created_at']  # added sender_avatar

    def get_sender_avatar(self, obj):
        # Return the first letter of the username as avatar (or you can return an emoji/icon)
        return obj.sender.username[0].upper() if obj.sender.username else '?' 
        
        
        
class HeaderLogoSerializer(serializers.ModelSerializer):
    class Meta:
        model = HeaderLogo
        fields = ['id', 'image', 'link', 'order', 'is_active']
        
class ProductSEOSerializer(serializers.ModelSerializer):
    class Meta:
        model = product_seo
        fields = '__all__'

class PageSEOSerializer(serializers.ModelSerializer):
    class Meta:
        model = PageSEO
        fields = "__all__"


# ================= BLOG HERO =================

class BlogHeroSerializer(serializers.ModelSerializer):
    class Meta:
        model = BlogHero
        fields = '__all__'


# ================= ABOUT HERO =================

class AboutHeroSerializer(serializers.ModelSerializer):
    class Meta:
        model = AboutHero
        fields = '__all__'


# ================= TESTIMONIAL HERO =================

class TestimonialHeroSerializer(serializers.ModelSerializer):
    class Meta:
        model = TestimonialHero
        fields = '__all__'
        
        
        
class AboutCoreValueSerializer(serializers.ModelSerializer):
    class Meta:
        model = AboutCoreValue
        fields = '__all__'










# ================= New IMplementation ================= 


# ================= BLOG ANALYTICS SERIALIZERS =================

class BlogAnalyticsSerializer(serializers.ModelSerializer):
    avg_read_time = serializers.FloatField(read_only=True)
    class Meta:
        model = BlogAnalytics
        fields = ['date', 'total_views', 'unique_visitors', 'total_read_time_seconds', 
                  'bounce_count', 'scroll_depth_25', 'scroll_depth_50', 
                  'scroll_depth_75', 'scroll_depth_100', 'avg_read_time']

class BlogTrafficSourceSerializer(serializers.ModelSerializer):
    class Meta:
        model = BlogTrafficSource
        fields = '__all__'

class BlogProductClickSerializer(serializers.ModelSerializer):
    product_name = serializers.CharField(source='product.product_name', read_only=True)
    class Meta:
        model = BlogProductClick
        fields = ['product', 'product_name', 'click_count', 'date']

class BlogMarketplaceClickSerializer(serializers.ModelSerializer):
    platform_name = serializers.CharField(source='platform.name', read_only=True)
    class Meta:
        model = BlogMarketplaceClick
        fields = ['platform', 'platform_name', 'click_count', 'date']
        
        
        
        
        
        
        
        
        
        
# ================= SUBSCRIBER SEGMENTATION & TAGGING SERIALIZERS =================

class SubscriberTagSerializer(serializers.ModelSerializer):
    class Meta:
        model = SubscriberTag
        fields = '__all__'

class SubscriberSegmentSerializer(serializers.ModelSerializer):
    class Meta:
        model = SubscriberSegment
        fields = '__all__'

class SubscriberExtendedSerializer(serializers.ModelSerializer):
    tags = serializers.SerializerMethodField()
    segment_ids = serializers.SerializerMethodField()

    class Meta:
        model = NewsletterSubscriber
        fields = '__all__'

    def get_tags(self, obj):
        return [tag.tag.name for tag in obj.tags.all()]

    def get_segment_ids(self, obj):
        # compute segments dynamically (simplified – could be heavy)
        return []

# ================= EMAIL CAMPAIGN ANALYTICS SERIALIZERS =================

from django.db.models import Count
from django.db.models.functions import ExtractHour
from rest_framework import serializers


class EmailCampaignSerializer(serializers.ModelSerializer):
    open_rate = serializers.SerializerMethodField()
    click_rate = serializers.SerializerMethodField()
    unsubscribe_rate = serializers.SerializerMethodField()
    bounce_rate = serializers.SerializerMethodField()
    device_breakdown = serializers.SerializerMethodField()
    hourly_engagement = serializers.SerializerMethodField()
    recipient_tags = serializers.PrimaryKeyRelatedField(
        many=True,
        queryset=SubscriberTag.objects.all(),
        required=False
    )
    class Meta:
        model = EmailCampaign
        fields = "__all__"
        read_only_fields = [
            "status",
            "recipient_count",
            "sent_at",
            "total_opens",
            "unique_opens",
            "total_clicks",
            "unique_clicks",
            "unsubscribe_count",
            "bounce_count",
            "created_at",
            "updated_at",
        ]

    def get_open_rate(self, obj):
        if obj.recipient_count <= 0:
            return 0.0
        return round((obj.unique_opens / obj.recipient_count) * 100, 2)

    def get_click_rate(self, obj):
        if obj.recipient_count <= 0:
            return 0.0
        return round((obj.unique_clicks / obj.recipient_count) * 100, 2)

    def get_unsubscribe_rate(self, obj):
        if obj.recipient_count <= 0:
            return 0.0
        return round((obj.unsubscribe_count / obj.recipient_count) * 100, 2)

    def get_bounce_rate(self, obj):
        if obj.recipient_count <= 0:
            return 0.0
        return round((obj.bounce_count / obj.recipient_count) * 100, 2)

    def get_device_breakdown(self, obj):
        devices = (
            obj.events
            .filter(event_type="open")
            .values("device_type")
            .annotate(count=Count("id"))
        )

        return {
            device["device_type"] or "unknown": device["count"]
            for device in devices
        }

    def get_hourly_engagement(self, obj):
        hourly = (
            obj.events
            .filter(event_type="open")
            .annotate(hour=ExtractHour("created_at"))
            .values("hour")
            .annotate(count=Count("id"))
            .order_by("hour")
        )

        return {
            hour["hour"]: hour["count"]
            for hour in hourly
        }
        
from rest_framework import serializers
from .models import ModalSettingsUI


class ModalSettingsUISerializer(serializers.ModelSerializer):
    background_image = serializers.ImageField(
        required=False,
        allow_null=True
    )

    class Meta:
        model = ModalSettingsUI
        fields = "__all__"

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

        request = self.context.get("request")

        if instance.background_image:
            if request:
                data["background_image"] = request.build_absolute_uri(
                    instance.background_image.url
                )
            else:
                data["background_image"] = instance.background_image.url
        else:
            data["background_image"] = None

        return data

class PrivecySerializer(serializers.ModelSerializer):
    class Meta:
        model = privecy
        fields = "__all__"

class termsSerializer(serializers.ModelSerializer):
    class Meta:
        model = terms
        fields = "__all__"
        
from rest_framework import serializers
from .models import Watch_Buy


from rest_framework import serializers

from .models import Watch_Buy, Product


class WatchBuySerializer(serializers.ModelSerializer):

    # WRITE: frontend sends product_id
    product_id = serializers.PrimaryKeyRelatedField(
        source="product",
        queryset=Product.objects.all(),
        write_only=True,
    )

    # READ: return complete product information
    product = ProductSerializer(read_only=True)

    product_name = serializers.CharField(
        source="product.product_name",
        read_only=True,
    )

    platforms = serializers.SerializerMethodField()
    lowest_price_platform = serializers.SerializerMethodField()
    video_url = serializers.SerializerMethodField()

    class Meta:
        model = Watch_Buy

        fields = [
            "id",
            "product_id",
            "product",
            "product_name",
            "platforms",
            "lowest_price_platform",
            "video",
            "price",
            "location",
            "video_url",
            "updated_at",
        ]

        read_only_fields = [
            "id",
            "product",
            "product_name",
            "platforms",
            "lowest_price_platform",
            "video_url",
            "updated_at",
        ]

    def get_platforms(self, obj):
        platforms = obj.product.platforms.filter(
            is_active=True
        )

        return [
            {
                "name": platform.name,
                "url": platform.url,
                "price": platform.price,
                "rating": platform.rating,
                "is_active": platform.is_active,
            }
            for platform in platforms
        ]

    def get_lowest_price_platform(self, obj):
        platform = (
            obj.product.platforms
            .filter(is_active=True)
            .order_by("price")
            .first()
        )

        if not platform:
            return None

        return {
            "name": platform.name,
            "url": platform.url,
            "price": platform.price,
            "rating": platform.rating,
            "is_active": platform.is_active,
        }

    def get_video_url(self, obj):
        request = self.context.get("request")

        if obj.video:
            url = obj.video.url

            if request:
                return request.build_absolute_uri(url)

            return url

        return None
class OurJourneySerializer(serializers.ModelSerializer):

    logo_url = serializers.SerializerMethodField()

    class Meta:
        model = Our_Journey
        fields = [
            "id",
            "title",
            "subtitle",
            "logo",
            "logo_url",
        ]
        read_only_fields = [
            "id",
            "logo_url",
        ]

    def get_logo_url(self, obj):
        request = self.context.get("request")

        if obj.logo:
            url = obj.logo.url

            if request:
                return request.build_absolute_uri(url)

            return url

        return None
        
class EmailTrackingEventSerializer(serializers.ModelSerializer):
    subscriber = NewsletterSubscriberSerializer(read_only=True)
    class Meta:
        model = EmailTrackingEvent
        fields = '__all__'