from rest_framework import serializers

from webservice_running.models import OrdersLocal


# from dbsynce.serializer import OrdersSerializer


class OrderNotDefined(Exception):
    """
    If order_synced field is not defined throw exception
    """

    def __init__(self, message="order_synced is not defined"):
        self.message = message
        super().__init__(self.message)


class OrdersLocalSerializer(serializers.ModelSerializer):
    service = serializers.IntegerField(
        source="order_synced.service.pk",
        allow_null=True
    )
    service_category = serializers.IntegerField(
        source="order_synced.service_category.pk",
        allow_null=True
    )
    state = serializers.CharField(
        source="order_synced.state",
        allow_null=True
    )
    id_metaservice = serializers.IntegerField(
        source="order_synced.id_metaservice",
        allow_null=True
    )

    provider = serializers.IntegerField(
        source="order_synced.provider.pk",
        allow_null=True
    )
    provider_screen_name = serializers.CharField(
        source="order_synced.provider.user.full_name",
        allow_null=True
    )

    receiver = serializers.IntegerField(
        source="order_synced.receiver.pk",
        allow_null=True
    )
    receiver_screen_name = serializers.CharField(
        source="order_synced.receiver.full_name",
        allow_null=True
    )

    client = serializers.CharField(
        source="order_synced.client.pk",
        allow_null=True
    )
    client_screen_name = serializers.CharField(
        source="order_synced.client.user.full_name",
        allow_null=True
    )

    # time_created = serializers.DateTimeField(
    #     source="order_synced.time_created", 
    #     allow_null=True
    # )
    time_placed = serializers.DateTimeField(
        source="order_synced.time_placed",
        allow_null=True
    )
    time_start = serializers.DateTimeField(
        source="order_synced.time_start",
        allow_null=True
    )
    time_start_real = serializers.DateTimeField(
        source="order_synced.time_start_real",
        allow_null=True
    )
    time_start_predicted = serializers.DateTimeField(
        source="order_synced.time_start_predicted",
        allow_null=True
    )
    time_finish_predicted = serializers.DateTimeField(
        source="order_synced.time_finish_predicted",
        allow_null=True
    )
    time_finish_real = serializers.DateTimeField(
        source="order_synced.time_finish_real",
        allow_null=True
    )

    predicted_price = serializers.FloatField(
        source="order_synced.predicted_price",
        allow_null=True
    )
    real_price = serializers.FloatField(
        source="order_synced.real_price",
        allow_null=True
    )
    is_global = serializers.BooleanField(
        source="order_synced.is_global",
        allow_null=True
    )
    is_visible = serializers.BooleanField(
        source="order_synced.is_visible",
        allow_null=True
    )
    ticket = serializers.IntegerField(
        source="order_synced.ticket.pk",
        allow_null=True
    )
    status = serializers.IntegerField(
        source="order_synced.ticket.stauts",
        allow_null=True
    )
    priority = serializers.IntegerField(
        source="order_synced.ticket.priority",
        allow_null=True
    )
    title = serializers.CharField(
        source="order_synced.ticket.title",
        allow_null=True
    )
    note = serializers.CharField(
        source="order_synced.ticket.note",
        allow_null=True
    )
    due_date = serializers.DateField(
        source="order_synced.ticket.due_date",
        allow_null=True
    )
    status_changed_date = serializers.DateTimeField(
        source="order_synced.ticket.status_changed_date",
        allow_null=True
    )

    # order_synced = OrdersSerializer(read_only=True)

    class Meta:
        model = OrdersLocal
        fields = "__all__"
        # fields = [
        #     "order",
        #     "order_synced"
        # ]
        # depth = 2

    def update(self, instance, validated_data):
        """
        Normally order_synced is not null, but in testing it is null=True, so it can produce exceptions
        """

        order_instance = instance.order_synced
        if not order_instance:
            raise OrderNotDefined()
        ticket_instance = instance.order_synced.ticket

        for attr, value in validated_data.items():
            if attr == "order_synced":
                for order_synced_attr, order_synced_value in value.items():
                    if order_synced_attr == "ticket":
                        for ticket_attr, ticket_value in order_synced_value.items():
                            setattr(ticket_instance, ticket_attr, ticket_value)
                            continue
                    else:
                        setattr(order_instance, order_synced_attr, order_synced_value)
            else:
                setattr(instance, attr, value)

        instance.save()
        ticket_instance.save()
        order_instance.save()
        return instance
