from django.db import models
from django.utils.translation import ugettext_lazy as _


class PersonsFilterException(Exception):
    pass


class BigAutoField(models.AutoField):
    empty_strings_allowed = False
    description = _("Big (8 byte) integer")
    MAX_BIGINT = 9223372036854775807

    def get_internal_type(self):
        return "BigIntegerField"

    def db_type(self, connection):
        if 'mysql' in connection.__class__.__module__:
            return 'bigint AUTO_INCREMENT'
        return super(BigAutoField, self).db_type(connection)


class PersonsFilter(models.Model):
    class Meta:
        unique_together = (('filter_id', 'person', 'department'),)

    persons_count = models.IntegerField(default=0)
    result_hash = models.CharField(max_length=40)
    modified_at = models.DateTimeField(auto_now=True)
    updated_at = models.DateTimeField(auto_now_add=True)

    persons = models.ManyToManyField(
        'django_intranet_stuff.Staff',
        related_name='persons_filters',
        through='PersonToPersonFilter'
    )

    filter_id = models.CharField(
        max_length=40,
        null=True,
        blank=True,
        default=None,
    )
    person = models.OneToOneField(
        'django_intranet_stuff.Staff',
        related_name='direct_filter',
        null=True,
        blank=True,
    )
    department = models.ForeignKey(
        'django_intranet_stuff.Department',
        related_name='direct_filter',
        null=True,
        blank=True,
    )

    def __str__(self):
        return '{}'.format(self.id)

    def save(self, *args, **kwargs):
        check_person_filter_params(
            self.filter_id, self.person, self.department
        )
        return super(PersonsFilter, self).save(*args, **kwargs)


class PersonToPersonFilter(models.Model):
    id = BigAutoField(primary_key=True)
    staff = models.ForeignKey('django_intranet_stuff.Staff')
    personsfilter = models.ForeignKey(PersonsFilter)

    class Meta:
        db_table = 'person_filter_personsfilter_persons'
        unique_together = (('personsfilter', 'staff'),)


def check_person_filter_params(filter_id, person, department):
    curent = (
        0 if filter_id is None else 1,
        0 if person is None else 1,
        0 if department is None else 1,
    )

    possible = {
        (1, 0, 0),
        (1, 1, 0),
        (0, 0, 1),
        (1, 0, 1),
    }
    if curent not in possible:
        raise PersonsFilterException


class SavedPersonsFilter(models.Model):
    class Meta:
        unique_together = (('person', 'persons_filter'),)

    person = models.ForeignKey(
        'django_intranet_stuff.Staff',
        related_name='saved_filters',
    )
    name = models.CharField(max_length=128)
    persons_filter = models.ForeignKey(
        PersonsFilter,
        related_name='saved_filters',
    )

    # Фильтр надо показывать, как закладку
    is_bookmark = models.BooleanField(default=False)
    # Фильтр надо показывать в кабинете
    is_for_cab = models.BooleanField(default=False, db_index=True)

    # Подписки
    absences_subscription = models.BooleanField(default=False)
    birthdays_subscription = models.BooleanField(default=False)

    def __str__(self):
        return '%s(%s)' % (
            self.person.login if self.person else '',
            self.persons_filter.id if self.persons_filter else ''
        )
