"""Notification app serializers."""
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers

from location.serializers import CountrySimpleSerializer
from notification import models
from notification.tasks import send_subscribes_update_email
from utils.methods import get_user_ip
from utils.serializers import TranslatedField


class SubscriptionTypeSerializer(serializers.ModelSerializer):
    """Subscription type serializer."""

    name_translated = TranslatedField()
    country = CountrySimpleSerializer()

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

        model = models.SubscriptionType
        fields = (
            'id',
            'index_name',
            'name_translated',
            'country',
        )


class CreateAndUpdateSubscribeSerializer(serializers.ModelSerializer):
    """Create and Update Subscribe serializer."""

    email = serializers.EmailField(required=False, source='send_to')
    subscription_types = serializers.PrimaryKeyRelatedField(many=True, queryset=models.SubscriptionType.objects.all())
    country_code = serializers.CharField(required=False, allow_blank=True)

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

        model = models.Subscriber
        fields = (
            'id',
            'email',
            'subscription_types',
            'link_to_unsubscribe',
            'country_code',
            'update_code'
        )
        read_only_fields = ('link_to_unsubscribe', 'update_code')

    def validate(self, attrs):
        """Validate attrs."""
        request = self.context.get('request')
        user = request.user

        # validate email
        email = attrs.pop('send_to')

        if attrs.get('email'):
            email = attrs.get('email')

        if user.is_authenticated:
            if email is not None and email != user.email:
                raise serializers.ValidationError(_('Does not match user email'))
        else:
            if email is None:
                raise serializers.ValidationError({'email': _('This field is required.')})

        # append info
        attrs['email'] = email

        if request.country_code:
            attrs['country_code'] = request.country_code

        else:
            attrs['country_code'] = attrs.get('country_code')

        attrs['locale'] = request.locale
        attrs['ip_address'] = get_user_ip(request)

        if user.is_authenticated:
            attrs['user'] = user

        return attrs

    def create(self, validated_data):
        """Create obj."""

        subscriber = models.Subscriber.objects.make_subscriber(**validated_data)

        if settings.USE_CELERY:
            send_subscribes_update_email.delay(subscriber.pk)
        else:
            send_subscribes_update_email(subscriber.pk)

        return subscriber

    def update(self, instance, validated_data):
        if settings.USE_CELERY:
            send_subscribes_update_email.delay(instance.pk)
        else:
            send_subscribes_update_email(instance.pk)

        return super().update(instance, validated_data)


class UpdateSubscribeSerializer(serializers.ModelSerializer):
    """Update with code Subscribe serializer."""

    subscription_types = serializers.PrimaryKeyRelatedField(many=True, queryset=models.SubscriptionType.objects.all())

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

        model = models.Subscriber
        fields = (
            'subscription_types',
            'link_to_unsubscribe',
            'update_code'
        )
        read_only_fields = ('link_to_unsubscribe', 'update_code')

    def validate(self, attrs):
        """Validate attrs."""
        request = self.context.get('request')
        user = request.user

        if request.country_code:
            attrs['country_code'] = request.country_code

        else:
            attrs['country_code'] = attrs.get('country_code')

        attrs['locale'] = request.locale
        attrs['ip_address'] = get_user_ip(request)

        if user.is_authenticated:
            attrs['user'] = user

        return attrs

    def update(self, instance, validated_data):
        if settings.USE_CELERY:
            send_subscribes_update_email.delay(instance.pk)
        else:
            send_subscribes_update_email(instance.pk)

        return super().update(instance, validated_data)


class SubscribeObjectSerializer(serializers.ModelSerializer):
    """Subscription type serializer."""

    subscription_type = serializers.SerializerMethodField()

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

        model = models.Subscribe
        fields = (
            'subscribe_date',
            'unsubscribe_date',
            'subscription_type'
        )
        extra_kwargs = {
            'subscribe_date': {'read_only': True},
        }

    def get_subscription_type(self, instance):
        return SubscriptionTypeSerializer(
            models.SubscriptionType.objects.get(pk=instance.old_subscription_type_id)
        ).data


class SubscribeSerializer(serializers.ModelSerializer):
    """Subscribe serializer."""

    email = serializers.EmailField(required=False, source='send_to')
    subscription_types = SubscriptionTypeSerializer(source='active_subscriptions', read_only=True, many=True)
    history = SubscribeObjectSerializer(source='subscription_history', many=True)

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

        model = models.Subscriber
        fields = (
            'email',
            'subscription_types',
            'link_to_unsubscribe',
            'history',
        )


class UnsubscribeSerializer(serializers.ModelSerializer):
    email = serializers.EmailField(read_only=True, required=False, source='send_to')
    subscription_types = SubscriptionTypeSerializer(source='active_subscriptions', read_only=True, many=True)

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

        model = models.Subscriber
        fields = SubscribeSerializer.Meta.fields
