from django.db import models
from django.conf import settings
from django.urls import reverse


# from autoslug import AutoSlugField


class Cases(models.Model):
    '''Абстрактный класс для описания падежей'''
    class Meta:
        abstract = True

    nominative = models.CharField(verbose_name='Именительный', max_length=50)
    genitive = models.CharField(verbose_name="Родительный", max_length=50)
    dative = models.CharField(verbose_name="Дательный", max_length=50)

    def __str__(self):
        return f'{self.nominative}/{self.genitive}/{self.dative}'


# Модели для хранения ФИО в разных падежах
class SurnameCases(models.Model):
    '''Падежи фамилии'''
    genitive = models.CharField("Родительный", max_length=50)
    dative = models.CharField("Дательный", max_length=50)

    class Meta:
        verbose_name = "Падеж фамилии"
        verbose_name_plural = "Падежи фамилии"
        ordering = [
            'genitive',
        ]

    def __str__(self):
        return f'{self.genitive}/{self.dative}'

    def get_absolute_url(self):
        return reverse(viewname="surname_cases_detail", kwargs={"pk": self.pk})


class NameCases(models.Model):
    '''Падежи имени'''
    genitive = models.CharField("Родительный", max_length=50)
    dative = models.CharField("Дательный", max_length=50)

    class Meta:
        verbose_name = "Падеж имени"
        verbose_name_plural = "Падежи имени"
        ordering = [
            'genitive',
        ]

    def __str__(self):
        return f'{self.genitive}/{self.dative}'

    def get_absolute_url(self):
        return reverse(viewname="name_cases_detail", kwargs={"pk": self.pk})


class Patronymic_cases(models.Model):
    '''Падежи отчества'''
    genitive = models.CharField(verbose_name="Родительный", max_length=50)
    dative = models.CharField(verbose_name="Дательный", max_length=50)

    class Meta:
        verbose_name = "Падеж отчества"
        verbose_name_plural = "Падежи отчества"
        ordering = [
            'genitive',
        ]

    def __str__(self):
        return f'{self.genitive}/{self.dative}'

    def get_absolute_url(self):
        return reverse(viewname="patronymic_cases_detail", kwargs={"pk": self.pk})


class Humans(models.Model):
    '''
    Абстрактная модель человека, чтоб не повторять одинаковые поля во всех моделях
    '''
    class Meta:
        abstract = True

    surname = models.CharField(verbose_name='Фамилия', max_length=30)
    surname_cases = models.ForeignKey(SurnameCases, verbose_name="падежи фамилии", on_delete=models.PROTECT, blank=True,
                                      null=True)
    name = models.CharField(verbose_name='Имя', max_length=20)
    name_cases = models.ForeignKey(NameCases, verbose_name="падежи имени", on_delete=models.PROTECT, blank=True,
                                   null=True)
    patronymic = models.CharField(verbose_name='Отчество', max_length=25, blank=True)
    patronymic_cases = models.ForeignKey(Patronymic_cases, verbose_name="падежи отчества", on_delete=models.PROTECT,
                                         blank=True, null=True)
    birthdate = models.DateField(verbose_name='День рождения', blank=True, null=True)
    gender = models.CharField(verbose_name="Пол", max_length=4, choices=settings.GENDER, blank=False, default='муж.')
    phone = models.CharField(verbose_name='Номер телефона', max_length=20, blank=True)
    e_mail = models.CharField(verbose_name='Электронная почта', max_length=70, blank=True)
    added_at = models.DateTimeField(verbose_name="Добавлен", auto_now=False, auto_now_add=True)

    def __str__(self) -> str:
        return f'{self.surname} {str(self.name)[0]}. {str(self.patronymic)[0]}.'
    
    def fio_genetive(self) -> str:
        '''формирование фио в родительном падеже'''
        return f'{self.client.surname_cases.genitive} {self.client.name_cases.genitive} {self.client.patronymic_cases.genitive}'

    def fio_dative(self) -> str:
        '''формирование укороченного фио в дательном падеже'''
        return f'{self.client.surname_cases.dative} {self.client.name_cases.dative[:1]}. {self.client.patronymic_cases.dative[:1]}.'



