from django.db import models

import functools

from ichec_django_core.models import (
    Member,
    Form,
    TimesStampMixin,
    DefaultPublicMixin,
    SoftDeleteMixin,
    content_file_name,
)

from marinerg_facility.models import Facility


class AccessCall(TimesStampMixin, DefaultPublicMixin, SoftDeleteMixin):

    class Meta:
        verbose_name = "Access Call"
        verbose_name_plural = "Access Calls"

    class StatusChoice(models.TextChoices):
        OPEN = "OPEN", "Open"
        CLOSED = "CLOSED", "Closed"
        DRAFT = "DRAFT", "Draft"

    title = models.CharField(max_length=200)
    description = models.TextField()
    status = models.CharField(
        max_length=10, choices=StatusChoice.choices, default=StatusChoice.DRAFT
    )
    closing_date = models.DateTimeField()
    coordinator = models.ForeignKey(Member, on_delete=models.CASCADE)
    contact_email = models.CharField(max_length=200, null=True)

    board_chair = models.ForeignKey(
        Member, on_delete=models.CASCADE, related_name="chaired_access_boards"
    )
    board_members = models.ManyToManyField(
        Member,
        verbose_name="list of review board members",
        related_name="access_boards",
        blank=True,
    )

    use_facility_review = models.BooleanField(default=False)

    selectable_facilities = models.ManyToManyField(
        Facility,
        verbose_name="Selectable Facilities",
        related_name="selectable_access_calls",
        blank=True,
    )

    applications_summary = models.FileField(
        null=True,
        upload_to=functools.partial(
            content_file_name, "access_call_applications_summary"
        ),
    )

    review_template = models.FileField(null=True)

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

    def __str__(self):
        return self.title

    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() == "closed"
            and self.__last_status.lower() != "closed"
        ):
            self.on_closed()

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

    def on_closed(self):
        for application in self.applications.all():
            if application.status == "SUBMITTED" or application.status == "FACILITY":
                application.status = "BOARD"
                application.save()

    @property
    def resolved_contact_email(self):
        if self.contact_email:
            return self.contact_email
        else:
            return self.coordinator.email

    def get_field_by_key(self, key: str):
        for group in self.form.groups.all():
            for field in group.fields.all():
                if field.key == key:
                    return field
        raise RuntimeError(f"Requested field '{key}' not found")


class AccessCallFacilityReview(TimesStampMixin):

    class Meta:
        verbose_name = "Access Call Facility Review"
        verbose_name_plural = "Access Call Facility Reviews"

    class Decision(models.TextChoices):
        ACCEPT = "ACCEPT", "Accept"
        REJECT = "REJECT", "Reject"

    decision = models.CharField(max_length=10, choices=Decision.choices)
    comments = models.TextField(blank=True)
    call = models.ForeignKey(AccessCall, on_delete=models.CASCADE)
    facility = models.ForeignKey(Facility, on_delete=models.CASCADE)
