import functools

from django.db import models
from django.utils import timezone

from ichec_django_core.models import (
    Member,
    TimesStampMixin,
    PopulatedForm,
    content_file_name,
)

from marinerg_facility.models import Facility

from .access_call import AccessCall
from .summary import generate_summary
from .email import send_application_submit_emails


class AccessApplication(TimesStampMixin):

    class Meta:
        verbose_name = "Access Application"
        verbose_name_plural = "Access Application"

    class Status(models.TextChoices):
        CREATED = "CREATED", "Created"
        SUBMITTED = "SUBMITTED", "Submitted"
        AWAITING_FACILITY_REVIEW = "FACILITY", "Awaiting Facility Review"
        AWAITING_BOARD_REVIEW = "BOARD", "Awaiting Board Review"
        AWAITING_DECISION = "DECISION", "Awaiting Decision"
        ACCEPTED = "ACCEPTED", "Accepted"
        REJECTED = "REJECTED", "Rejected"

    facilities = models.ManyToManyField(
        Facility, related_name="application_choices", blank=True
    )

    chosen_facility = models.ForeignKey(
        Facility, on_delete=models.CASCADE, related_name="applications", null=True
    )

    request_start_date = models.DateTimeField(null=True)
    request_end_date = models.DateTimeField(null=True)
    dates_flexible = models.BooleanField(default=False)

    applicant = models.ForeignKey(Member, on_delete=models.CASCADE)
    call = models.ForeignKey(
        AccessCall, on_delete=models.CASCADE, related_name="applications"
    )

    summary = models.FileField(
        null=True,
        upload_to=functools.partial(content_file_name, "application_summary"),
    )
    status = models.CharField(
        max_length=10, choices=Status.choices, default=Status.CREATED
    )

    form = models.OneToOneField(PopulatedForm, on_delete=models.CASCADE)

    submitted = models.DateTimeField(null=True)
    __last_status = None

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.__last_status = str(self.status)

    def save(self, force_insert=False, force_update=False, *args, **kwargs):

        if (
            str(self.status).lower() == "submitted"
            and self.__last_status.lower() == "created"
        ):
            self.on_submitted()
        self.__last_status = str(self.status)

        super().save(force_insert, force_update, *args, **kwargs)

    def on_submitted(self):

        self.submitted = timezone.now()
        generate_summary(self)
        if False:
            send_application_submit_emails(self)

        if self.call.use_facility_review:
            self.status = "FACILITY"
        else:
            self.status = "BOARD"

    def __str__(self):
        return f"{self.applicant.email} application for '{self.call.title}'"
