from datetime import datetime

from pydantic import BaseModel, Extra
from ichec_django_core.client import (
    Identifiable,
    Timestamped,
    FormCreate,
    FormDetail,
    FormFieldDetail,
    register_types,
    PopulatedFormCreate,
    PopulatedFormDetail,
)


class AccessCallBase(BaseModel, frozen=True):

    title: str
    description: str
    status: str
    closing_date: datetime
    selectable_facilities: list[str] = []


class AccessCallCreate(AccessCallBase, frozen=True):

    form: FormCreate
    use_facility_review: bool
    public: bool
    coordinator: str
    board_chair: str
    board_members: list[str] = []


class AccessCallPublicDetail(Timestamped, AccessCallBase, frozen=True):
    resolved_contact_email: str
    form: FormDetail

    class Config:
        extra = Extra.forbid

    def get_field(self, key: str) -> FormFieldDetail | None:
        for group in self.form.groups:
            for field in group.fields:
                if field.key == key:
                    return field
        return None


class AccessCallReviewerDetail(AccessCallPublicDetail, frozen=True):
    coordinator: str
    board_chair: str
    review_template: str | None


class AccessCallDetail(AccessCallReviewerDetail, frozen=True):

    board_members: list[str] = []
    applications_summary: str | None
    use_facility_review: bool
    public: bool


class AccessCallList(Timestamped, AccessCallBase, frozen=True):

    pass


class ApplicationFieldValueBase(BaseModel, frozen=True):

    value: str
    field: str
    asset: str | None = None


class ApplicationFieldValueCreate(ApplicationFieldValueBase, frozen=True):
    pass


class ApplicationFieldValueDetail(Identifiable, ApplicationFieldValueBase, frozen=True):
    pass


class AccessApplicationBase(BaseModel, frozen=True):
    call: str
    facilities: list[str] = []
    chosen_facility: str | None = None
    request_start_date: datetime | None = None
    request_end_date: datetime | None = None
    dates_flexible: bool = True
    status: str = "SUBMITTED"


class AccessApplicationCreate(AccessApplicationBase, frozen=True):
    form: PopulatedFormCreate


class AccessApplicationDetail(Timestamped, AccessApplicationBase, frozen=True):
    applicant: str
    submitted: datetime | None = None
    form: PopulatedFormDetail


register_types(
    "access_calls",
    {
        "create": AccessCallCreate,
        "detail-public": AccessCallPublicDetail,
        "detail-reviewer": AccessCallReviewerDetail,
        "detail": AccessCallDetail,
        "list": AccessCallList,
    },
)

register_types(
    "access_applications",
    {"create": AccessApplicationCreate, "detail": AccessApplicationDetail},
)
