from typing import Optional, List, Any
from datetime import datetime

from ....core.enums.state import State
from ....core.interfaces.dto import Dto
from ....core.interfaces.core import Core
from ....core.interfaces.reaction import Reaction
from ....enums.content.posts.status import PostStatus


class Post[Properties: Any](Core[Properties]):
  title: str
  type: Optional[str]

  slug: Optional[str]
  subtitle: Optional[str]

  parent: Optional[str]  # Post ID

  content: str
  summary: Optional[str]

  categories: Optional[List[str]]  # example: ['electronic > laptop', 'pc > laptop']

  state: Optional[State]
  status: PostStatus
  visibility: Optional[str]  # Example: 'public', 'private', 'internal'

  rate: Optional[float]
  votes: Optional[int]
  rating: Optional[float]

  views: Optional[int]
  loves: Optional[int]
  likes: Optional[int]
  dislikes: Optional[int]

  thumbnail: Optional[str]
  attachments: Optional[List[str]]
  featured_image: Optional[str]

  keywords: Optional[List[str]]

  related_posts: Optional[List[str]]
  publication_date: Optional[datetime]

  reactions: Optional[List[Reaction]]


# ----------------------------------------
# Data Transfer Object Interface
# ----------------------------------------


class PostDto[Properties: Any](Dto[Properties]):
  title: str
  type: Optional[str]

  slug: Optional[str]
  subtitle: Optional[str]

  parent: Optional[str]  # Post ID

  content: str
  summary: Optional[str]

  categories: Optional[List[str]]  # example: ['electronic > laptop', 'pc > laptop']

  state: Optional[State]
  status: PostStatus
  visibility: Optional[str]  # Example: 'public', 'private', 'internal'

  rate: Optional[float]
  votes: Optional[int]
  rating: Optional[float]

  views: Optional[int]
  loves: Optional[int]
  likes: Optional[int]
  dislikes: Optional[int]

  thumbnail: Optional[str]
  attachments: Optional[List[str]]
  featured_image: Optional[str]

  keywords: Optional[List[str]]

  related_posts: Optional[List[str]]
  publication_date: Optional[datetime]

  reactions: Optional[List[Reaction]]
