"""
Order serializer
"""

# import decimal

from django.db.models import Q
from django.utils.translation import gettext as _
from rest_framework import serializers
from rest_framework.exceptions import PermissionDenied

from core.apps.eggs import models
from core.apps.eggs.models import Market, History, Notification
from core.apps.eggs.serializers import courier, location, market
from core.apps.eggs.serializers.order_item import OrderItemsSerializer
from core.http.models import User
from core.http.serializers import user


class OrderCourierSerializer(serializers.ModelSerializer):
    user_id = user.UserSerializer()

    class Meta:
        model = models.Courier
        fields = (
            "id",
            "user_id",
        )


class OrderSerializer(serializers.ModelSerializer):
    market = market.MarketSerializer(read_only=True, source="market_id")
    location = location.LocationSerializer(
        read_only=True, source="location_id"
    )
    courier = courier.CourierSerializer(read_only=True, source="courier_id")
    order_items = OrderItemsSerializer(many=True, read_only=True)

    class Meta:
        model = models.Order
        fields = (
            "id",
            "courier",
            "market",
            "location",
            "price",
            "price_paid",
            "debt",
            "status",
            "comment",
            "data",
            "count",
            "order_items",
        )

    def to_representation(self, instance):
        representation = super().to_representation(instance)
        for field in ["price", "price_paid", "debt"]:
            try:
                representation[field] = str(
                    round(float(representation[field]), 2)
                )
            except (TypeError, ValueError):
                representation[field] = "Invalid value"
        return representation


class OrderCreateSerializer(serializers.ModelSerializer):
    location = location.LocationSerializer(source="location_id", required=True)
    market = market.MarketSerializer(source="market_id", read_only=True)
    order_items = OrderItemsSerializer(many=True, required=False)

    class Meta:
        model = models.Order
        fields = (
            "id",
            "market_id",
            "market",
            "comment",
            "price",
            "price_paid",
            "debt",
            "location",
            "status",
            "count",
            "order_items",
        )

    def validate_price(self, value):
        try:
            return round(float(value), 2)
        except (TypeError, ValueError):
            raise serializers.ValidationError("Invalid price value.")

    def create(self, validated_data):
        order_items_data = validated_data.pop("order_items", [])
        location_data = validated_data.pop("location_id", None)
        request = self.context.get("request")
        if request and request.user.role == "market":
            try:
                market_instance = Market.objects.get(user_id=request.user.id)
                validated_data["market_id"] = market_instance
            except Market.DoesNotExist:
                raise PermissionDenied(
                    "Bu foydalanuvchi uchun Market mavjud emas"
                )
        if request and request.user.role == "courier":
            courier_instance = models.Courier.objects.get(
                user_id=request.user.id
            )
            validated_data["courier_id"] = courier_instance

        if location_data:
            location = models.Location.objects.create(**location_data)
            validated_data["location_id"] = location

        # validated_data["price"] = self.validate_price(
        #     validated_data.get("price", 0.00)
        # )
        # validated_data["price_paid"] = self.validate_price(
        #     validated_data.get("price_paid", 0.00)
        # )
        # validated_data["debt"] = self.validate_price(
        #     validated_data.get("debt", 0.00)
        # )

        order_pk = super().create(validated_data).pk
        order = models.Order.objects.get(pk=order_pk)

        for order_item_data in order_items_data:
            models.OrderItems.objects.create(order_id=order, **order_item_data)

        created_who = ""
        if request:
            if request.user.role == "market" and order.market_id is not None:
                created_who = f"{order.market_id.user_id.first_name} {order.market_id.user_id.last_name}"
            elif (
                request.user.role == "courier" and order.courier_id is not None
            ):
                created_who = f"{order.courier_id.user_id.first_name} {order.courier_id.user_id.last_name}"
            elif request.user.role == "admin":
                created_who = (
                    f"{request.user.first_name} {request.user.last_name}"
                )

        History.objects.create(
            content_object=order,
            action="order_created",
            created_who=created_who,
            user_id=request.user,
            created_by=order.market_id.name,
            comment=order.comment,
            reason=_(f"Buyurtma: {order.price}"),
            avatar=(
                order.market_id.avatar if order.market_id.avatar else None
            ),
        )

        notification_user = User.objects.filter(
            Q(role="admin") | Q(role="courier")
        )
        for user in notification_user:
            Notification.objects.create(
                user=user,
                title=f"Yangi buyurtma: {order.price}",
                body=f"Yangi buyurtma: {order.market_id.name} {order.price}",
            )

        return order

    def to_representation(self, instance):
        serializer = OrderSerializer(instance)
        return serializer.data

    def update(self, instance, validated_data):
        order_items_data = validated_data.pop("order_items", [])
        location_data = validated_data.pop("location_id", None)
        request = self.context.get("request")

        if request and request.user.role == "courier":
            courier_instance = models.Courier.objects.get(
                user_id=request.user.id
            )
            instance.courier_id = courier_instance

        for attr, value in validated_data.items():
            if attr in ["price", "price_paid", "debt"]:
                value = self.validate_price(value)
            setattr(instance, attr, value)
        instance.save()

        for order_item_data in order_items_data:
            models.OrderItems.objects.update_or_create(
                order_id=instance, defaults=order_item_data
            )

        if location_data:
            location, created = models.Location.objects.update_or_create(
                id=instance.location_id.id if instance.location_id else None,
                defaults=location_data,
            )
            instance.location_id = location
            instance.save()

        return instance
