from rest_framework import serializers
from django.utils import timezone
from decimal import Decimal
from .models import Restaurant, MenuItem, Booking, BookingItem, Table, AaharConfig, AaharOrderSync, Offer, Combo, ComboItem, MenuCategory, ItemVariant, ItemFeature
from .utils import calculate_distance, check_delivery_availability, estimate_delivery_time, calculate_delivery_charge


def effective_image_url(obj, request):
    """Menu item image to display: HotelFinder upload takes precedence over the Aahar-synced image."""
    img = obj.custom_image if obj.custom_image else obj.image
    if not img:
        return None
    name = str(img)
    if name.startswith(('http://', 'https://')):
        return name
    return request.build_absolute_uri(img.url) if request else img.url


class RestaurantSerializer(serializers.ModelSerializer):
    """Full restaurant serializer with all details"""
    menu_items_count = serializers.SerializerMethodField()
    aahar_service_id = serializers.SerializerMethodField()
    
    class Meta:
        model = Restaurant
        fields = '__all__'
        read_only_fields = ['created_at', 'updated_at']
    
    def get_menu_items_count(self, obj):
        return obj.menu_items.filter(is_available=True).count()

    def get_aahar_service_id(self, obj):
        try:
            return obj.aahar_config.aahar_restaurant_service_id
        except AttributeError:
            return None



class RestaurantListSerializer(serializers.ModelSerializer):
    """Optimized serializer for list views"""
    class Meta:
        model = Restaurant
        fields = ['id', 'name', 'location', 'cuisine', 'rating', 'image', 
                  'is_delivery_available', 'is_dine_in_available', 'is_takeaway_available',
                  'average_cost_for_two', 'delivery_radius_km', 'is_active',
                  'latitude', 'longitude', 'owner']


class MenuCategorySerializer(serializers.ModelSerializer):
    """Menu category serializer"""
    parent_details = serializers.SerializerMethodField()

    class Meta:
        model = MenuCategory
        fields = '__all__'
        read_only_fields = ['created_at', 'restaurant']

    def get_parent_details(self, obj):
        if obj.parent:
            return {
                'id': obj.parent.id,
                'name': obj.parent.name,
                'icon': obj.parent.icon
            }
        return None


class ItemVariantSerializer(serializers.ModelSerializer):
    """Item variant serializer"""
    class Meta:
        model = ItemVariant
        fields = '__all__'
        read_only_fields = ['menu_item']


class ItemFeatureSerializer(serializers.ModelSerializer):
    """Item feature serializer"""
    class Meta:
        model = ItemFeature
        fields = '__all__'
        read_only_fields = ['menu_item']


class MenuItemSerializer(serializers.ModelSerializer):
    """Menu item serializer"""
    image = serializers.SerializerMethodField()
    variants = ItemVariantSerializer(many=True, read_only=True)
    features = ItemFeatureSerializer(many=True, read_only=True)
    custom_category_details = MenuCategorySerializer(source='custom_category', read_only=True)

    class Meta:
        model = MenuItem
        fields = '__all__'
        read_only_fields = ['created_at', 'restaurant']

    def get_image(self, obj):
        return effective_image_url(obj, self.context.get('request'))


class RestaurantSummarySerializer(serializers.ModelSerializer):
    """Simplified restaurant serializer for embedding in menu items"""
    class Meta:
        model = Restaurant
        fields = ['id', 'name', 'location', 'rating', 'image', 
                  'is_delivery_available', 'is_dine_in_available', 'is_takeaway_available',
                  'delivery_radius_km', 'max_party_size']


class GlobalMenuItemSerializer(serializers.ModelSerializer):
    """Menu item serializer with embedded restaurant details"""
    restaurant_details = RestaurantSummarySerializer(source='restaurant', read_only=True)
    image = serializers.SerializerMethodField()
    variants = ItemVariantSerializer(many=True, read_only=True)
    features = ItemFeatureSerializer(many=True, read_only=True)
    custom_category_details = MenuCategorySerializer(source='custom_category', read_only=True)

    class Meta:
        model = MenuItem
        fields = ['id', 'name', 'description', 'price', 'category', 'custom_category', 'custom_category_details', 'image', 
                  'is_vegetarian', 'is_vegan', 'spice_level', 'preparation_time_minutes', 'show_detail_screen',
                  'restaurant', 'restaurant_details', 'variants', 'features']

    def get_image(self, obj):
        """HotelFinder upload preferred; else the Aahar-synced image (absolute URLs returned as-is)."""
        return effective_image_url(obj, self.context.get('request'))



