"""
Pydantic schemas for the magasin app
"""
from typing import List, Optional
from datetime import datetime, timedelta, time
from pydantic import BaseModel, Field


# Records data structure
class RecordBase(BaseModel):
    """Records base schema"""
    place: str = Field(...,
                       title="Name of the RU corresponding the given record")
    date: datetime = Field(..., title="Date of the record")
    density: float = Field(..., title="Estimated density of people")
    waiting_time: Optional[timedelta] = Field(
        title="Estimated waiting time for people coming at this date")


class Record(RecordBase):
    """Database records base schema"""
    id: int

    class Config:
        orm_mode = True


class RecordRead(BaseModel):
    """ Data structure for record in graph """
    name: int
    time: int


class CollaborativeRecords(BaseModel):
    """CollaborativeRecords schema"""
    user_id: Optional[int] = Field(default=None, title="Id of the user timed")
    place: str = Field(..., title="Name of the RU corresponding the given record")
    date: datetime = Field(..., title="Date of the record")
    waiting_time: Optional[timedelta] = Field(default=None, title="Caculated waiting time for timed person")


# Comments Data structure

class CommentBase(BaseModel):
    """Comments base schema"""
    content: str = Field(..., title="Content of the comment posted")


class Comment(CommentBase):
    """Comments reading schema"""
    id: int
    username: str = Field(..., title="Name of the user posting the comment")
    published_at: datetime = Field(..., title="Publication date of the comment")
    place: str = Field(..., title="Name of the RU corresponding the comment")

    class Config:
        orm_mode = True


# News data structure
class NewsBase(BaseModel):
    """News sql table model"""
    title: str = Field(..., title="Title of the news")
    content: str = Field(..., title="Content of the news")
    end_date: datetime = Field(..., title="End date to display the news")
    place: str = Field(..., title="Name of the RU corresponding the news")


class News(NewsBase):
    """Database news base schema"""
    id: Optional[int]
    published_at: datetime = Field(..., title="Publication date of the news")

    class Config:
        orm_mode = True


# Stats data structure
class WaitingTime(BaseModel):
    """Waiting time schema for reading"""
    status: bool = Field(default=False, title="Status of the restaurant for the current hour")
    waiting_time: Optional[timedelta] = Field(default=None, title="Waiting time for the restaurant")
    next_timetable: Optional[str] = Field(default=None, title="Next time the restaurant will be open")


class OpeningHoursBase(BaseModel):
    """Database opening_hours base schema"""
    place: str = Field(...,
                       title="Name of the RU corresponding the given record")
    day: int = Field(..., title="Day of the week")
    open_time: time = Field(..., title="Opening time")
    close_time: time = Field(..., title="Closing time")


class OpeningHours(OpeningHoursBase):
    """Database opening_hours base schema"""
    id: int

    class Config:
        orm_mode = True


class ClosureBase(BaseModel):
    """ Closure schema base """
    place: str = Field(..., title="Name of the restaurant")
    beginning_date: datetime = Field(..., title="Beginning date of closure")
    end_date: datetime = Field(..., title="Ending date of closure")


class Closure(ClosureBase):
    """ Closure schema """
    id: int

    class Config:
        orm_mode = True


class Restaurant(BaseModel):
    """Restaurant schema for reading"""
    name: str
    status: bool
    waiting_time: Optional[timedelta] = Field(default=None, title="Waiting time for the restaurant")
    timetable: str


class Graph(BaseModel):
    """ Data structure for current graph display """
    data: List[RecordRead] = Field(title="Last records list for the restaurant")
    start: Optional[int] = Field(default=None, title="Opening of the RU")
    end: Optional[int] = Field(default=None, title="Closure of the RU")


# User data structure
class User(BaseModel):
    """Database user base schema"""
    id: int
    state: str
    username: str
    cookie: str
    expiration_date: datetime
    admin: Optional[bool] = Field(default=False, title="Set to true to allow access to the admin interface")
