from rest_framework import serializers
from .models import AdditionalDetails, CustomOrderTracking, OrderProductCustomization, Orders, OrderProducts,Ads, Discount, Coupons, OrderDelivery, SomeOneElse
from django.urls import reverse
from products.models import ProductImage, Products, CustomProductImage
from products.serializers import CustomProductSerializer



class SomeOneElseDataSerializer(serializers.ModelSerializer):
    class Meta:
        model = SomeOneElse
        fields = ["name", "phone_number"]



class OrderProductCustomizationSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderProductCustomization
        fields = ["id", "custom_note", "custom_image"]



class OrderProductSerializer(serializers.ModelSerializer):
    sku_name = serializers.CharField(source="sku.sku_name")
    sku_quantity = serializers.CharField(source="sku.sku_quantity")
    sku_unit = serializers.CharField(source="sku.sku_unit")
    veg_or_non_veg = serializers.CharField(source="sku.product.veg_or_non_veg_status")
    customizations = OrderProductCustomizationSerializer(many=True, read_only=True)  

    class Meta:
        model = OrderProducts
        fields = [
            "sku",
            "quantity",
            "price",
            "sku_name",
            "veg_or_non_veg",
            "sku_quantity",
            "sku_unit",
            "customizations",
        ]





class PickUpOrderSerializer(serializers.ModelSerializer):
    order_data          = OrderProductSerializer(many=True, read_only=True)
    shop_name           = serializers.CharField(source="store_uuid.unit_name")
    shop_location       = serializers.CharField(source="store_uuid.unit_location")
    shop_contact        = serializers.CharField(source="store_uuid.contact_no")
    some_one_else_order = SomeOneElseDataSerializer(read_only=True)
    class Meta:
        model = Orders
        fields = [
            "uuid",
            "order_ID",
            "order_type",
            "order_status",
            "sub_total",
            "taxes_and_charges",
            "delivery_charges",
            "grand_total",
            "order_data",
            "created_date",
            "shop_name",
            "shop_location",
            "shop_contact",
            "delivery_slot_date",
            "delivery_slot_time",
            "some_one_else_order"
        ]
    def to_representation(self, instance):
        representation = super().to_representation(instance)
        if representation.get('some_one_else_order') is None:
            representation['some_one_else_order'] = {}  # return empty object instead of null
        return representation
    



class OrderSerializer(serializers.ModelSerializer):
    order_data = OrderProductSerializer(many=True, read_only=True)
    shop_name = serializers.CharField(source="store_uuid.unit_name")
    shop_location = serializers.CharField(source="store_uuid.unit_location")
    shop_contact = serializers.CharField(source="store_uuid.contact_no")

    address_type = serializers.CharField(source="drop_address.address_type", allow_null=True, required=False)
    address_1 = serializers.CharField(source="drop_address.house_number_or_name", allow_null=True, required=False)
    address_2 = serializers.CharField(source="drop_address.land_mark", allow_null=True, required=False)

    payment_mode = serializers.CharField(source="payment_mode.mode_name", allow_null=True, required=False)

    some_one_else_order = SomeOneElseDataSerializer(read_only=True)

    # ✅ NEW FIELDS
    additional_info = serializers.SerializerMethodField()
    mobile_number = serializers.SerializerMethodField()

    class Meta:
        model = Orders
        fields = [
            "uuid",
            "order_ID",
            "order_type",
            "order_status",
            "sub_total",
            "taxes_and_charges",
            "delivery_charges",
            "grand_total",
            "order_data",
            "created_date",
            "shop_name",
            "shop_location",
            "shop_contact",
            "delivery_slot_date",
            "delivery_slot_time",
            "address_type",
            "payment_mode",
            "address_1",
            "address_2",
            "some_one_else_order",
            "discount",

            # ✅ Include new fields
            "additional_info",
            "mobile_number"
        ]

    def get_additional_info(self, obj):
        try:
            details = AdditionalDetails.objects.filter(order=obj).first()
            return details.additional_info if details else ""
        except Exception:
            return ""

    def get_mobile_number(self, obj):
        try:
            details = AdditionalDetails.objects.filter(order=obj).first()
            return details.mobile_number if details else ""
        except Exception:
            return ""

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

        if representation.get('some_one_else_order') is None:
            representation['some_one_else_order'] = {}

        return representation

class CourierDetailsSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderDelivery
        fields = ["courier_service_name", "package_number", "expected_date_of_delivery", "tracking_link"]


class OrderSerializer2(serializers.ModelSerializer):
    order_data = OrderProductSerializer(many=True, read_only=True)
    pu_name = serializers.CharField(source="pu_uuid.pu_name")
    pu_location = serializers.CharField(source="pu_uuid.pu_location")
    pu_contact = serializers.CharField(source="pu_uuid.contact_no")

    address_type = serializers.CharField(
        source="drop_address.address_type",
        allow_null=True,
        required=False
    )
    address_1 = serializers.CharField(
        source="drop_address.house_number_or_name",
        allow_null=True,
        required=False
    )
    address_2 = serializers.CharField(
        source="drop_address.land_mark",
        allow_null=True,
        required=False
    )

    payment_mode = serializers.CharField(
        source="payment_mode.mode_name",
        allow_null=True,
        required=False
    )
    additional_info = serializers.SerializerMethodField()
    mobile_number = serializers.SerializerMethodField()

    some_one_else_order = SomeOneElseDataSerializer(read_only=True)

    class Meta:
        model = Orders
        fields = [
            "uuid",
            "order_ID",
            "order_type",
            "order_status",
            "sub_total",
            "taxes_and_charges",
            "delivery_charges",
            "grand_total",
            "order_data",
            "created_date",
            "pu_name",
            "pu_location",
            "pu_contact",
            "delivery_slot_date",
            "delivery_slot_time",
            "address_type",
            "payment_mode",
            "address_1",
            "address_2",
            "some_one_else_order",
            'discount',
         "additional_info",
            "mobile_number"
        ]

    def get_additional_info(self, obj):
        try:
            details = AdditionalDetails.objects.filter(order=obj).first()
            return details.additional_info if details else ""
        except Exception:
            return ""

    def get_mobile_number(self, obj):
        try:
            details = AdditionalDetails.objects.filter(order=obj).first()
            return details.mobile_number if details else ""
        except Exception:
            return ""
    def to_representation(self, instance):
        representation = super().to_representation(instance)
        if representation.get("some_one_else_order") is None:
            representation["some_one_else_order"] = {}
        return representation


class CustomOrderCreateSerializer(serializers.ModelSerializer):
    shop_name = serializers.CharField(source="store_uuid.unit_name")
    shop_location = serializers.CharField(source="store_uuid.unit_location")
    shop_contact = serializers.CharField(source="store_uuid.contact_no")
    address_type = serializers.CharField(source="drop_address.address_type", allow_null=True,required=False)
    address_1 = serializers.CharField(source="drop_address.house_number_or_name", allow_null=True, required=False)
    address_2 = serializers.CharField(source="drop_address.land_mark", allow_null=True, required=False)
    payment_mode = serializers.CharField(source="payment_mode.mode_name", allow_null=True, required=False)
    custom_product = CustomProductSerializer(read_only = True)
    some_one_else_order = SomeOneElseDataSerializer(read_only=True)
    class Meta:
        model = Orders
        fields = [
            "uuid",
            "order_ID",
            "order_type",
            "order_status",
            "sub_total",
            "taxes_and_charges",
            "delivery_charges",
            "grand_total",
            "created_date",
            "shop_name",
            "shop_location",
            "shop_contact",
            "delivery_slot_date",
            "delivery_slot_time",
            "address_type",
            "address_1",
            "address_2",
            "custom_product",
            "description",
            "message",
            "some_one_else_order",
            "payment_mode"
        ]
    def to_representation(self, instance):
        representation = super().to_representation(instance)
        if representation.get('some_one_else_order') is None:
            representation['some_one_else_order'] = {}  # return empty object instead of null
        return representation

    # def get_product_image(self, obj):
    #     product_image_custom = CustomProductImage.objects.filter(
    #         custom_product=obj.custom_product
    #     ).first()
    #     if product_image_custom:
    #         return product_image_custom.image.url
    #     return None
