"""This module declareds the pydantic API representation for todo-items."""

from datetime import datetime
from abc import ABC
from typing import Optional

from pydantic import BaseModel, validator

from todo.schemas.common import is_valid_id


class AbstractTodoItemValidator(BaseModel, ABC):
    """Base class for todo-item validators shared with child classes."""

    @validator('title', check_fields=False)
    def assert_title_is_valid(cls, title):
        if title is not None:
            if not len(title):
                raise ValueError("Title must not be empty.")
        return title

    @validator('description', check_fields=False)
    def assert_last_name_is_valid(cls, description):
        if description is not None:
            if not len(description):
                raise ValueError("Description must not be empty.")
        return description


class AbstractTodoItem(AbstractTodoItemValidator, ABC):
    """Base class for todo-item attributes shared with child classes."""

    title: str
    description: str


class TodoItemCreate(AbstractTodoItem):
    """Schema for todo-item creation."""

    pass


class TodoItemUpdate(AbstractTodoItemValidator):
    """Schema for todo-item updates."""

    title: Optional[str]
    description: Optional[str]
    done: Optional[bool]


class TodoItem(AbstractTodoItem):
    """Schema for todo-item displaying."""

    id: int
    done: bool
    created: datetime
    updated: datetime
    finished: datetime | None

    @validator('id')
    def assert_id_is_valid(cls, id):
        if not is_valid_id(id):
            raise ValueError("ID is invalid.")
        return id

    class Config:
        orm_mode = True