class TableSerializer(serializers.ModelSerializer):
    """Serializer for restaurant tables"""
    is_occupied = serializers.SerializerMethodField()
    current_booking = serializers.SerializerMethodField()

    class Meta:
        model = Table
        fields = '__all__'
        read_only_fields = ['created_at']

    def get_is_occupied(self, obj):
        # Check for active bookings
        # Statuses that indicate table is occupied: CONFIRMED, PREPARING, READY
        # PENDING might strictly not be occupied yet, but reserved.
        return obj.bookings.filter(
            status__in=['CONFIRMED', 'PREPARING', 'READY'],
            booking_type='DINE_IN'
        ).exists()

    def get_current_booking(self, obj):
        booking = obj.bookings.filter(
            status__in=['CONFIRMED', 'PREPARING', 'READY'],
            booking_type='DINE_IN'
        ).first()
        if booking:
            return {
                'id': booking.id,
                'customer_name': booking.customer_name,
                'party_size': booking.party_size,
                'status': booking.status
            }
        return None


class BookingItemSerializer(serializers.ModelSerializer):
    """Booking/Order item serializer"""
    menu_item_name = serializers.CharField(source='menu_item.name', read_only=True)
    
    class Meta:
        model = BookingItem
        fields = ['id', 'menu_item', 'menu_item_name', 'quantity', 'unit_price', 'total_price', 'special_instructions']
        read_only_fields = ['unit_price', 'total_price']


class BookingItemCreateSerializer(serializers.ModelSerializer):
    """Serializer for creating booking items"""
    class Meta:
        model = BookingItem
        fields = ['menu_item', 'quantity', 'special_instructions']


class BookingSerializer(serializers.ModelSerializer):
    """Full booking serializer with items"""
    items = BookingItemSerializer(many=True, read_only=True)
    restaurant_name = serializers.CharField(source='restaurant.name', read_only=True)
    customer_username = serializers.CharField(source='customer.username', read_only=True)
    delivery_partner_name = serializers.CharField(source='delivery_partner.username', read_only=True)
    allocated_tables_details = TableSerializer(source='allocated_tables', many=True, read_only=True)
    
    class Meta:
        model = Booking
        fields = '__all__'
        read_only_fields = ['created_at', 'updated_at', 'distance_km', 'is_distance_warning', 
                           'distance_warning_message', 'estimated_delivery_time', 'delivery_charge',
                           'subtotal', 'tax_amount', 'total_amount', 'delivery_partner']