class CustomOrderSerializer(serializers.ModelSerializer):
    shop_name = serializers.CharField(source="store_uuid.unit_name")
    shop_location = serializers.CharField(source="store_uuid.unit_location")
    shop_contact = serializers.CharField(source="store_uuid.contact_no")

    address_type = serializers.CharField(source="drop_address.address_type", allow_null=True, required=False)
    address_1 = serializers.CharField(source="drop_address.house_number_or_name", allow_null=True, required=False)
    address_2 = serializers.CharField(source="drop_address.land_mark", allow_null=True, required=False)

    custom_product = CustomProductSerializer(read_only=True)
    some_one_else_order = SomeOneElseDataSerializer(read_only=True)

    payment_mode = serializers.CharField(source="payment_mode.mode_name", allow_null=True, required=False)

    # ✅ Custom fields
    custom_image = serializers.SerializerMethodField()
    quantity = serializers.SerializerMethodField()
    quantity_unit = serializers.SerializerMethodField()
    delivery_type = serializers.SerializerMethodField()

    latitude = serializers.SerializerMethodField()
    longitude = serializers.SerializerMethodField()

    # ✅ NEW FIELD
    is_edited = serializers.SerializerMethodField()

    class Meta:
        model = Orders
        fields = [
            "uuid",
            "order_ID",
            "order_type",
            "order_status",
            "sub_total",
            "taxes_and_charges",
            "delivery_charges",
            "grand_total",
            "discount",
            "created_date",
            "shop_name",
            "shop_location",
            "shop_contact",
            "delivery_slot_date",
            "delivery_slot_time",
            "address_type",
            "address_1",
            "address_2",
            "custom_product",
            "description",
            "message",
            "some_one_else_order",
            "custom_image",
            "quantity",
            "quantity_unit",
            "delivery_type",
            "latitude",
            "longitude",
            "payment_mode",
            "is_edited",  # ✅ added
        ]

    # ✅ CACHE TRACKING (IMPORTANT OPTIMIZATION)
    def get_tracking(self, obj):
        if not hasattr(self, "_tracking_cache"):
            try:
                self._tracking_cache = CustomOrderTracking.objects.get(order_id=obj)
            except CustomOrderTracking.DoesNotExist:
                self._tracking_cache = None
        return self._tracking_cache

    def get_custom_image(self, obj):
        tracking = self.get_tracking(obj)
        if tracking and tracking.custom_image:
            return self.context['request'].build_absolute_uri(tracking.custom_image.url)
        return None

    def get_quantity(self, obj):
        tracking = self.get_tracking(obj)
        return tracking.quantity if tracking else None

    def get_quantity_unit(self, obj):
        tracking = self.get_tracking(obj)
        return tracking.quantity_unit if tracking else None

    def get_delivery_type(self, obj):
        tracking = self.get_tracking(obj)
        return tracking.delivery_type if tracking else None

    def get_latitude(self, obj):
        tracking = self.get_tracking(obj)
        if tracking and tracking.delivery_type == "Pick Up" and obj.drop_address:
            return obj.drop_address.latitude
        return None

    def get_longitude(self, obj):
        tracking = self.get_tracking(obj)
        if tracking and tracking.delivery_type == "Pick Up" and obj.drop_address:
            return obj.drop_address.longitude
        return None

    # ✅ NEW FIELD METHOD
    def get_is_edited(self, obj):
        return self.context.get("is_edited", False)

    def to_representation(self, instance):
        representation = super().to_representation(instance)
        if representation.get('some_one_else_order') is None:
            representation['some_one_else_order'] = {}
        return representation
    # def get_product_image(self, obj):
    #     product_image_custom = CustomProductImage.objects.filter(
    #         custom_product=obj.custom_product
    #     ).first()
    #     if product_image_custom:
    #         return product_image_custom.image.url
    #     return None



class OrderProductCustomizationSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderProductCustomization
        fields = ["id", "custom_note", "custom_image"]





# class PastOrderListSerializer(serializers.ModelSerializer):
#     order_ID = serializers.CharField()
#     delivery_slot_date = serializers.DateField()
#     delivery_slot_time = serializers.TimeField(required=False, allow_null=True)
#     grand_total = serializers.FloatField()
#     order_status = serializers.CharField()
#     order_type = serializers.CharField()
#     products = OrderProductSerializer(source="order_data", many=True, read_only=True)
#     product_image = serializers.SerializerMethodField()
#     address_type = serializers.CharField(
#         source="drop_address.address_type", allow_null=True, required=False
#     )