class PassportDepartment(models.Model):
    ''' подразделения выдачи паспорта '''
    code = models.CharField(verbose_name="Код подразделения", max_length=7)
    title = models.CharField(verbose_name="Наименование подразделения", max_length=255)

    def __str__(self) -> str:
        return f'{self.code} | {self.title}'

    class Meta:
        verbose_name = 'Паспортное подразделение'
        verbose_name_plural = 'Паспортные подразделения'


class Passports(models.Model):
    ''' паспорт '''
    series = models.CharField(verbose_name="Серия", max_length=5)
    number = models.CharField(verbose_name="Номер", max_length=20)
    issued_date = models.DateField(verbose_name="Дата выдачи", auto_now=False, auto_now_add=False)
    issued_department = models.CharField(verbose_name="Наименование подразделения", max_length=150)
    passport_department = models.ForeignKey(PassportDepartment, verbose_name="Код подразделения",
                                            on_delete=models.PROTECT, null=True)
    address_registration = models.TextField(verbose_name="Адрес проживания")

    def __str__(self) -> str:
        return f'серия:{self.series} номер:{self.number} дата получения {self.issued_date}'

    class Meta:
        verbose_name = 'Паспорт'
        verbose_name_plural = 'Паспорта'


class Diplomas(models.Model):
    series = models.CharField(verbose_name="Серия", max_length=8)
    number = models.CharField(verbose_name="Номер", max_length=20)
    issued_date = models.DateField(verbose_name="Дата выдачи", auto_now=False, auto_now_add=False)

    def __str__(self) -> str:
        return f'серия:{self.series} номер:{self.number} дата получения {self.issued_date}'

    class Meta:
        verbose_name = 'Полученный Диплом'
        verbose_name_plural = 'Полученные Дипломы'


class Customers(Humans):
    ''' модель заказчика, если договор заключается не на студента '''
    passport = models.ForeignKey(Passports, verbose_name="Паспорт", on_delete=models.PROTECT, blank=True, null=True)

    def get_absolute_url(self):
        return reverse(viewname="customer", kwargs={"customer_id": self.pk})

    class Meta:
        verbose_name = 'Заказчика'
        verbose_name_plural = 'Заказчики'
        ordering = [
            'surname',
            'name',
        ]


class Students(Humans):
    ''' модель обучающегося/студента '''
    photo = models.ImageField(verbose_name="Фото", upload_to='photos/%Y/%m/%d/', blank=True)
    passport = models.ForeignKey(Passports, verbose_name="Паспорт", on_delete=models.PROTECT, blank=True, null=True)
    snils = models.CharField(verbose_name="Номер СНИЛС", max_length=50, blank=True)
    diploma = models.ForeignKey(Diplomas, verbose_name="Диплом", on_delete=models.PROTECT, blank=True, null=True)

    def get_absolute_url(self):
        return reverse(viewname="student", kwargs={"student_id": self.pk})

    class Meta:
        verbose_name = 'Студента'
        verbose_name_plural = 'Студенты'
        ordering = [
            'surname',
            'name',
        ]


# Модели сотрудников 
class Post(models.Model):
    title = models.CharField(verbose_name="Должность", max_length=50)

    def __str__(self) -> str:
        return f'{self.title}'


class Degree(models.Model):
    title = models.CharField(verbose_name="Степень", max_length=50)

    def __str__(self) -> str:
        return f'{self.title}'


class Grade(models.Model):
    title = models.CharField(verbose_name="Звание", max_length=50)

    def __str__(self) -> str:
        return f'{self.title}'


class Emploees(Humans):
    '''Сотрудники'''
    degree = models.ForeignKey(Degree, verbose_name="Ученая степень", on_delete=models.PROTECT, blank=True, null=True)
    grade = models.ForeignKey(Grade, verbose_name="Звание", on_delete=models.PROTECT, blank=True, null=True)
    post = models.ForeignKey(Post, verbose_name="Должность", on_delete=models.PROTECT, blank=True, null=True)
    department = models.CharField(verbose_name="Подразделение", max_length=255)
    photo = models.ImageField(verbose_name="Фото", upload_to='photos/%Y/%m/%d/', blank=True)

    class Meta:
        verbose_name = 'Сотрудника'
        verbose_name_plural = 'Сотрудники'
        ordering = [
            'surname',
            'name',
        ]