class BookingCreateSerializer(serializers.ModelSerializer):
    """Serializer for creating bookings with validation"""
    items = BookingItemCreateSerializer(many=True, write_only=True, required=False)
    allocated_tables = serializers.PrimaryKeyRelatedField(many=True, queryset=Table.objects.all(), required=False)
    coins_to_redeem = serializers.DecimalField(max_digits=10, decimal_places=2, required=False, default=0, write_only=True)
    
    class Meta:
        model = Booking
        fields = ['restaurant', 'booking_type', 'customer_name', 'contact_number', 'email',
                  'reservation_date', 'reservation_time', 'party_size', 'special_requests',
                  'delivery_address', 'delivery_latitude', 'delivery_longitude',
                  'order_notes', 'items', 'allocated_tables', 'booking_fee', 'payment_status', 'payment_mode', 'coins_to_redeem']
    
    def validate(self, data):
        booking_type = data.get('booking_type')
        restaurant = data.get('restaurant')
        allocated_tables = data.get('allocated_tables', [])
        
        # Validate based on booking type
        if booking_type == 'DINE_IN':
            if not restaurant.is_dine_in_available:
                raise serializers.ValidationError("Dine-in is not available at this restaurant")
            if not data.get('reservation_date') or not data.get('reservation_time'):
                raise serializers.ValidationError("Reservation date and time are required for dine-in")
            if not data.get('party_size'):
                raise serializers.ValidationError("Party size is required for dine-in")
            if data['party_size'] > restaurant.max_party_size:
                raise serializers.ValidationError(f"Maximum party size is {restaurant.max_party_size}")
                
            # Allow creating booking without tables allocated initially (Owner allocates later)
            # But if provided, validate them
            if allocated_tables:
                for table in allocated_tables:
                    if table.restaurant != restaurant:
                        raise serializers.ValidationError(f"Table {table.table_number} does not belong to this restaurant")
                        
        elif booking_type == 'DELIVERY':
            if allocated_tables:
                raise serializers.ValidationError("Tables cannot be allocated for delivery orders")
                
            if not restaurant.is_delivery_available:
                raise serializers.ValidationError("Delivery is not available at this restaurant")
            if not data.get('delivery_address'):
                raise serializers.ValidationError("Delivery address is required")
            
            # Check distance for delivery
            if data.get('delivery_latitude') and data.get('delivery_longitude'):
                delivery_info = check_delivery_availability(
                    restaurant, 
                    data['delivery_latitude'], 
                    data['delivery_longitude']
                )
                if not delivery_info['is_deliverable']:
                    raise serializers.ValidationError(delivery_info['warning_message'])
                    
        elif booking_type == 'TAKEAWAY':
            if allocated_tables:
                raise serializers.ValidationError("Tables cannot be allocated for takeaway orders")
                
            if not restaurant.is_takeaway_available:
                raise serializers.ValidationError("Take away is not available at this restaurant")
        
        return data
    
    def create(self, validated_data):
        items_data = validated_data.pop('items', [])
        allocated_tables = validated_data.pop('allocated_tables', [])
        coins_to_redeem = validated_data.pop('coins_to_redeem', 0)
        request = self.context.get('request')
        
        # Set customer from request
        if request and request.user.is_authenticated:
            validated_data['customer'] = request.user
        else:
            # Handle guest or create user if needed (Assuming logged in for now)
            # Or raise error if auth required
            pass
        
        # Calculate distance and set warning for TAKEAWAY orders
        restaurant = validated_data['restaurant']
        if validated_data.get('delivery_latitude') and validated_data.get('delivery_longitude'):
            delivery_info = check_delivery_availability(
                restaurant,
                validated_data['delivery_latitude'],
                validated_data['delivery_longitude']
            )
            validated_data['distance_km'] = delivery_info['distance_km']
            validated_data['is_distance_warning'] = delivery_info['has_warning']
            validated_data['distance_warning_message'] = delivery_info['warning_message']
            
            # Set estimated delivery time for delivery orders
            if validated_data['booking_type'] == 'DELIVERY':
                validated_data['estimated_delivery_time'] = estimate_delivery_time(delivery_info['distance_km'])
                validated_data['delivery_charge'] = calculate_delivery_charge(delivery_info['distance_km'])
        
        # Create booking
        booking = Booking.objects.create(**validated_data)
        
        # Allocate tables
        if allocated_tables:
            booking.allocated_tables.set(allocated_tables)
        
        # Create booking items
        subtotal = 0
        aahar_items = []
        for item_data in items_data:
            menu_item = item_data['menu_item']
            unit_price = menu_item.price
            quantity = item_data.get('quantity', 1)
            total_price = unit_price * quantity
            
            BookingItem.objects.create(
                booking=booking,
                menu_item=menu_item,
                quantity=quantity,
                unit_price=unit_price,
                total_price=total_price,
                special_instructions=item_data.get('special_instructions', '')
            )
            subtotal += total_price
            aahar_item_id = menu_item.aahar_item_id
            if not aahar_item_id:
                aahar_item_id = -abs(menu_item.id)
                
            aahar_items.append({
                "item_id": aahar_item_id,
                "item_name": menu_item.name,
                "quantity": quantity,
                "price": str(unit_price),
                "remarks": item_data.get('special_instructions', '')
            })
        
        # Update totals
        booking.subtotal = Decimal(str(subtotal))
        booking.tax_amount = booking.subtotal * Decimal('0.05')  # 5% tax
        
        delivery_charge = Decimal(str(booking.delivery_charge)) if booking.delivery_charge else Decimal('0.00')
        booking.total_amount = booking.subtotal + delivery_charge + booking.tax_amount
        booking.save()
        
        # --- Loyalty Redemption ---
        if coins_to_redeem > 0 and booking.customer:
            from .loyalty_services import IronLawsEnforcer, get_or_create_wallet, IronLawsError
            wallet = get_or_create_wallet(booking.customer, restaurant)
            try:
                result = IronLawsEnforcer.validate_redemption(
                    wallet=wallet,
                    bill_amount=booking.total_amount,
                    coins_requested=coins_to_redeem,
                )
                IronLawsEnforcer.apply_redemption(
                    wallet=wallet,
                    booking=booking,
                    coins_to_redeem=result['coins_approved'],
                )
                booking.total_amount -= result['discount_amount']
                booking.save(update_fields=['total_amount'])
            except IronLawsError as e:
                import logging
                logger = logging.getLogger(__name__)
                logger.error(f"Failed to redeem coins for booking {booking.id}: {str(e)}")
        
        # --- Ahaar Online Order Integration ---
        # If this restaurant is linked to Ahaar and it's a Delivery/Takeaway,
        # push this booking to Ahaar backend.
        if booking.booking_type in ['DELIVERY', 'TAKEAWAY'] and hasattr(restaurant, 'aahar_config') and restaurant.aahar_config.is_active:
            import restaurant.aahar_service as aahar_service
            aahar_config = restaurant.aahar_config
            
            # Format payload according to OrderCreate schema
            is_transfer_type = "takeaway_hf" if booking.booking_type == 'TAKEAWAY' else "orders_hf"
            
            # Generate unique booking ID string (combining name, phone, date, time, and booking ID)
            from django.utils import timezone
            booking.refresh_from_db()
            booking_time = booking.created_at or timezone.now()
            clean_name = "".join(c for c in booking.customer_name if c.isalnum() or c == '_').replace(' ', '_')
            booking_time_str = booking_time.strftime('%Y%m%d_%H%M%S')
            generated_booking_id = f"{clean_name}_{booking.contact_number}_{booking_time_str}_{booking.id}"[:100]

            order_payload = {
                "restaurant_id": int(aahar_config.aahar_restaurant_service_id),
                "customer_name": f"{booking.customer_name} (#{booking.id})",
                "customer_mobile": booking.contact_number,
                "customer_phone": booking.contact_number,
                "booking_id": generated_booking_id,
                "payment_status": "Pending" if booking.payment_status == 'UNPAID' else "Paid",
                "is_transfer": is_transfer_type,
                "items": aahar_items
            }
            
            try:
                # Push the order to Ahaar. Not blocking the booking if this fails, 
                # but in production we might want to flag it for retry.
                response = aahar_service.submit_online_order(
                    int(aahar_config.aahar_restaurant_service_id), 
                    order_payload,
                    base_url=aahar_config.aahar_domain
                )
                if response and (response.get('code') == 200 or response.get('code') == 201):
                    data = response.get('data', {})
                    aahar_order_id = data.get('order_id')
                    if aahar_order_id:
                        AaharOrderSync.objects.create(
                            aahar_config=aahar_config,
                            aahar_order_id=aahar_order_id,
                            aahar_order_number=data.get('parcel_number', ''),
                            invoice=f"HF-{booking.id}",
                            booking_id=generated_booking_id,
                            is_transfer=is_transfer_type,
                            grand_total=booking.total_amount,
                            payment_status='PAID' if booking.payment_status == 'PAID' else 'UNPAID',
                            payment_mode=booking.payment_mode,
                            order_data=order_payload
                        )
            except Exception as e:
                import logging
                logger = logging.getLogger(__name__)
                logger.error(f"Failed to submit online order to Aahar for booking {booking.id}: {str(e)}")
        # ----------------------------------------
        
        # Send WhatsApp detailed bill / receipt confirmation
        try:
            from .whatsapp_service import send_order_confirmation
            send_order_confirmation(booking)
        except Exception as e:
            import logging
            logger = logging.getLogger(__name__)
            logger.error(f"Failed to send WhatsApp confirmation for booking {booking.id}: {str(e)}")

        return booking


