from rest_framework import serializers
from .models import (
    CardTemplate, Card, CardBatch, CardUsageLog,
    ClothingAttributes, PropAttributes, SongAttributes,
    DanceAttributes, DecorationAttributes
)


class ClothingAttributesSerializer(serializers.ModelSerializer):
    class Meta:
        model = ClothingAttributes
        fields = [
            'style', 'size', 'color', 'season', 
            'material', 'fit_type', 'care_instructions'
        ]


class PropAttributesSerializer(serializers.ModelSerializer):
    class Meta:
        model = PropAttributes
        fields = [
            'prop_type', 'material', 'size', 'weight',
            'durability', 'usage_instructions'
        ]


class SongAttributesSerializer(serializers.ModelSerializer):
    class Meta:
        model = SongAttributes
        fields = [
            'genre', 'duration', 'bpm', 'composer',
            'lyricist', 'arrangement', 'audio_file', 'lyrics'
        ]


class DanceAttributesSerializer(serializers.ModelSerializer):
    class Meta:
        model = DanceAttributes
        fields = [
            'style', 'difficulty', 'duration', 'choreographer',
            'required_space', 'calories_burn', 'tutorial_video'
        ]


class DecorationAttributesSerializer(serializers.ModelSerializer):
    class Meta:
        model = DecorationAttributes
        fields = [
            'decoration_type', 'style', 'material', 'size',
            'placement', 'indoor_outdoor', 'installation_required', 'care_instructions'
        ]


class CardTemplateSerializer(serializers.ModelSerializer):
    category_display = serializers.SerializerMethodField()
    rarity_display = serializers.SerializerMethodField()
    card_type_display = serializers.SerializerMethodField()
    status_display = serializers.SerializerMethodField()
    image_url = serializers.URLField(source='image', required=False, allow_blank=True)

    # 新增：所有类别专有属性的write_only字段
    clothing_attributes = ClothingAttributesSerializer(write_only=True, required=False)
    prop_attributes = PropAttributesSerializer(write_only=True, required=False)
    song_attributes = SongAttributesSerializer(write_only=True, required=False)
    dance_attributes = DanceAttributesSerializer(write_only=True, required=False)
    decoration_attributes = DecorationAttributesSerializer(write_only=True, required=False)

    class Meta:
        model = CardTemplate
        fields = [
            'id', 'name', 'category', 'category_display', 'description', 
            'card_type', 'card_type_display', 'rarity', 'rarity_display',
            'image', 'image_url', 'model_url', 'model_version',
            'status', 'status_display', 'published_at', 'price',
            'created_at', 'updated_at',
            # 新增
            'clothing_attributes', 'prop_attributes', 'song_attributes', 'dance_attributes', 'decoration_attributes',
        ]
        read_only_fields = ['created_at', 'updated_at', 'published_at']
    
    def create(self, validated_data):
        # 把所有 *_attributes 字段pop掉，只留主表字段
        # 属性的创建由 View 层的 create 方法负责
        validated_data.pop('clothing_attributes', None)
        validated_data.pop('prop_attributes', None)
        validated_data.pop('song_attributes', None)
        validated_data.pop('dance_attributes', None)
        validated_data.pop('decoration_attributes', None)
        return super().create(validated_data)
    
    def get_category_display(self, obj):
        return dict(CardTemplate.CATEGORY_CHOICES).get(obj.category)
    
    def get_rarity_display(self, obj):
        return obj.get_rarity_display()
    
    def get_card_type_display(self, obj):
        return obj.get_card_type_display()
    
    def get_status_display(self, obj):
        return obj.get_status_display()
    
    def to_representation(self, instance):
        representation = super().to_representation(instance)
        # 添加类别专有属性
        try:
            if instance.category == 'clothing' and hasattr(instance, 'clothing_attrs'):
                representation['attributes'] = ClothingAttributesSerializer(instance.clothing_attrs).data
            elif instance.category == 'prop' and hasattr(instance, 'prop_attrs'):
                representation['attributes'] = PropAttributesSerializer(instance.prop_attrs).data
            elif instance.category == 'song' and hasattr(instance, 'song_attrs'):
                representation['attributes'] = SongAttributesSerializer(instance.song_attrs).data
            elif instance.category == 'dance' and hasattr(instance, 'dance_attrs'):
                representation['attributes'] = DanceAttributesSerializer(instance.dance_attrs).data
            elif instance.category == 'decoration' and hasattr(instance, 'decoration_attrs'):
                representation['attributes'] = DecorationAttributesSerializer(instance.decoration_attrs).data
        except Exception:
            representation['attributes'] = None
        return representation

    def update(self, instance, validated_data):
        # 取出专属属性数据
        clothing_data = validated_data.pop('clothing_attributes', None)
        prop_data = validated_data.pop('prop_attributes', None)
        song_data = validated_data.pop('song_attributes', None)
        dance_data = validated_data.pop('dance_attributes', None)
        decoration_data = validated_data.pop('decoration_attributes', None)

        # 更新主表
        instance = super().update(instance, validated_data)

        # 更新专属属性
        if clothing_data is not None and hasattr(instance, 'clothing_attrs'):
            for k, v in clothing_data.items():
                setattr(instance.clothing_attrs, k, v)
            instance.clothing_attrs.save()
        if prop_data is not None and hasattr(instance, 'prop_attrs'):
            for k, v in prop_data.items():
                setattr(instance.prop_attrs, k, v)
            instance.prop_attrs.save()
        if song_data is not None and hasattr(instance, 'song_attrs'):
            for k, v in song_data.items():
                setattr(instance.song_attrs, k, v)
            instance.song_attrs.save()
        if dance_data is not None and hasattr(instance, 'dance_attrs'):
            for k, v in dance_data.items():
                setattr(instance.dance_attrs, k, v)
            instance.dance_attrs.save()
        if decoration_data is not None and hasattr(instance, 'decoration_attrs'):
            for k, v in decoration_data.items():
                setattr(instance.decoration_attrs, k, v)
            instance.decoration_attrs.save()

        return instance


