"""Location app common serializers."""
from django.contrib.gis.geos import Point
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
from location import models
from utils.serializers import TranslatedField


class CountrySerializer(serializers.ModelSerializer):
    """Country serializer."""

    name_translated = TranslatedField()

    class Meta:
        model = models.Country
        fields = [
            'id',
            'code',
            'svg_image',
            'name_translated',
        ]


class CountrySimpleSerializer(serializers.ModelSerializer):
    """Simple country serializer."""

    name_translated = TranslatedField()

    class Meta:
        """Meta class."""

        model = models.Country
        fields = ('id', 'code', 'name_translated')


class RegionSerializer(serializers.ModelSerializer):
    """Region serializer"""

    country = CountrySerializer(read_only=True)
    country_id = serializers.PrimaryKeyRelatedField(
        source='country',
        queryset=models.Country.objects.all(),
        write_only=True
    )

    class Meta:
        model = models.Region
        fields = [
            'id',
            'name',
            'code',
            'parent_region',
            'country',
            'country_id'
        ]


class CityShortSerializer(serializers.ModelSerializer):
    """Short city serializer"""
    country = CountrySerializer(read_only=True)

    class Meta:
        """Meta class"""
        model = models.City
        fields = (
            'id',
            'name',
            'code',
            'country',
        )


class CitySerializer(serializers.ModelSerializer):
    """City serializer."""
    region = RegionSerializer(read_only=True)
    region_id = serializers.PrimaryKeyRelatedField(
        source='region',
        queryset=models.Region.objects.all(),
        write_only=True
    )
    country_id = serializers.PrimaryKeyRelatedField(
        source='country',
        queryset=models.Country.objects.all(),
        write_only=True
    )
    country = CountrySerializer(read_only=True)

    class Meta:
        model = models.City
        fields = [
            'id',
            'name',
            'region',
            'region_id',
            'country_id',
            'country',
            'postal_code',
            'is_island',
        ]


class AddressBaseSerializer(serializers.ModelSerializer):
    """Serializer for address obj in related objects."""

    latitude = serializers.FloatField(allow_null=True)
    longitude = serializers.FloatField(allow_null=True)

    # todo: remove this fields (backward compatibility)
    geo_lon = serializers.FloatField(source='longitude', allow_null=True,
                                     read_only=True)
    geo_lat = serializers.FloatField(source='latitude', allow_null=True,
                                     read_only=True)

    class Meta:
        """Meta class."""

        model = models.Address
        fields = (
            'id',
            'street_name_1',
            'street_name_2',
            'number',
            'postal_code',
            'latitude',
            'longitude',

            # todo: remove this fields (backward compatibility)
            'geo_lon',
            'geo_lat',
        )

    def validate_latitude(self, value):
        if -90 <= value <= 90:
            return value
        raise serializers.ValidationError(_('Invalid value'))

    def validate_longitude(self, value):
        if -180 <= value <= 180:
            return value
        raise serializers.ValidationError(_('Invalid value'))

    def validate(self, attrs):
        # validate coordinates
        latitude = attrs.pop('latitude', None)
        longitude = attrs.pop('longitude', None)
        if latitude is not None and longitude is not None:
            attrs['coordinates'] = Point(longitude, latitude)
        return attrs


class AddressDetailSerializer(AddressBaseSerializer):
    """Address serializer."""

    city_id = serializers.PrimaryKeyRelatedField(
        source='city', write_only=True,
        queryset=models.City.objects.all())
    city = CitySerializer(read_only=True)

    class Meta(AddressBaseSerializer.Meta):
        """Meta class."""

        fields = AddressBaseSerializer.Meta.fields + (
            'city_id',
            'city',
        )


class WineRegionBaseSerializer(serializers.ModelSerializer):
    """Wine region serializer."""
    country = CountrySerializer()

    class Meta:
        """Meta class."""
        model = models.WineRegion
        fields = [
            'id',
            'name',
            'country',
        ]


class WineSubRegionBaseSerializer(serializers.ModelSerializer):
    """Wine sub region serializer."""

    class Meta:
        """Meta class."""
        model = models.WineSubRegion
        fields = [
            'id',
            'name',
        ]


class EstablishmentWineRegionBaseSerializer(serializers.ModelSerializer):
    """Establishment wine region origin serializer."""

    id = serializers.IntegerField(source='wine_region.id')
    name = serializers.CharField(source='wine_region.name')
    country = CountrySerializer(source='wine_region.country')

    class Meta:
        """Meta class."""
        model = models.EstablishmentWineOriginAddress
        fields = [
            'id',
            'name',
            'country',
        ]


class EstablishmentWineOriginBaseSerializer(serializers.ModelSerializer):
    """Serializer for intermediate model EstablishmentWineOrigin."""
    wine_region = WineRegionBaseSerializer()
    wine_sub_region = WineSubRegionBaseSerializer(allow_null=True)

    class Meta:
        """Meta class."""
        model = models.EstablishmentWineOriginAddress
        fields = [
            'wine_region',
            'wine_sub_region',
        ]


class WineOriginRegionBaseSerializer(EstablishmentWineRegionBaseSerializer):
    """Product wine region origin serializer."""

    class Meta(EstablishmentWineRegionBaseSerializer.Meta):
        """Meta class."""
        model = models.WineOriginAddress


class WineOriginBaseSerializer(EstablishmentWineOriginBaseSerializer):
    """Serializer for intermediate model ProductWineOrigin."""

    class Meta(EstablishmentWineOriginBaseSerializer.Meta):
        """Meta class."""
        model = models.WineOriginAddress


class WineRegionSerializer(serializers.ModelSerializer):
    """Wine region w/ sub region serializer"""

    wine_sub_region = WineSubRegionBaseSerializer(source='wine_region.wine_sub_region',
                                                  allow_null=True, many=True)

    class Meta(WineRegionBaseSerializer.Meta):
        fields = WineRegionBaseSerializer.Meta.fields + [
            'wine_sub_region'
        ]