class BookingStatusUpdateSerializer(serializers.ModelSerializer):
    """Serializer for updating booking status"""
    allocated_tables = serializers.PrimaryKeyRelatedField(many=True, queryset=Table.objects.all(), required=False)
    
    class Meta:
        model = Booking
        fields = ['status', 'payment_status', 'allocated_tables']
        
    def update(self, instance, validated_data):
        allocated_tables = validated_data.pop('allocated_tables', None)
        
        if allocated_tables is not None:
            if instance.booking_type != 'DINE_IN':
                 raise serializers.ValidationError("Cannot allocate tables to non-Dine-In booking")
            instance.allocated_tables.set(allocated_tables)
            
        return super().update(instance, validated_data)


class DeliveryCheckSerializer(serializers.Serializer):
    """Serializer for checking delivery availability"""
    restaurant_id = serializers.IntegerField()
    latitude = serializers.DecimalField(max_digits=9, decimal_places=6)
    longitude = serializers.DecimalField(max_digits=9, decimal_places=6)


class DeliveryCheckResponseSerializer(serializers.Serializer):
    """Response serializer for delivery check"""
    is_deliverable = serializers.BooleanField()
    distance_km = serializers.FloatField(allow_null=True)
    has_warning = serializers.BooleanField()
    warning_message = serializers.CharField(allow_blank=True)
    estimated_delivery_time = serializers.DateTimeField(allow_null=True)
    delivery_charge = serializers.DecimalField(max_digits=8, decimal_places=2, allow_null=True)