class Groups(models.Model):
    ''' Учебные группы '''
    title = models.CharField(verbose_name="Обозначение", max_length=50, unique=True, db_index=True)
    graduation_at = models.CharField(verbose_name='Год выпуска', max_length=4)
    graduation_date = models.DateField(verbose_name="Дата выпуска", auto_now=False, auto_now_add=False, null=True)

    def get_absolute_url(self):
        return reverse(viewname="group", kwargs={"group_id": self.pk})

    def __str__(self) -> str:
        return f'{self.title}'

    class Meta:
        verbose_name = 'Группа'
        verbose_name_plural = 'Группы'
        ordering = [
            '-graduation_date',
            '-title',
        ]


class Structures(models.Model):
    ''' Текущие структуры университета '''
    warrant_number = models.CharField(verbose_name="Доверенность №", max_length=15)
    warrant_date = models.DateField(verbose_name="Доверенность от", default='2022-05-05')
    director_ido = models.ForeignKey(Emploees, verbose_name="Директор ИДО", related_name='dir_ido',
                                     on_delete=models.PROTECT)
    responsible_ido = models.CharField(verbose_name="Ответственный от ИДО", max_length=50)
    res_ido = models.ForeignKey(Emploees, verbose_name="Ответственный от ИДО", related_name='res_ido',
                                on_delete=models.PROTECT)
    responsible_def = models.CharField(verbose_name="Ответственный от ДЭиФ", max_length=50)
    res_def = models.ForeignKey(Emploees, verbose_name='Ответственный от ДЭиФ', related_name='res_def',
                                on_delete=models.PROTECT)
    rector = models.CharField(verbose_name="Ректор", max_length=50, blank=True, null=True)

    class Meta:
        verbose_name = 'Структуру'
        verbose_name_plural = 'Структуры'
        ordering = [
            '-warrant_date',
        ]

    def __str__(self) -> str:
        return (f"Доверенность № {self.warrant_number} от {self.warrant_date:%d.%m.%Y}"
                f" на имя {self.director_ido.surname_cases.genitive}"
                f" {self.director_ido.name_cases.genitive}"
                f" {self.director_ido.patronymic_cases.genitive}"
                )


# Модель для шаблонов файлов
class Template_files(models.Model):
    ''' шаблоны файлов '''
    date = models.DateField(verbose_name="Дата шаблона", auto_now=False, auto_now_add=True)
    title = models.CharField(verbose_name="Название", max_length=50)
    file = models.FileField(verbose_name="Файл шаблона", upload_to='templates/%Y/%m', blank=True)

    class Meta:
        verbose_name = "Шаблон"
        verbose_name_plural = "Шаблоны"

    def __str__(self):
        return f'{self.title} от {self.date:%d-%m-%Y}'

    # def get_absolute_url(self):
    #     return reverse("template_files_detail", kwargs={"pk": self.pk})


# Модели необходимые для ВКР
class Questions(models.Model):
    body = models.TextField("Вопрос")
    member = models.ForeignKey(Emploees, verbose_name="Член комиссии", on_delete=models.PROTECT)
    # protocol_id = models.ForeignKey('Protocols', verbose_name='Протокол', on_delete=models.PROTECT, null=True)

    class Meta:
        verbose_name = "Вопрос"
        verbose_name_plural = "Вопросы"

    def __str__(self):
        return f'{self.member.surname} {self.member.name[:1]}. {self.member.patronymic[:1]}. - {self.body}'

    def get_absolute_url(self):
        return reverse(viewname="questions_detail", kwargs={"question_pk": self.pk})


