from django.contrib.auth.models import PermissionsMixin
from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
from django.db import models, transaction


class Edition(models.Model):
    year = models.PositiveIntegerField('Rok', unique=True)
    roman = models.CharField('Nr. edycji', max_length=25)

    active = models.BooleanField('Aktualna', default=False)
    submissions = models.BooleanField('Możliwość zgłoszenia drużyny', default=False)

    scores_available = models.BooleanField('Wyniki dostępne dla wszystkich', default=False)
    scores_eliminations = models.BooleanField('Wyniki z eliminacji dostępne dla nauczycieli', default=False)

    entry_threshold = models.IntegerField('Próg punkowy - wejście do finału', default=0)
    award_threshold = models.IntegerField('Próg punktowy - wyróżnienie', default=0)
    laureate_threshold = models.IntegerField('Próg punktowy - tytuł laureata', default=0)

    scores = models.FileField('Wyniki do wczytania', blank=True, upload_to='wyniki',
                              help_text='Uwaga! Wyniki muszą być zawarte w pliku .csv. Kolumny po kolei to odpowiednio: identyfikator ucznia, wynik z eliminacji, wynik z finału.')
    first_test = models.FileField('Zadania eliminacyjne', blank=True, upload_to='eliminacje')
    second_test = models.FileField('Zadania finałowe', blank=True, upload_to='finaly')

    def __str__(self):
        return f'Edycja {self.roman}'

    @staticmethod
    def current():
        return Edition.objects.filter(active=True).first()

    def save(self, *args, **kwargs):
        if self.active is True:
            Edition.objects.exclude(id=self.id).update(active=False)

        super(Edition, self).save(*args, **kwargs)

    class Meta:
        verbose_name = 'Edycja'
        verbose_name_plural = 'Edycje'


class Student(models.Model):
    name = models.CharField('Imię', max_length=50)
    surname = models.CharField('Nazwisko', max_length=50)
    grade = models.PositiveIntegerField('Klasa', choices=map(lambda x: (x, x), range(1, 9)))

    score_first = models.IntegerField('Wynik z eliminacji', default=0)
    score_second = models.IntegerField('Wynik z finału', default=0)

    school_name = models.CharField('Nazwa szkoły', max_length=100, blank=True)
    school_town = models.CharField('Miejscowość', max_length=100, blank=True)
    school_address = models.CharField('Adres', max_length=100, blank=True)

    identifier = models.CharField('Identyfikator', max_length=100, blank=True, editable=True,
                                  help_text='UWAGA - tej wartości należy nie zmieniać')

    def __str__(self):
        return f'{self.surname} {self.name}'

    class Meta:
        verbose_name = 'Uczeń'
        verbose_name_plural = 'Uczniowie'


class Announcement(models.Model):
    title = models.CharField('Tytuł', max_length=250)
    content = models.TextField('Treść')
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'Ogłoszenie'
        verbose_name_plural = 'Ogłoszenia'
        ordering = ['-created_at']


class UserManager(BaseUserManager):
    use_in_migrations = True

    def _create_user(self, email, password, **extra_fields):
        if not email:
            raise ValueError('The given email must be set')

        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(email, password, **extra_fields)

    def create_superuser(self, email, password, **extra_fields):
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('request_notifications', True)
        extra_fields.setdefault('email_notifications', True)

        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        return self._create_user(email, password, **extra_fields)


class School(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField('Adres e-mail', unique=True)
    name = models.CharField('Nazwa szkoły', max_length=100)
    town = models.CharField('Miejscowość', max_length=100)
    address = models.CharField('Adres', max_length=100)
    phone = models.PositiveIntegerField('Numer telefonu', null=True)

    is_staff = models.BooleanField('Staff status', default=False)
    is_active = models.BooleanField('Active status', default=True)
    request_notifications = models.BooleanField('Powiadomienia przy wysłaniu zgłoszenia', default=False)
    email_notifications = models.BooleanField('Powiadomienia przy wysłaniu wiadomości email', default=False)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    def __str__(self):
        return self.name or self.email

    def get_full_name(self):
        return self.email

    def get_short_name(self):
        return self.email

    def updateTeam(self):
        with transaction.atomic():
            identifier = f'{Edition.current().year}-{self.id}-'

            Student.objects.filter(identifier__startswith=identifier).update(
                school_name=self.name,
                school_town=self.town,
                school_address=self.address
            )

    class Meta:
        verbose_name = 'Szkoła'
        verbose_name_plural = 'Szkoły'