# ==================== Delivery Partner Serializers ====================
from .models import DeliveryContract, DeliveryCommissionLedger

class DeliveryContractSerializer(serializers.ModelSerializer):
    restaurant_name = serializers.CharField(source='restaurant.name', read_only=True)
    restaurant_location = serializers.CharField(source='restaurant.location', read_only=True)
    delivery_partner_name = serializers.CharField(source='delivery_partner.username', read_only=True)
    delivery_partner_phone = serializers.CharField(source='delivery_partner.phone', read_only=True)

    class Meta:
        model = DeliveryContract
        fields = ['id', 'restaurant', 'restaurant_name', 'restaurant_location', 'delivery_partner', 'delivery_partner_name', 'delivery_partner_phone', 'commission_type', 'commission_value', 'status', 'created_at']
        read_only_fields = ['delivery_partner', 'created_at', 'updated_at']

class DeliveryCommissionLedgerSerializer(serializers.ModelSerializer):
    restaurant_name = serializers.CharField(source='restaurant.name', read_only=True)
    delivery_partner_name = serializers.CharField(source='delivery_partner.username', read_only=True)
    
    class Meta:
        model = DeliveryCommissionLedger
        fields = ['id', 'booking', 'delivery_partner', 'delivery_partner_name', 'restaurant', 'restaurant_name', 'commission_amount', 'is_settled', 'settled_at', 'created_at']
        read_only_fields = ['created_at']


# ==================== Delivery Tracking Serializers ====================
from .models import DeliveryLocationLog

class DeliveryLocationUpdateSerializer(serializers.Serializer):
    """Validates incoming GPS coordinates from delivery partner"""
    latitude = serializers.DecimalField(max_digits=9, decimal_places=6)
    longitude = serializers.DecimalField(max_digits=9, decimal_places=6)


class DeliveryLocationLogSerializer(serializers.ModelSerializer):
    class Meta:
        model = DeliveryLocationLog
        fields = ['id', 'latitude', 'longitude', 'timestamp']
        read_only_fields = ['id', 'timestamp']