class Protocols(models.Model):
    number = models.IntegerField(verbose_name="Номер протокола")
    date_time = models.DateTimeField(verbose_name="Дата и время протокола", auto_now=False, auto_now_add=False)
    questions = models.ManyToManyField(Questions, verbose_name="Вопросы")
    template = models.ForeignKey(Template_files, verbose_name="Шаблон", on_delete=models.PROTECT)

    class Meta:
        verbose_name = "Протокол"
        verbose_name_plural = "Протоколы"
        ordering = [
            '-date_time',
        ]

    def __str__(self):
        return f'№{self.number} от {self.date_time}'

    def get_absolute_url(self):
        return reverse(viewname="get_protocol", kwargs={"protocol_pk": self.pk})


class Degree_works(models.Model):
    title = models.CharField(verbose_name="Тема работы", max_length=200)
    adviser = models.ForeignKey(Emploees, verbose_name="Руководитель работы", on_delete=models.PROTECT)
    protocol = models.ForeignKey(Protocols, verbose_name="Протокол защиты", on_delete=models.PROTECT, blank=True,
                                 null=True)
    score = models.CharField(verbose_name="Оценка", max_length=40, choices=settings.SCORE, blank=False,
                             default='хорошо')
    registration_number = models.IntegerField(verbose_name='Регистрационный номер', blank=True, null=True)
    diploma_number = models.CharField(verbose_name='Номер диплома', max_length=45, blank=True, null=True)

    class Meta:
        verbose_name = "ВКР"
        verbose_name_plural = "ВКР"

    def __str__(self):
        return f'"{self.title}". рук - {self.adviser}'

    def get_absolute_url(self):
        return reverse(viewname="degree_work_detail", kwargs={"degree_work_pk": self.pk})


class Contracts(models.Model):
    number = models.CharField(verbose_name="Номер договора", max_length=20,
                              unique=True)  # , default=f"П08.{datetime.now:%y}")
    agreement_date = models.DateField(verbose_name="Дата заключения", auto_now=False, auto_now_add=False,
                                      default='2022-05-05')
    start_date = models.DateField(verbose_name="Начало обучения")
    end_date = models.DateField(verbose_name="Окончание обучения")
    payment_date1 = models.DateField(verbose_name="Дата оплаты 1 семестра", default='2021-09-30')
    payment_date2 = models.DateField(verbose_name="Дата оплаты 2 семестра", default='2022-02-01')
    payment_date3 = models.DateField(verbose_name="Дата оплаты 3 семестра", default='2022-09-01')
    client = models.ForeignKey(Students, verbose_name="Обучающийся", on_delete=models.PROTECT)
    customer = models.ForeignKey(Customers, verbose_name="Заказчик", on_delete=models.PROTECT, blank=True, null=True)
    structure = models.ForeignKey(Structures, verbose_name='Текущая структура', on_delete=models.PROTECT)
    scan = models.FileField(verbose_name="Скан документа", upload_to='pdf/contracts/%Y/%m/', blank=True)
    group = models.ForeignKey(Groups, verbose_name="Группа", on_delete=models.PROTECT)
    degree_work = models.ForeignKey(Degree_works, verbose_name="ВКР", on_delete=models.PROTECT, blank=True, null=True)

    def get_absolute_url(self):
        return reverse(viewname="contract", kwargs={"contract_id": self.pk})

    def get_gen_diploma_url(self):
        return reverse(viewname="gen_diploma_form", kwargs={"contract_id":self.pk})

    def get_gen_supplement_url(self):
        return reverse(viewname="gen_diploma_supplement", kwargs={"contract_id":self.pk})

    class Meta:
        verbose_name = 'Договор'
        verbose_name_plural = 'Договоры'
        ordering = [
            '-agreement_date',
            '-number',
            # 'title',
        ]

    def __str__(self) -> str:
        customer = f' заказчик - {self.customer.surname} {self.customer.name[0]}. {self.customer.patronymic[0]}.' if self.customer else ''
        dip_title = f' - {self.degree_work}' if not self.degree_work == None else ''
        return f'Договор № {self.number} - {self.client.surname} {self.client.name[0]}. {self.client.patronymic[0]}.' + customer + dip_title


