import datetime
from typing import Optional, Any

from watcher.enums import ProblemReason, ProblemStatus
from .base import BaseSchema
from watcher.api.schemas.staff import StaffSchema
from pydantic.utils import GetterDict


class ProblemGapGetterDict(GetterDict):
    def get(self, key: str, default: Any = None) -> Any:
        if key in ('title', 'comment') and self._obj.is_manual:
            return getattr(self._obj.gap_settings, key, None)
        else:
            return super().get(key, default)


class ProblemGap(BaseSchema):
    id: int
    staff_id: int
    start: datetime.datetime
    end: datetime.datetime
    type: Optional[str]
    title: Optional[str]
    comment: Optional[str]
    is_manual: bool

    class Config(BaseSchema.Config):
        getter_dict = ProblemGapGetterDict


class ProblemGetterDict(GetterDict):
    def get(self, key: str, default: Any = None) -> Any:
        if key == 'gap':
            if self._obj.manual_gap_id:
                setattr(self._obj.manual_gap, 'is_manual', True)
                return self._obj.manual_gap
            elif self._obj.duty_gap_id:
                setattr(self._obj.duty_gap, 'is_manual', False)
                return self._obj.duty_gap
            else:
                return
        else:
            return super().get(key, default)


class ProblemBaseSchema(BaseSchema):
    id: int
    shift_id: int
    staff_id: Optional[int]
    report_date: Optional[datetime.datetime]
    resolve_date: Optional[datetime.datetime]
    reason: ProblemReason
    status: ProblemStatus
    gap: Optional[ProblemGap]

    class Config(BaseSchema.Config):
        getter_dict = ProblemGetterDict


class ProblemShiftSchema(BaseSchema):
    id: int
    start: datetime.datetime
    end: datetime.datetime
    schedule_id: int
    staff_id: Optional[int]


class ProblemListSchema(ProblemBaseSchema):
    shift: ProblemShiftSchema
    staff: Optional[StaffSchema]
