import datetime
from decimal import Decimal
from typing import Optional, List

from pydantic import condecimal

from watcher.enums import ShiftStatus
from .base import BaseSchema, optional
from .staff import StaffSchema, StaffCompactSchema
from .slot import SlotShortSchema
from .schedule import ScheduleRichListSchema, ScheduleABCSchema


class ShiftBaseSchema(BaseSchema):
    slot_id: Optional[int]
    start: datetime.datetime
    end: datetime.datetime
    status: ShiftStatus
    approved: bool
    approved_by_id: Optional[int]
    approved_at: Optional[datetime.datetime]
    empty: bool
    replacement_for_id: Optional[int]
    schedule_id: Optional[int]
    staff_id: Optional[int]
    is_primary: Optional[bool]


class ShiftReplacementForSchema(ShiftBaseSchema):
    id: int
    is_primary: bool


class ShiftListSchema(ShiftBaseSchema):
    id: int
    staff: Optional[StaffSchema]
    slot: Optional[SlotShortSchema]
    replacement_for: Optional[ShiftReplacementForSchema]
    is_primary: bool


class ShiftRichListSchema(ShiftListSchema):
    schedule: ScheduleRichListSchema


class ShiftRatingSchema(BaseSchema):
    staff: StaffSchema
    rating: condecimal(ge=Decimal(0))


class ShiftPatchSchema(BaseSchema):
    staff_id: Optional[int]
    empty: Optional[bool]
    approved: Optional[bool]
    is_primary: Optional[bool]


class ShiftABCListSchema(BaseSchema):
    id: int
    schedule_id: int
    staff_id: Optional[int]
    start: datetime.datetime
    end: datetime.datetime
    is_primary: bool
    approved: bool
    schedule: ScheduleABCSchema
    staff: Optional[StaffCompactSchema]


@optional(
    'id',
    'slot_id',
    'status',
    'approved',
    'approved_by_id',
    'approved_at',
    'empty',
    'schedule_id',
    'staff_id',
    'replacement_for_id',
    'is_primary'
)
class ShiftPutSchema(ShiftBaseSchema):
    id: int
    approved: bool = True


class SubShiftsPutSchema(BaseSchema):
    sub_shifts: List[ShiftPutSchema]


class ShiftUploadSchema(BaseSchema):
    slot_id: Optional[int]
    start: datetime.datetime
    end: datetime.datetime
    approved: Optional[bool] = True
    empty: bool = False
    staff_login: Optional[str]
    is_primary: Optional[bool]


class ShiftsUploadSchema(BaseSchema):
    shifts: List[ShiftUploadSchema]
    replace: bool = False
    schedule_id: int