class DeliveryTrackingSerializer(serializers.Serializer):
    """Full tracking response: current position + destination + route history"""
    booking_id = serializers.IntegerField()
    status = serializers.CharField()
    delivery_partner_name = serializers.CharField()

    # Current partner location
    current_latitude = serializers.DecimalField(max_digits=9, decimal_places=6, allow_null=True)
    current_longitude = serializers.DecimalField(max_digits=9, decimal_places=6, allow_null=True)
    last_updated = serializers.DateTimeField(allow_null=True)

    # Restaurant (source)
    restaurant_name = serializers.CharField()
    restaurant_latitude = serializers.DecimalField(max_digits=9, decimal_places=6, allow_null=True)
    restaurant_longitude = serializers.DecimalField(max_digits=9, decimal_places=6, allow_null=True)

    # Customer destination
    delivery_address = serializers.CharField()
    destination_latitude = serializers.DecimalField(max_digits=9, decimal_places=6, allow_null=True)
    destination_longitude = serializers.DecimalField(max_digits=9, decimal_places=6, allow_null=True)

    # Route history (GPS breadcrumbs)
    route_history = DeliveryLocationLogSerializer(many=True)


# ==================== Aahar Integration Serializers ====================

class AaharConfigSerializer(serializers.ModelSerializer):
    """Serializer for Aahar configuration display"""
    restaurant_name = serializers.CharField(source='restaurant.name', read_only=True)
    restaurant_finder_config = serializers.SerializerMethodField()
    aahar_api_key = serializers.SerializerMethodField()

    class Meta:
        model = AaharConfig
        fields = ['id', 'restaurant', 'restaurant_name', 'aahar_restaurant_service_id',
                  'aahar_domain', 'is_multitenant', 'aahar_api_token', 'is_active', 
                  'restaurant_finder_config', 'aahar_api_key', 'linked_at', 'updated_at']
        read_only_fields = ['linked_at', 'updated_at']

    def get_restaurant_finder_config(self, obj):
        if hasattr(obj, 'restaurant_finder_config') and obj.restaurant_finder_config:
            from .serializers import RestaurantFinderConfigSerializer
            return RestaurantFinderConfigSerializer(obj.restaurant_finder_config).data
        return None

    def get_aahar_api_key(self, obj):
        from django.conf import settings
        return getattr(settings, 'AAHAR_API_KEY', '')


class AaharOrderSyncSerializer(serializers.ModelSerializer):
    """Serializer for Aahar synced orders"""
    restaurant_name = serializers.CharField(source='aahar_config.restaurant.name', read_only=True)

    class Meta:
        model = AaharOrderSync
        fields = ['id', 'aahar_config', 'restaurant_name', 'aahar_order_id', 'aahar_order_number',
                  'invoice', 'room_number', 'booking_id', 'order_data', 'grand_total',
                  'payment_status', 'payment_mode', 'status', 'synced_at', 'updated_at']
        read_only_fields = ['synced_at', 'updated_at']


class AaharLinkRequestSerializer(serializers.Serializer):
    """Validates incoming restaurant-Aahar link request"""
    restaurant_id = serializers.IntegerField()
    aahar_restaurant_service_id = serializers.CharField(max_length=50)
    aahar_domain = serializers.CharField(max_length=255)
    is_multitenant = serializers.BooleanField(default=True, required=False)
    aahar_api_token = serializers.CharField(max_length=500, required=False, allow_blank=True, default="")

    def validate_restaurant_id(self, value):
        try:
            Restaurant.objects.get(pk=value)
        except Restaurant.DoesNotExist:
            raise serializers.ValidationError("Restaurant not found")
        return value


class AaharPaymentUpdateSerializer(serializers.Serializer):
    """Validates payment status update request"""
    aahar_order_sync_id = serializers.IntegerField()
    payment = serializers.DecimalField(max_digits=10, decimal_places=2)
    mode = serializers.ChoiceField(choices=['cash', 'upi', 'card', 'online', 'wallet'])
    status = serializers.ChoiceField(choices=['paid', 'refunded'])


class AaharFetchOrdersRequestSerializer(serializers.Serializer):
    """Validates fetch orders request"""
    aahar_config_id = serializers.IntegerField()
    room_number = serializers.CharField(max_length=20, required=False, default='')
    booking_id = serializers.CharField(max_length=50, required=False, default='')


# ==================== Restaurant Finder Integration Serializers ====================

from .models import RestaurantFinderConfig, RestaurantFinderOrderSync

