














# # ==================== serializers.py ====================
# from rest_framework import serializers
# from .models import Product, ProductType, ProductAttribute, AttributePossibleValue


# class ProductInputSerializer(serializers.Serializer):
#     """Serializer for individual product input."""
#     product_id = serializers.CharField(required=False, allow_blank=True, allow_null=True)
#     title = serializers.CharField(required=False, allow_blank=True, allow_null=True)
#     short_desc = serializers.CharField(required=False, allow_blank=True, allow_null=True)
#     long_desc = serializers.CharField(required=False, allow_blank=True, allow_null=True)
#     image_url = serializers.URLField(required=False, allow_blank=True, allow_null=True)


# class MandatoryAttrsField(serializers.DictField):
#     """Custom DictField to validate mandatory_attrs structure."""
#     child = serializers.ListField(child=serializers.CharField())


# class ProductBatchInputSerializer(serializers.Serializer):
#     """Serializer for an individual product input within the batch request."""
#     item_id = serializers.CharField(required=True)
#     mandatory_attrs = MandatoryAttrsField(
#         required=True,
#         help_text="A dictionary of attribute names and their possible values."
#     )


# class SingleProductRequestSerializer(serializers.Serializer):
#     """Serializer for single product extraction request."""
#     item_id = serializers.CharField(required=True)
#     mandatory_attrs = serializers.DictField(
#         child=serializers.ListField(child=serializers.CharField()),
#         required=True
#     )
#     model = serializers.CharField(required=False, default="llama-3.1-8b-instant")
#     extract_additional = serializers.BooleanField(required=False, default=True)
#     process_image = serializers.BooleanField(required=False, default=True)
#     multiple = serializers.ListField(
#         child=serializers.CharField(),
#         required=False,
#         default=list,
#         help_text="List of attribute names that can have multiple values"
#     )
#     threshold_abs = serializers.FloatField(default=0.65, required=False)
#     margin = serializers.FloatField(default=0.15, required=False)
#     use_dynamic_thresholds = serializers.BooleanField(default=True, required=False)
#     use_adaptive_margin = serializers.BooleanField(default=True, required=False)
#     use_semantic_clustering = serializers.BooleanField(default=True, required=False)

#     def validate_model(self, value):
#         from django.conf import settings
#         if value not in settings.SUPPORTED_MODELS:
#             raise serializers.ValidationError(
#                 f"Model must be one of {settings.SUPPORTED_MODELS}"
#             )
#         return value


# class BatchProductRequestSerializer(serializers.Serializer):
#     """Serializer for batch product extraction request (with item-specific attributes)."""
#     products = serializers.ListField(
#         child=ProductBatchInputSerializer(),
#         required=True,
#         min_length=1
#     )
#     model = serializers.CharField(required=False, default="llama-3.1-8b-instant")
#     extract_additional = serializers.BooleanField(required=False, default=True)
#     process_image = serializers.BooleanField(required=False, default=True)
#     multiple = serializers.ListField(
#         child=serializers.CharField(),
#         required=False,
#         default=list,
#         help_text="List of attribute names that can have multiple values"
#     )
#     threshold_abs = serializers.FloatField(default=0.65, required=False)
#     margin = serializers.FloatField(default=0.15, required=False)
#     use_dynamic_thresholds = serializers.BooleanField(default=True, required=False)
#     use_adaptive_margin = serializers.BooleanField(default=True, required=False)
#     use_semantic_clustering = serializers.BooleanField(default=True, required=False)
    
#     def validate_model(self, value):
#         from django.conf import settings
#         if value not in settings.SUPPORTED_MODELS:
#             raise serializers.ValidationError(
#                 f"Model must be one of {settings.SUPPORTED_MODELS}"
#             )
#         return value
    
#     def validate_products(self, value):
#         from django.conf import settings
#         max_size = getattr(settings, 'MAX_BATCH_SIZE', 100)
#         if len(value) > max_size:
#             raise serializers.ValidationError(
#                 f"Batch size cannot exceed {max_size} products"
#             )
#         return value


# class OCRResultSerializer(serializers.Serializer):
#     """Serializer for OCR results."""
#     detected_text = serializers.ListField(child=serializers.DictField())
#     extracted_attributes = serializers.DictField()


# class ProductAttributeResultSerializer(serializers.Serializer):
#     """Serializer for individual product extraction result."""
#     product_id = serializers.CharField(required=False)
#     mandatory = serializers.DictField()
#     additional = serializers.DictField(required=False)
#     ocr_results = OCRResultSerializer(required=False)
#     error = serializers.CharField(required=False)
#     raw_output = serializers.CharField(required=False)


