from django.utils.translation import gettext_lazy as _
from rest_framework.exceptions import ValidationError
from rest_framework.fields import CharField, DictField, FloatField, IntegerField
from rest_framework.serializers import ModelSerializer, Serializer

from core.models import Address


class AddressAutocompleteInputSerializer(Serializer):
    q = CharField(required=True)
    limit = IntegerField(required=False, min_value=1, max_value=10, default=5)


class AddressSuggestionSerializer(Serializer):
    display_name = CharField()
    lat = FloatField()
    lon = FloatField()
    address = DictField(child=CharField())


class AddressSerializer(ModelSerializer):
    latitude = FloatField(source="location.y", read_only=True)
    longitude = FloatField(source="location.x", read_only=True)

    class Meta:
        model = Address
        fields = [
            "uuid",
            "street",
            "address_line",
            "district",
            "city",
            "region",
            "postal_code",
            "country",
            "latitude",
            "longitude",
            "raw_data",
            "api_response",
            "user",
        ]
        read_only_fields = [
            "latitude",
            "longitude",
            "raw_data",
            "api_response",
        ]


class AddressCreateSerializer(ModelSerializer):
    raw_data = CharField(
        write_only=True,
        max_length=512,
    )
    address_line_1 = CharField(write_only=True, max_length=128, required=False)
    address_line_2 = CharField(write_only=True, max_length=128, required=False)

    class Meta:
        model = Address
        fields = ["raw_data", "address_line_1", "address_line_2"]

    def create(self, validated_data):
        raw = validated_data.pop("raw_data")
        user = None
        if self.context["request"].user.is_authenticated:
            user = self.context["request"].user
        return Address.objects.create(raw_data=raw, user=user, **validated_data)


class DoFeedbackSerializer(Serializer):
    comment = CharField(required=True)
    rating = IntegerField(min_value=1, max_value=10, default=10)
    action = CharField(default="add")

    def validate(self, data):
        if data["action"] == "add" and not all([data["comment"], data["rating"]]):
            raise ValidationError(_("you must provide a comment, rating, and order product uuid to add feedback."))