class CardTemplateDetailSerializer(CardTemplateSerializer):
    """Detailed template serializer with related batches and cards count"""
    batches_count = serializers.SerializerMethodField()
    active_cards_count = serializers.SerializerMethodField()
    
    class Meta(CardTemplateSerializer.Meta):
        fields = CardTemplateSerializer.Meta.fields + ['batches_count', 'active_cards_count']
    
    def get_batches_count(self, obj):
        return obj.batches.count()
    
    def get_active_cards_count(self, obj):
        # 只计算激活状态的卡片数量
        return obj.cards.filter(status='active').count()
    
    def to_representation(self, instance):
        representation = super().to_representation(instance)
        
        # 添加类别专有属性
        try:
            if instance.category == 'clothing' and hasattr(instance, 'clothing_attrs'):
                representation['attributes'] = ClothingAttributesSerializer(instance.clothing_attrs).data
            elif instance.category == 'prop' and hasattr(instance, 'prop_attrs'):
                representation['attributes'] = PropAttributesSerializer(instance.prop_attrs).data
            elif instance.category == 'song' and hasattr(instance, 'song_attrs'):
                representation['attributes'] = SongAttributesSerializer(instance.song_attrs).data
            elif instance.category == 'dance' and hasattr(instance, 'dance_attrs'):
                representation['attributes'] = DanceAttributesSerializer(instance.dance_attrs).data
            elif instance.category == 'decoration' and hasattr(instance, 'decoration_attrs'):
                representation['attributes'] = DecorationAttributesSerializer(instance.decoration_attrs).data
        except Exception as e:
            # 处理相关属性不存在的情况
            representation['attributes'] = None

        return representation


class CardSerializer(serializers.ModelSerializer):
    category_display = serializers.SerializerMethodField()
    template_name = serializers.SerializerMethodField()
    status_display = serializers.SerializerMethodField()
    image_url = serializers.SerializerMethodField()
    
    class Meta:
        model = Card
        fields = [
            'id', 'unique_id', 'template', 'template_name', 'name', 
            'category', 'category_display', 'description', 'batch',
            'image', 'image_url', 'price', 'status', 'status_display',
            'user', 'used_at', 'manufactured', 'manufactured_at', 
            'created_at', 'updated_at'
        ]
        read_only_fields = [
            'created_at', 'updated_at', 'used_at', 
            'manufactured_at', 'image_url'
        ]
    
    def get_category_display(self, obj):
        return dict(CardTemplate.CATEGORY_CHOICES).get(obj.category)
    
    def get_template_name(self, obj):
        return obj.template.name if obj.template else None
    
    def get_status_display(self, obj):
        return obj.get_status_display()
    
    def get_image_url(self, obj):
        if obj.image:
            return obj.image.url
        # 如果卡片没有图片，使用模板的图片（模板image现在是URLField字符串）
        elif obj.template and obj.template.image:
            return obj.template.image
        return None