# class BatchProductResponseSerializer(serializers.Serializer):
#     """Serializer for batch extraction response."""
#     results = serializers.ListField(child=ProductAttributeResultSerializer())
#     total_products = serializers.IntegerField()
#     successful = serializers.IntegerField()
#     failed = serializers.IntegerField()


# class ProductSerializer(serializers.ModelSerializer):
#     """Serializer for Product model with product type details."""
#     product_type_details = serializers.SerializerMethodField()
    
#     class Meta:
#         model = Product
#         fields = [
#             'id',
#             'item_id',
#             'product_name',
#             'product_long_description',
#             'product_short_description',
#             'product_type',
#             'image_path',
#             'image',
#             'product_type_details',
#         ]

#     def get_product_type_details(self, obj):
#         """Fetch ProductType object and its attributes for this product."""
#         try:
#             product_type = ProductType.objects.get(name=obj.product_type)
#         except ProductType.DoesNotExist:
#             return []

#         # Serialize its attributes
#         attributes = ProductAttribute.objects.filter(product_type=product_type)
#         return [
#             {
#                 "attribute_name": attr.name,
#                 "is_mandatory": "Yes" if attr.is_mandatory else "No",
#                 "possible_values": [pv.value for pv in attr.possible_values.all()]
#             }
#             for attr in attributes
#         ]


# class AttributePossibleValueSerializer(serializers.ModelSerializer):
#     """Serializer for AttributePossibleValue model."""
#     class Meta:
#         model = AttributePossibleValue
#         fields = ['value']


# class ProductAttributeSerializer(serializers.ModelSerializer):
#     """Serializer for ProductAttribute model with possible values."""
#     possible_values = AttributePossibleValueSerializer(many=True, read_only=True)
    
#     class Meta:
#         model = ProductAttribute
#         fields = ['name', 'is_mandatory', 'possible_values']


# class ProductTypeSerializer(serializers.ModelSerializer):
#     """Serializer for ProductType model with attributes."""
#     attributes = ProductAttributeSerializer(many=True, read_only=True)
    
#     class Meta:
#         model = ProductType
#         fields = ['name', 'attributes']







        



# ==================== Updated serializers.py ====================
from rest_framework import serializers
from .models import Product, ProductType, ProductAttribute, AttributePossibleValue


class ProductInputSerializer(serializers.Serializer):
    """Serializer for individual product input."""
    product_id = serializers.CharField(required=False, allow_blank=True, allow_null=True)
    title = serializers.CharField(required=False, allow_blank=True, allow_null=True)
    short_desc = serializers.CharField(required=False, allow_blank=True, allow_null=True)
    long_desc = serializers.CharField(required=False, allow_blank=True, allow_null=True)
    image_url = serializers.URLField(required=False, allow_blank=True, allow_null=True)


class MandatoryAttrsField(serializers.DictField):
    """Custom DictField to validate mandatory_attrs structure."""
    child = serializers.ListField(child=serializers.CharField())


class ProductBatchInputSerializer(serializers.Serializer):
    """Serializer for an individual product input within the batch request."""
    item_id = serializers.CharField(required=True)
    mandatory_attrs = MandatoryAttrsField(
        required=True,
        help_text="A dictionary of attribute names and their possible values."
    )


class SingleProductRequestSerializer(serializers.Serializer):
    """Serializer for single product extraction request."""
    item_id = serializers.CharField(required=True)
    mandatory_attrs = serializers.DictField(
        child=serializers.ListField(child=serializers.CharField()),
        required=True
    )
    model = serializers.CharField(required=False, default="llama-3.1-8b-instant")
    extract_additional = serializers.BooleanField(required=False, default=True)
    process_image = serializers.BooleanField(required=False, default=True)
    multiple = serializers.ListField(
        child=serializers.CharField(),
        required=False,
        default=list,
        help_text="List of attribute names that can have multiple values"
    )
    threshold_abs = serializers.FloatField(default=0.65, required=False)
    margin = serializers.FloatField(default=0.15, required=False)
    use_dynamic_thresholds = serializers.BooleanField(default=True, required=False)
    use_adaptive_margin = serializers.BooleanField(default=True, required=False)
    use_semantic_clustering = serializers.BooleanField(default=True, required=False)

    def validate_model(self, value):
        from django.conf import settings
        if value not in settings.SUPPORTED_MODELS:
            raise serializers.ValidationError(
                f"Model must be one of {settings.SUPPORTED_MODELS}"
            )
        return value