class RestaurantFinderConfigSerializer(serializers.ModelSerializer):
    """Serializer for Restaurant Finder configuration display"""
    restaurant_name = serializers.CharField(source='aahar_config.restaurant.name', read_only=True)

    class Meta:
        model = RestaurantFinderConfig
        fields = ['id', 'aahar_config', 'restaurant_name', 'api_url', 'brand_name',
                  'outlet_id', 'api_key', 'is_active', 'created_at', 'updated_at']
        read_only_fields = ['created_at', 'updated_at']


class RestaurantFinderOrderSyncSerializer(serializers.ModelSerializer):
    """Serializer for Restaurant Finder synced orders"""
    restaurant_name = serializers.CharField(source='config.restaurant.name', read_only=True)

    class Meta:
        model = RestaurantFinderOrderSync
        fields = ['id', 'config', 'restaurant_name', 'rf_order_id', 'order_data', 'grand_total',
                  'payment_status', 'payment_mode', 'status', 'synced_at', 'updated_at']
        read_only_fields = ['synced_at', 'updated_at']


class RestaurantFinderLinkRequestSerializer(serializers.Serializer):
    """Validates incoming aahar-RestaurantFinder link request"""
    aahar_config_id = serializers.IntegerField()

    def validate_aahar_config_id(self, value):
        from .models import AaharConfig
        try:
            AaharConfig.objects.get(pk=value)
        except AaharConfig.DoesNotExist:
            raise serializers.ValidationError("Aahar config not found")
        return value

class OfferSerializer(serializers.ModelSerializer):
    class Meta:
        model = Offer
        fields = ['id', 'title', 'description', 'discount_percentage', 'image', 'is_active', 'valid_until']


class ComboItemSerializer(serializers.ModelSerializer):
    menu_item_id = serializers.IntegerField(source='menu_item.id', read_only=True)
    name = serializers.CharField(source='menu_item.name', read_only=True)
    price = serializers.DecimalField(source='menu_item.price', max_digits=8, decimal_places=2, read_only=True)

    class Meta:
        model = ComboItem
        fields = ['menu_item', 'menu_item_id', 'name', 'price', 'quantity']


class ComboItemWriteSerializer(serializers.Serializer):
    menu_item = serializers.PrimaryKeyRelatedField(queryset=MenuItem.objects.all())
    quantity = serializers.IntegerField(default=1, min_value=1)


class ComboSerializer(serializers.ModelSerializer):
    combo_items = ComboItemSerializer(many=True, read_only=True)
    items = ComboItemWriteSerializer(many=True, write_only=True, required=False)

    class Meta:
        model = Combo
        fields = ['id', 'restaurant', 'name', 'description', 'service_category_id', 
                  'service_category_name', 'price', 'image', 'is_active', 'created_at', 
                  'combo_items', 'items']
        read_only_fields = ['id', 'restaurant', 'created_at']

    def create(self, validated_data):
        items_data = validated_data.pop('items', [])
        price = validated_data.get('price')
        if price is None:
            computed_price = 0
            for item in items_data:
                menu_item = item.get('menu_item')
                qty = item.get('quantity', 1)
                computed_price += menu_item.price * qty
            validated_data['price'] = computed_price

        combo = Combo.objects.create(**validated_data)
        for item in items_data:
            menu_item = item.get('menu_item')
            qty = item.get('quantity', 1)
            ComboItem.objects.create(combo=combo, menu_item=menu_item, quantity=qty)
        return combo

    def update(self, instance, validated_data):
        items_data = validated_data.pop('items', None)
        price_explicit = 'price' in validated_data

        # Update other fields first
        for attr, value in validated_data.items():
            setattr(instance, attr, value)

        if items_data is not None:
            instance.combo_items.all().delete()
            for item in items_data:
                menu_item = item.get('menu_item')
                qty = item.get('quantity', 1)
                ComboItem.objects.create(combo=instance, menu_item=menu_item, quantity=qty)

        if not price_explicit or validated_data.get('price') is None:
            computed_price = 0
            for item in instance.combo_items.all():
                computed_price += item.menu_item.price * item.quantity
            instance.price = computed_price

        instance.save()
        return instance


