from django.contrib.auth.models import User
from rest_framework.exceptions import ValidationError

from core import serializers
from incident.models import Incident, IncidentRecommendations, IncidentEffect, IncidentCategory
from rotation.enums import Period, WeekDay, Month, RotationType
from rotation.services.cron_utils import schedule_to_dict


class ScheduleSerializer(serializers.Serializer):
    period = serializers.ChoiceField(choices=Period.choices)
    time = serializers.TimeLocalizedTzAwareField(required=False, format='%H:%M:%S')
    week_day = serializers.MultipleChoiceField(choices=WeekDay.choices, required=False)
    month = serializers.MultipleChoiceField(choices=Month.choices, required=False)

    def validate(self, attrs):
        if attrs['period'] == Period.DAY and not attrs.get('time'):
            raise ValidationError({'time': self.error_messages['required']})
        if attrs['period'] == Period.WEEK and not attrs.get('week_day'):
            raise ValidationError({'week_day': self.error_messages['required']})
        if attrs['period'] == Period.MONTH and not attrs.get('month'):
            raise ValidationError({'month': self.error_messages['required']})
        return attrs


class RotationSettingsSerializer(serializers.Serializer):
    rotation_type = serializers.ChoiceField(choices=RotationType.choices)


class SizeRotationSettingsSerializer(RotationSettingsSerializer):
    size_rotation = serializers.IntegerField(min_value=1)


class TimeRotationSettingsSerializer(RotationSettingsSerializer):
    schedule = ScheduleSerializer()


class FullRotationSettingsSerializer(SizeRotationSettingsSerializer, TimeRotationSettingsSerializer):
    schedule = ScheduleSerializer(required=False)

    def to_representation(self, settings_obj):
        if settings_obj.task:
            schedule = settings_obj.task.crontab
            if schedule and settings_obj.rotation_type == RotationType.TIME:
                settings_obj.schedule = schedule_to_dict(schedule)
        return super(FullRotationSettingsSerializer, self).to_representation(settings_obj)


class DumpIncidentSerializer(serializers.ModelSerializer):
    class DumpIncidentCategorySerializer(serializers.ModelSerializer):
        class Meta:
            model = IncidentCategory
            fields = '__all__'

    class DumpIncidentEffectSerializer(serializers.ModelSerializer):
        class Meta:
            model = IncidentEffect
            fields = '__all__'

    class DumpIncidentRecommendationsSerializer(serializers.ModelSerializer):
        class Meta:
            model = IncidentRecommendations
            fields = '__all__'

    class DumpIncidentAssignedToSerializer(serializers.ModelSerializer):
        class Meta:
            model = User
            fields = ('id', 'username', 'first_name')

    category = DumpIncidentCategorySerializer()
    effects = DumpIncidentEffectSerializer(many=True)
    close_recommendations = DumpIncidentRecommendationsSerializer(many=True)
    assigned_to = DumpIncidentAssignedToSerializer()

    class Meta:
        model = Incident
        fields = '__all__'