# Приказы
# Выписки
class Extracts(models.Model):
    number = models.CharField(verbose_name="Номер протокола", max_length=5)
    date = models.DateField(verbose_name="Дата", auto_now=False, auto_now_add=False)
    speaker = models.ForeignKey(Emploees, verbose_name="Докладчик", related_name='speaker', on_delete=models.PROTECT)
    secretary = models.ForeignKey(Emploees, verbose_name="Секретарь", related_name='secretary',
                                  on_delete=models.PROTECT)
    department = models.CharField(verbose_name="Подразделение", max_length=255)

    class Meta:
        verbose_name = "Выписку"
        verbose_name_plural = "Выписки"

    def __str__(self):
        return f'Выписка из протокола № {self.number} от {self.date}'

    def get_absolute_url(self):
        return reverse(viewname="extract", kwargs={"extract_id": self.pk})


class Orders(models.Model):
    number = models.CharField(verbose_name="Номер", max_length=50, blank=True)
    registered = models.DateField(verbose_name="от", auto_now=False, auto_now_add=False, blank=True)
    event_date = models.DateField(verbose_name="дата вступления в силу", auto_now=False, auto_now_add=False)
    type_order = models.ForeignKey("Order_types", verbose_name="Тип приказа", on_delete=models.PROTECT)
    contracts = models.ManyToManyField(Contracts, verbose_name="Студенты", blank=True)
    emploees = models.ManyToManyField(Emploees, verbose_name="Сотрудники", blank=True)
    structure = models.ForeignKey(Structures, verbose_name='Текущая структура', on_delete=models.PROTECT)
    scan = models.FileField(verbose_name="Скан документа", upload_to='pdf/orders/%Y/%m/', blank=True)
    extract = models.ForeignKey(Extracts, verbose_name="Выписка", on_delete=models.PROTECT, blank=True, null=True)
    template = models.ForeignKey(Template_files, verbose_name="Шаблон", on_delete=models.PROTECT, blank=True, null=True)

    def get_absolute_url(self):
        return reverse(viewname="get_order", kwargs={"order_id": self.pk})

    class Meta:
        verbose_name = 'Приказ'
        verbose_name_plural = 'Приказы'
        ordering = [
            '-registered',
        ]

    def __str__(self) -> str:
        return f'{self.type_order} № {self.number} от {self.registered}'


class Order_types(models.Model):
    title = models.CharField(verbose_name="Наименование", max_length=150)
    body = models.TextField(verbose_name="Текст вводной", blank=True)
    footer = models.TextField(verbose_name="Основание")

    def __str__(self) -> str:
        return f'Приказ {self.title}'


# Справки
class Sertificates(models.Model):
    number = models.CharField(verbose_name="Исходящий номер", max_length=50, blank=True)
    registered = models.DateField(verbose_name="Зарегистрирована", auto_now=False, auto_now_add=False, blank=True)
    order = models.ForeignKey(Orders, verbose_name="Приказ", on_delete=models.PROTECT)
    contract = models.ForeignKey(Contracts, verbose_name="Договор", on_delete=models.PROTECT)
    scan = models.FileField(verbose_name="Скан документа", upload_to='pdf/sertificates/%Y/%m/', blank=True)

    class Meta:
        verbose_name = "Справку"
        verbose_name_plural = "Справки"

    def __str__(self) -> str:
        return f"{self.contract.client} по приказу {self.order}"

    def get_absolute_url(self):
        return reverse(viewname="sertificate", kwargs={"sertificate_id": self.pk})


class Access_lists(models.Model):
    registration_date = models.DateField(verbose_name='от')
    number = models.CharField(verbose_name="Номер", max_length=10, blank=True)
    students = models.ManyToManyField(Contracts, verbose_name='Студенты', blank=True)
    template = models.ForeignKey(Template_files, verbose_name="Шаблон", on_delete=models.PROTECT, blank=True, null=True)

    class Meta:
        verbose_name = "Пропуск"
        verbose_name_plural = "Пропуски"

    def __str__(self) -> str:
        return f"{self.registration_date} "

    def get_absolute_url(self):
        return reverse(viewname="get_acces", kwargs={"acces_id": self.pk})

    def gen_absolute_url(self):
        return reverse(viewname="gen_acces", kwargs={"acces_id": self.pk})
