from django.conf import settings
from rest_framework import serializers
from .models import OrderItemModel, OrderModel, DiscountCode, Cart, CartItem
from product.serializers import ProductVariantSerialzier, AttributeValueSerialzier, ProductImageSerailizer
from account.serializers import UserAddressSerializer
from product.models import ProductVariant


class ProductVariantSerialzier(serializers.ModelSerializer):
    product_attributes = AttributeValueSerialzier(many=True)
    image = serializers.SerializerMethodField()
    discount_amount = serializers.SerializerMethodField()
    title = serializers.SerializerMethodField()
    price = serializers.SerializerMethodField()
    final_price = serializers.SerializerMethodField()
    category = serializers.SerializerMethodField()
    slug = serializers.CharField(source='product.slug')

    class Meta:
        model = ProductVariant
        fields = ['id', 'slug', 'title', 'product_attributes', 'in_stock', 'price',
                  'discount', 'color', 'image', 'discount_amount', 'category', 'final_price']

    def get_discount_amount(self, obj):
        discount_amount = int(obj.price * (obj.discount / 100))
        return f'{discount_amount:,.0f} تومانءءء'

    def get_final_price(self, obj):
        final_price = obj.price - int(obj.price * (obj.discount / 100))
        return f'{final_price:,.0f} تومانءءء'

    def get_price(self, obj):
        return f'{obj.price:,.0f} تومانءءء'

    def get_image(self, obj):
        return self.context.get('request').build_absolute_uri(obj.images.all().first().image.url)

    def get_title(self, obj):
        return obj.product.name

    def get_category(self, obj):
        return obj.product.category.name


class DiscountCodeSerializer(serializers.ModelSerializer):
    class Meta:
        model = DiscountCode
        fields = ('code', 'percent')
        read_only_fields = ('percent',)


class OrderItemSerailzier(serializers.ModelSerializer):
    product = serializers.SerializerMethodField()
    discount_amount = serializers.SerializerMethodField()
    price = serializers.SerializerMethodField()
    final_price = serializers.SerializerMethodField()
    discount = serializers.SerializerMethodField()
    special_discount_amount = serializers.SerializerMethodField()

    class Meta:
        model = CartItem
        exclude = ('cart',)
        read_only_fields = ('cart', 'product', 'discount_percent')

    def get_product(self, obj):
        return ProductVariantSerialzier(instance=obj.product_variant, context={'request': self.context.get('request')}).data

    def get_discount_amount(self, obj):
        return f'{obj.item_discount_amount:,.0f} تومانءءء'

    def get_final_price(self, obj):
        return f'{obj.price_after_discount:,.0f} تومانءءء'

    def get_price(self, obj):
        return f'{obj.price_before_discount:,.0f} تومانءءء'

    def get_discount(self, obj):
        return obj.product_variant.discount

    def get_special_discount_amount(self, obj):
        # For cart items
        amount = getattr(obj, 'special_discount_amount', None)
        if amount is None:
            # If it's an order item, check item_special_discount_amount property
            amount = getattr(obj, 'item_special_discount_amount', 0)
        if amount is None or amount == 0:
            return None
        return f'{int(amount):,.0f} تومانءءء'


class CartSerializer(serializers.ModelSerializer):
    items = OrderItemSerailzier(many=True)
    cart_total = serializers.SerializerMethodField()
    tax_amount = serializers.SerializerMethodField()
    final_price = serializers.SerializerMethodField()
    discount_code = serializers.SerializerMethodField()
    items_discount_amount = serializers.SerializerMethodField()
    special_discount_total = serializers.SerializerMethodField()
    special_discount_code = serializers.SerializerMethodField()
    address = UserAddressSerializer()

    class Meta:
        model = Cart
        fields = ['items_discount_amount', 'discount_code', 'items', 'cart_total', 'tax_amount',
                  'final_price', 'address', 'special_discount_total', 'special_discount_code']

    def get_special_discount_code(self, obj):
        if obj.special_discount_code:
            return {
                'code': f'{obj.special_discount_code.code}',
                'user': f'{obj.special_discount_code.user.phone}'
            }
        else:
            return None

    def get_discount_code(self, obj):
        if obj.discount_code:
            return {
                'code': f'{obj.discount_code.code}',
                'percent': obj.discount_code.percent,
                'amount': f'{obj.discount_code_amount:,.0f} تومانءءء'
            }
        else:
            return None

    def get_tax_amount(self, obj):
        return f'{obj.tax_amount:,.0f} تومانءءء'

    def get_cart_total(self, obj):
        return f'{obj.cart_total:,.0f} تومانءءء'

    def get_items_discount_amount(self, obj):
        return f'{obj.items_discount_amount:,.0f} تومانءءء'

    def get_final_price(self, obj):
        return f'{obj.final_price:,.0f} تومانءءء'

    def get_special_discount_total(self, obj):
        # sum of special discounts on cart items
        total = obj.special_discount_total if hasattr(
            obj, 'special_discount_total') else 0
        return f'{int(total):,.0f} تومانءءء'


class OrderListSerializer(serializers.ModelSerializer):
    count = serializers.SerializerMethodField()
    images = serializers.SerializerMethodField()
    verbose_status = serializers.SerializerMethodField()
    order_id = serializers.SerializerMethodField()

    class Meta:
        model = OrderModel
        fields = ['created_at', 'status',  "images", "count",
                  "id", 'final_price', 'order_id', 'verbose_status']
        read_only_fields = ['count', 'images', 'order_id', 'verbose_status']

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

    def get_count(self, obj):
        return obj.items.all().count()

    def get_order_id(self, obj):
        return obj.pk

    def get_images(self, obj):
        image_list = [
            self.context.get('request').build_absolute_uri(image.image.url)
            if (image := item.product.images.all().first()) else None
            for item in obj.items.all()[:3]
        ]
        return filter(lambda x: x is not None, image_list)


class OrderGetSerializer(serializers.ModelSerializer):
    count = serializers.SerializerMethodField()
    images = serializers.SerializerMethodField()
    order_id = serializers.SerializerMethodField()
    verbose_status = serializers.SerializerMethodField()
    items = OrderItemSerailzier(many=True)
    address = UserAddressSerializer()
    discount_code = DiscountCodeSerializer()

    class Meta:
        model = OrderModel
        fields = ['created_at', 'status',  "images", "count", "id", 'final_price', 'order_id', 'verbose_status',
                  'address', 'items', 'tax', 'cart_total', 'discount_code', 'discount_amount', 'special_discount_total']

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

    def get_count(self, obj):
        return obj.items.all().count()

    def get_images(self, obj):
        image_list = [
            self.context.get('request').build_absolute_uri(image.image.url)
            if (image := item.product.images.all().first()) else None
            for item in obj.items.all()[:3]
        ]
        return filter(lambda x: x is not None, image_list)

    def get_order_id(self, obj):
        return obj.id