class CardDetailSerializer(CardSerializer):
    """Detailed card serializer with usage logs"""
    usage_logs = serializers.SerializerMethodField()
    template_details = serializers.SerializerMethodField()
    
    class Meta(CardSerializer.Meta):
        fields = CardSerializer.Meta.fields + ['usage_logs', 'template_details']
    
    def get_usage_logs(self, obj):
        # Only return the 10 most recent logs
        logs = obj.usage_logs.all().order_by('-created_at')[:10]
        return CardUsageLogSerializer(logs, many=True).data
    
    def get_template_details(self, obj):
        if obj.template:
            return {
                'rarity': obj.template.rarity,
                'rarity_display': obj.template.get_rarity_display(),
                'card_type': obj.template.card_type,
                'card_type_display': obj.template.get_card_type_display(),
                'model_url': obj.template.model_url,
                'model_version': obj.template.model_version,
            }
        return None


class CardBatchSerializer(serializers.ModelSerializer):
    category_display = serializers.SerializerMethodField()
    template_name = serializers.SerializerMethodField()
    status_display = serializers.SerializerMethodField()
    excel_file_url = serializers.SerializerMethodField()
    
    class Meta:
        model = CardBatch
        fields = [
            'id', 'batch_number', 'template', 'template_name', 
            'category', 'category_display', 'quantity', 'description',
            'status', 'status_display', 'exported', 'exported_at', 
            'excel_file', 'excel_file_url', 'sent_to_production', 
            'production_date', 'published', 'published_at', 
            'created_at', 'updated_at',
            'start_id', 'end_id'
        ]
        read_only_fields = [
            'created_at', 'updated_at', 'exported_at', 'excel_file', 
            'excel_file_url', 'production_date', 'published_at', 'quantity',
            'start_id', 'end_id'
        ]
    
    def get_category_display(self, obj):
        return dict(CardTemplate.CATEGORY_CHOICES).get(obj.category)
    
    def get_template_name(self, obj):
        return obj.template.name if obj.template else None
    
    def get_status_display(self, obj):
        return obj.get_status_display()
    
    def get_excel_file_url(self, obj):
        if obj.excel_file:
            return obj.excel_file.url
        return None


class CardUsageLogSerializer(serializers.ModelSerializer):
    action_display = serializers.SerializerMethodField()
    user_display = serializers.SerializerMethodField()
    
    class Meta:
        model = CardUsageLog
        fields = [
            'id', 'card', 'user', 'user_display', 'action', 'action_display',
            'details', 'old_status', 'new_status', 'created_at', 'ip_address'
        ]
        read_only_fields = fields
    
    def get_action_display(self, obj):
        return obj.get_action_display() if hasattr(obj, 'get_action_display') else obj.action
    
    def get_user_display(self, obj):
        if obj.user:
            return obj.user.username
        return None


class CardScanSerializer(serializers.Serializer):
    """Serializer for scanning a card with NFC"""
    unique_id = serializers.CharField(max_length=100)
    
    def validate(self, data):
        """
        Check that at least one identifier is provided.
        """
        if not any([data.get('unique_id')]):
            raise serializers.ValidationError("unique_id must be provided.")
        return data


class CardUseSerializer(serializers.Serializer):
    """Serializer for using a card"""
    unique_id = serializers.CharField(max_length=100)


class CardBatchGenerateSerializer(serializers.Serializer):
    """Serializer for generating card batches"""
    template = serializers.PrimaryKeyRelatedField(queryset=CardTemplate.objects.all())
    quantity = serializers.IntegerField(min_value=1, max_value=10000)
    description = serializers.CharField(required=False, allow_blank=True)


class CardTemplatePublishSerializer(serializers.Serializer):
    """Serializer for publishing a card template"""
    template_id = serializers.IntegerField()


class CardBatchPublishSerializer(serializers.Serializer):
    """Serializer for publishing a card batch"""
    batch_id = serializers.IntegerField()


class CardBatchManufactureSerializer(serializers.Serializer):
    """Serializer for marking a card batch as manufactured"""
    batch_id = serializers.IntegerField()