class BatchProductRequestSerializer(serializers.Serializer):
    """Serializer for batch product extraction request (with item-specific attributes)."""
    products = serializers.ListField(
        child=ProductBatchInputSerializer(),
        required=True,
        min_length=1
    )
    model = serializers.CharField(required=False, default="llama-3.1-8b-instant")
    extract_additional = serializers.BooleanField(required=False, default=True)
    process_image = serializers.BooleanField(required=False, default=True)
    multiple = serializers.ListField(
        child=serializers.CharField(),
        required=False,
        default=list,
        help_text="List of attribute names that can have multiple values"
    )
    threshold_abs = serializers.FloatField(default=0.65, required=False)
    margin = serializers.FloatField(default=0.15, required=False)
    use_dynamic_thresholds = serializers.BooleanField(default=True, required=False)
    use_adaptive_margin = serializers.BooleanField(default=True, required=False)
    use_semantic_clustering = serializers.BooleanField(default=True, required=False)
    
    def validate_model(self, value):
        from django.conf import settings
        if value not in settings.SUPPORTED_MODELS:
            raise serializers.ValidationError(
                f"Model must be one of {settings.SUPPORTED_MODELS}"
            )
        return value
    
    def validate_products(self, value):
        from django.conf import settings
        max_size = getattr(settings, 'MAX_BATCH_SIZE', 100)
        if len(value) > max_size:
            raise serializers.ValidationError(
                f"Batch size cannot exceed {max_size} products"
            )
        return value


class OCRResultSerializer(serializers.Serializer):
    """Serializer for OCR results."""
    detected_text = serializers.ListField(child=serializers.DictField())
    extracted_attributes = serializers.DictField()


class VisualAttributeDetailSerializer(serializers.Serializer):
    """Serializer for detailed visual attribute predictions."""
    attribute = serializers.CharField()
    predictions = serializers.ListField(child=serializers.DictField())


class VisualResultSerializer(serializers.Serializer):
    """Serializer for visual processing results."""
    visual_attributes = serializers.DictField(
        help_text="Extracted visual attributes like color, pattern, style, etc."
    )
    detailed_predictions = serializers.DictField(
        child=VisualAttributeDetailSerializer(),
        required=False,
        help_text="Detailed predictions with confidence scores for each attribute"
    )
    error = serializers.CharField(required=False)


class ProductAttributeResultSerializer(serializers.Serializer):
    """Serializer for individual product extraction result."""
    product_id = serializers.CharField(required=False)
    mandatory = serializers.DictField()
    additional = serializers.DictField(required=False)
    ocr_results = OCRResultSerializer(required=False)
    visual_results = VisualResultSerializer(required=False)
    error = serializers.CharField(required=False)
    raw_output = serializers.CharField(required=False)


class BatchProductResponseSerializer(serializers.Serializer):
    """Serializer for batch extraction response."""
    results = serializers.ListField(child=ProductAttributeResultSerializer())
    total_products = serializers.IntegerField()
    successful = serializers.IntegerField()
    failed = serializers.IntegerField()


class ProductSerializer(serializers.ModelSerializer):
    """Serializer for Product model with product type details."""
    product_type_details = serializers.SerializerMethodField()
    
    class Meta:
        model = Product
        fields = [
            'id',
            'item_id',
            'product_name',
            'product_long_description',
            'product_short_description',
            'product_type',
            'image_path',
            'image',
            'product_type_details',
        ]

    def get_product_type_details(self, obj):
        """Fetch ProductType object and its attributes for this product."""
        try:
            product_type = ProductType.objects.get(name=obj.product_type)
        except ProductType.DoesNotExist:
            return []

        # Serialize its attributes
        attributes = ProductAttribute.objects.filter(product_type=product_type)
        return [
            {
                "attribute_name": attr.name,
                "is_mandatory": "Yes" if attr.is_mandatory else "No",
                "possible_values": [pv.value for pv in attr.possible_values.all()]
            }
            for attr in attributes
        ]


class AttributePossibleValueSerializer(serializers.ModelSerializer):
    """Serializer for AttributePossibleValue model."""
    class Meta:
        model = AttributePossibleValue
        fields = ['value']


class ProductAttributeSerializer(serializers.ModelSerializer):
    """Serializer for ProductAttribute model with possible values."""
    possible_values = AttributePossibleValueSerializer(many=True, read_only=True)
    
    class Meta:
        model = ProductAttribute
        fields = ['name', 'is_mandatory', 'possible_values']


class ProductTypeSerializer(serializers.ModelSerializer):
    """Serializer for ProductType model with attributes."""
    attributes = ProductAttributeSerializer(many=True, read_only=True)
    
    class Meta:
        model = ProductType
        fields = ['name', 'attributes']