from django.conf import settings

from .. import exceptions

from .plain import PlainField


class SlotField(PlainField):
    MAX_SLOTS = settings.ACHIEVERY_MAX_SLOTS

    def validate(self, value):
        super(SlotField, self).validate(value)

        if not (value is None or 0 < value <= self.MAX_SLOTS):
            raise exceptions.InvalidSlot(value, data=value)

    def get_related_saves(self, instance):
        """Need to swap slots if a conflict is present"""
        inst_id = instance.id
        inst_slot = getattr(instance, self.name)
        if not inst_slot:
            return ()

        person_id = instance.person.id
        data = {
            self.name: inst_slot,
            'person_id': person_id,
        }
        try:
            stored_self_model = instance.model.__class__.objects.get(pk=inst_id)
        except instance.model.DoesNotExist:
            stored_self_model = None

        stored_self_slot = getattr(stored_self_model, self.name, None)

        try:
            conflicted = (
                instance.model.__class__.objects
                .exclude(id=inst_id).get(**data)
            )
        except instance.model.DoesNotExist:
            return ()
        else:
            setattr(conflicted, self.name, stored_self_slot)
            setattr(stored_self_model, self.name, None)
            return stored_self_model, conflicted
