from django.db import models
from NEMO.constants import CHAR_FIELD_MEDIUM_LENGTH, MEDIA_PROTECTED
from NEMO.models import BaseModel, BaseDocumentModel, User
from django.utils.translation import gettext_lazy as _
from django.core.exceptions import ValidationError

from NEMO_billing.models import Institution, CoreFacility


class InstitutionAgreement(BaseModel):
    agreement_id = models.CharField(
        max_length=CHAR_FIELD_MEDIUM_LENGTH, unique=True, help_text=_("The unique ID for this agreement")
    )
    name = models.CharField(max_length=CHAR_FIELD_MEDIUM_LENGTH, help_text=_("The name of the agreement"))
    institution = models.ForeignKey(
        Institution,
        blank=False,
        null=False,
        on_delete=models.PROTECT,
        help_text=_("The institution this agreement is for"),
    )
    core_facilities = models.ManyToManyField(
        CoreFacility,
        blank=True,
        help_text="Core facilities that are covered under this agreement.",
    )
    start_date = models.DateField(
        blank=False,
        null=False,
        help_text=_("The date this agreement goes into effect."),
    )
    expiration_date = models.DateField(
        blank=True,
        null=True,
        help_text=_("The date this agreement expires."),
    )
    reminder_date = models.DateField(
        blank=True,
        null=True,
        help_text=_("The date to send a reminder about this agreement's expiration."),
    )
    owner = models.ForeignKey(
        User,
        blank=False,
        null=False,
        on_delete=models.PROTECT,
        help_text=_("The owner of this agreement."),
    )
    point_of_contact_name = models.CharField(
        max_length=CHAR_FIELD_MEDIUM_LENGTH,
        blank=False,
        null=False,
        help_text=_("The name of the point of contact for this agreement."),
    )
    point_of_contact_email = models.EmailField(
        max_length=CHAR_FIELD_MEDIUM_LENGTH,
        blank=False,
        null=False,
        help_text=_("The email address of the point of contact for this agreement."),
    )

    class Meta:
        ordering = ["-start_date", "name"]

    def clean(self):
        errors = {}
        if self.expiration_date and self.start_date and self.expiration_date <= self.start_date:
            errors["expiration_date"] = "Expiration date must be after start date"
        if self.reminder_date and self.start_date and self.reminder_date < self.start_date:
            errors["reminder_date"] = "Reminder date must be after start date"
        if self.expiration_date and self.reminder_date and self.reminder_date >= self.expiration_date:
            errors["reminder_date"] = "Reminder date must be before or on the expiration date"

        if len(errors) > 0:
            raise ValidationError(errors)

    def __str__(self):
        return f"{self.name} ({self.agreement_id})"


class InstitutionAgreementDocuments(BaseDocumentModel):
    agreement = models.ForeignKey(InstitutionAgreement, on_delete=models.CASCADE)

    def get_filename_upload(self, filename):
        from django.template.defaultfilters import slugify

        name = slugify(self.agreement.name)
        return f"{MEDIA_PROTECTED}/institution_agreements/{name}/{filename}"

    class Meta(BaseDocumentModel.Meta):
        verbose_name_plural = "Service agreement documents"
