from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
from rest_framework.validators import UniqueTogetherValidator
from rest_framework_json_api.relations import ResourceRelatedField

from bluebottle.activities.utils import (
    BaseActivitySerializer, BaseContributionSerializer,
    ActivityValidationSerializer
)
from bluebottle.events.filters import ParticipantListFilter
from bluebottle.events.models import Event, Participant
from bluebottle.geo.models import Geolocation
from bluebottle.transitions.serializers import TransitionSerializer
from bluebottle.utils.serializers import ResourcePermissionField, FilteredRelatedField
from bluebottle.utils.serializers import (
    RelatedField, NonModelRelatedResourceField, NoCommitMixin
)


class ParticipantSerializer(BaseContributionSerializer):

    class Meta(BaseContributionSerializer.Meta):
        model = Participant
        fields = BaseContributionSerializer.Meta.fields + ('time_spent', )

        validators = [
            UniqueTogetherValidator(
                queryset=Participant.objects.all(),
                fields=('activity', 'user')
            )
        ]

    class JSONAPIMeta(BaseContributionSerializer.JSONAPIMeta):
        resource_name = 'contributions/participants'
        included_resources = [
            'user',
            'activity'
        ]

    included_serializers = {
        'activity': 'bluebottle.events.serializers.EventSerializer',
        'user': 'bluebottle.initiatives.serializers.MemberSerializer',
    }


class ParticipantTransitionSerializer(TransitionSerializer):
    resource = ResourceRelatedField(queryset=Participant.objects.all())
    field = 'transitions'
    included_serializers = {
        'resource': 'bluebottle.events.serializers.ParticipantSerializer',
        'resource.activity': 'bluebottle.events.serializers.EventSerializer',
    }

    class JSONAPIMeta:
        resource_name = 'contributions/participant-transitions'
        included_resources = [
            'resource',
            'resource.activity'
        ]


class LocationValidator(object):
    def set_context(self, field):
        self.is_online = field.parent.initial_data['is_online']

    def __call__(self, value):
        if not self.is_online and not value:
            raise serializers.ValidationError(
                _("This field is required or select 'Online'"),
                code='null'
            )

        return value


class RegistrationDeadlineValidator(object):
    def set_context(self, field):
        self.state_date = field.parent.initial_data['start_date']

    def __call__(self, value):
        if value > self.start_date:
            raise serializers.ValidationError(
                _('Registration deadline should be before start time'),
                code='registration_deadline'
            )

        return value


class LocationField(RelatedField):
    def validate_empty_values(self, data):
        return (False, data)


class EventValidationSerializer(ActivityValidationSerializer):
    start_date = serializers.DateField()
    start_time = serializers.TimeField()
    duration = serializers.FloatField()
    registration_deadline = serializers.DateField(allow_null=True)
    is_online = serializers.BooleanField()
    location = LocationField(
        queryset=Geolocation.objects.all(),
        allow_null=True,
        validators=[LocationValidator()]
    )

    def validate(self, data):
        """
        Check that location is set if not online
        """
        if not self.initial_data['is_online'] and not data['location']:
            raise serializers.ValidationError(
                {'location': "Location is required or select 'is online'"}
            )
        if self.initial_data['registration_deadline'] and \
                self.initial_data['registration_deadline'] > self.initial_data['start_date']:
            raise serializers.ValidationError(
                {'registration_deadline': "Registration deadline should be before start time"})
        return data

    class Meta:
        model = Event
        fields = ActivityValidationSerializer.Meta.fields + (
            'start_date', 'start_time', 'is_online', 'location', 'duration',
            'registration_deadline',
        )

    class JSONAPIMeta:
        resource_name = 'activities/event-validations'


class EventListSerializer(BaseActivitySerializer):
    permissions = ResourcePermissionField('event-detail', view_args=('pk',))
    validations = NonModelRelatedResourceField(EventValidationSerializer)

    class Meta(BaseActivitySerializer.Meta):
        model = Event
        fields = BaseActivitySerializer.Meta.fields + (
            'capacity',
            'start_date',
            'start_time',
            'duration',
            'is_online',
            'location',
            'location_hint',
            'permissions',
            'registration_deadline',
            'validations',
        )

    class JSONAPIMeta(BaseContributionSerializer.JSONAPIMeta):
        included_resources = [
            'owner',
            'initiative',
            'initiative.image',
            'location',
            'validations',
        ]
        resource_name = 'activities/events'

    included_serializers = {
        'owner': 'bluebottle.initiatives.serializers.MemberSerializer',
        'initiative': 'bluebottle.initiatives.serializers.InitiativeSerializer',
        'initiative.image': 'bluebottle.initiatives.serializers.InitiativeImageSerializer',
        'location': 'bluebottle.geo.serializers.GeolocationSerializer',
        'validations': 'bluebottle.events.serializers.EventValidationSerializer',
    }


class EventSerializer(NoCommitMixin, EventListSerializer):
    contributions = FilteredRelatedField(many=True, filter_backend=ParticipantListFilter)

    class JSONAPIMeta(EventListSerializer.JSONAPIMeta):
        included_resources = EventListSerializer.JSONAPIMeta.included_resources + [
            'contributions',
            'contributions.user'
        ]
        resource_name = 'activities/events'

    included_serializers = dict(
        EventListSerializer.included_serializers,
        **{
            'contributions': 'bluebottle.events.serializers.ParticipantSerializer',
        }
    )


class EventTransitionSerializer(TransitionSerializer):
    resource = ResourceRelatedField(queryset=Event.objects.all())
    field = 'transitions'
    included_serializers = {
        'resource': 'bluebottle.events.serializers.EventSerializer',
    }

    class JSONAPIMeta:
        included_resources = ['resource', ]
        resource_name = 'event-transitions'

@@ -3436,637 +3436,8 @@
  )%0A%0A
-    def validate(self, data):%0A        %22%22%22%0A        Check that location is set if not online%0A        %22%22%22%0A        if not self.initial_data%5B'is_online'%5D and not data%5B'location'%5D:%0A            raise serializers.ValidationError(%0A                %7B'location': %22Location is required or select 'is online'%22%7D%0A            )%0A        if self.initial_data%5B'registration_deadline'%5D and %5C%0A                self.initial_data%5B'registration_deadline'%5D %3E self.initial_data%5B'start_date'%5D:%0A            raise serializers.ValidationError(%0A                %7B'registration_deadline': %22Registration deadline should be before start time%22%7D)%0A        return data%0A%0A
     

Remove unused validate method