# 类别特定的属性序列化器
class CategoryTemplateSerializer(CardTemplateDetailSerializer):
    """Base class for category-specific template serializers"""
    
    def to_representation(self, instance):
        representation = super().to_representation(instance)
        
        # Add category-specific attributes if they exist
        try:
            if instance.category == 'clothing' and hasattr(instance, 'clothing_attrs'):
                representation['attributes'] = ClothingAttributesSerializer(instance.clothing_attrs).data
            elif instance.category == 'prop' and hasattr(instance, 'prop_attrs'):
                representation['attributes'] = PropAttributesSerializer(instance.prop_attrs).data
            elif instance.category == 'song' and hasattr(instance, 'song_attrs'):
                representation['attributes'] = SongAttributesSerializer(instance.song_attrs).data
            elif instance.category == 'dance' and hasattr(instance, 'dance_attrs'):
                representation['attributes'] = DanceAttributesSerializer(instance.dance_attrs).data
            elif instance.category == 'decoration' and hasattr(instance, 'decoration_attrs'):
                representation['attributes'] = DecorationAttributesSerializer(instance.decoration_attrs).data
        except Exception as e:
            # Handle the case where related attributes don't exist
            representation['attributes'] = None

        return representation


class MobileProductSerializer(serializers.ModelSerializer):
    """手机端通用产品序列化器 - 适用于所有分类"""
    category_display = serializers.SerializerMethodField()
    card_type_display = serializers.SerializerMethodField()
    rarity_display = serializers.SerializerMethodField()
    status_display = serializers.SerializerMethodField()
    image_url = serializers.URLField(source='image', read_only=True)
    active_cards_count = serializers.SerializerMethodField()
    attributes = serializers.SerializerMethodField()

    class Meta:
        model = CardTemplate
        fields = [
            'id', 'name', 'description',
            'category', 'category_display',
            'card_type', 'card_type_display',
            'rarity', 'rarity_display',
            'image_url',
            'status', 'status_display',
            'published_at',
            'active_cards_count',
            'attributes',
        ]

    def get_category_display(self, obj):
        return obj.get_category_display()

    def get_card_type_display(self, obj):
        return obj.get_card_type_display()

    def get_rarity_display(self, obj):
        return obj.get_rarity_display()

    def get_status_display(self, obj):
        return obj.get_status_display()

    def get_active_cards_count(self, obj):
        return obj.cards.filter(status='active').count()

    def get_attributes(self, obj):
        try:
            attr_map = {
                'clothing': ('clothing_attrs', ClothingAttributesSerializer),
                'prop': ('prop_attrs', PropAttributesSerializer),
                'song': ('song_attrs', SongAttributesSerializer),
                'dance': ('dance_attrs', DanceAttributesSerializer),
                'decoration': ('decoration_attrs', DecorationAttributesSerializer),
            }
            if obj.category in attr_map:
                attr_name, serializer_cls = attr_map[obj.category]
                if hasattr(obj, attr_name):
                    return serializer_cls(getattr(obj, attr_name)).data
        except Exception:
            pass
        return None



# 带有专有属性的卡牌详情序列化器
class CategoryCardDetailSerializer(CardDetailSerializer):
    """Card detail serializer with category-specific attributes"""
    
    def to_representation(self, instance):
        representation = super().to_representation(instance)
        
        # If card has a template, get its specific attributes
        if instance.template:
            template = instance.template
            try:
                # Add category-specific attributes if they exist
                if template.category == 'clothing' and hasattr(template, 'clothing_attrs'):
                    representation['attributes'] = ClothingAttributesSerializer(template.clothing_attrs).data
                elif template.category == 'prop' and hasattr(template, 'prop_attrs'):
                    representation['attributes'] = PropAttributesSerializer(template.prop_attrs).data
                elif template.category == 'song' and hasattr(template, 'song_attrs'):
                    representation['attributes'] = SongAttributesSerializer(template.song_attrs).data
                elif template.category == 'dance' and hasattr(template, 'dance_attrs'):
                    representation['attributes'] = DanceAttributesSerializer(template.dance_attrs).data
                elif template.category == 'decoration' and hasattr(template, 'decoration_attrs'):
                    representation['attributes'] = DecorationAttributesSerializer(template.decoration_attrs).data
            except Exception as e:
                # Handle the case where related attributes don't exist
                representation['attributes'] = None
        
        return representation 