#     class Meta:
#         model = Orders
#         fields = [
#             "uuid",
#             "order_ID",
#             "delivery_slot_date",
#             "delivery_slot_time",
#             "grand_total",
#             "order_status",
#             "order_type",
#             "products",
#             "product_image",
#             "address_type",
#             "description",
#         ]

#     def get_product_image(self, obj):
#         if obj.order_type == "Custom Orders":
#             product_image_custom = CustomProductImage.objects.filter(
#                 custom_product=obj.custom_product
#             ).first()
#             if product_image_custom:
#                 return product_image_custom.image.url
#         for order_product in obj.order_data.all():
#             product_image = ProductImage.objects.filter(
#                 product=order_product.sku.product
#             ).first()
#             if product_image:
#                 return product_image.image.url
#         return None

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

#         if not data.get("delivery_slot_time"):
#             data["delivery_slot_time"] = "Not Provided"

#         return data





class PastOrderListSerializer(serializers.ModelSerializer):
    order_ID = serializers.CharField()
    delivery_slot_date = serializers.DateField()
    delivery_slot_time = serializers.TimeField(required=False, allow_null=True)
    grand_total = serializers.FloatField()
    order_status = serializers.CharField()
    order_type = serializers.CharField()
    product_names = serializers.SerializerMethodField()
    product_image = serializers.SerializerMethodField()
    address_type = serializers.CharField(source="drop_address.address_type", allow_null=True,required=False)
    

    class Meta:
        model = Orders
        fields = [
            "uuid",
            "order_ID",
            "delivery_slot_date",
            "delivery_slot_time",
            "grand_total",
            "order_status",
            "order_type",
            "product_names",
            "product_image",
            "address_type",
            "description"
        ]

    def get_product_names(self, obj):
        if obj.order_type == "Custom Orders":
            return [obj.custom_product.item_name]
        return [order_product.product_name for order_product in obj.order_data.all()]

    def get_product_image(self, obj):
        if obj.order_type == "Custom Orders":
            product_image_custom = CustomProductImage.objects.filter(
                custom_product=obj.custom_product
            ).first()
            if product_image_custom:
                return product_image_custom.image.url

        for order_product in obj.order_data.all():
            # 🔥 FIX: check sku exists
            if not order_product.sku:
                continue

            product = order_product.sku.product

            # 🔥 EXTRA SAFETY
            if not product:
                continue

            product_image = ProductImage.objects.filter(
                product=product
            ).first()

            if product_image:
                return product_image.image.url

        return None

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

        if not data.get("delivery_slot_time"):
            data["delivery_slot_time"] = "Not Provided"

        return data

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Products
        fields = ["id", "item_name", "item_code"]

class CouponSerializer(serializers.ModelSerializer):
    class Meta:
        model = Coupons
        fields = ["id", "CouponName", "CouponCode"]

class DiscountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Discount
        fields = ["id", "DiscountName", "DiscountCode"]



class AdSerializer(serializers.ModelSerializer):
    web_image = serializers.ImageField(source="StandardImage", required=False)
    mobile_image = serializers.ImageField(source="BannerImage", required=False)

    Discount = DiscountSerializer(required=False)
    Coupon = CouponSerializer(required=False)
    Product = ProductSerializer(required=False)

    class Meta:
        model = Ads
        fields = [
            "AdTitle",
            "AdDescription",
            "AdPlacement",
            "AdType",
            "web_image",
            "mobile_image",
            "Discount",
            "Coupon",
            "Product",
        ]

class DiscountDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = Discount
        fields = ["id", "DiscountName", "DiscountCode", "DiscountDescription", "DiscountOn", "ApplicableCategory", "ApplicableSubCategory", "ApplicableProduct", "ApplicableSku", "DiscountPercentage", "StandardImage", "BannerImage"]


class OrderBillDetailsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Orders
        fields = ["sub_total","taxes_and_charges","delivery_charges","grand_total", "total_savings", "coupon_savings", "discount"]



