# retoor <retoor@molodetz.nl>

from __future__ import annotations

from typing import Any, Optional

from pydantic import ConfigDict, Field

from devplacepy.schemas.base import _Out


class UserOut(_Out):
    uid: str = ""
    username: str = ""
    avatar_seed: Optional[str] = None
    bio: Optional[str] = None
    location: Optional[str] = None
    git_link: Optional[str] = None
    website: Optional[str] = None
    level: Optional[int] = None
    xp: Optional[int] = None
    xp_progress_pct: Optional[int] = None
    xp_next_level: Optional[int] = None
    stars: Optional[int] = None
    created_at: Optional[str] = None
    last_seen: Optional[str] = None


class AttachmentOut(_Out):
    uid: str = ""
    filename: Optional[str] = None
    url: Optional[str] = None
    size: Optional[int] = None
    is_image: Optional[bool] = None
    is_video: Optional[bool] = None
    mime_type: Optional[str] = None
    created_at: Optional[str] = None
    can_modify: bool = False


class VotesOut(_Out):
    up: int = 0
    down: int = 0


class ReactionsOut(_Out):
    counts: dict = {}
    mine: list = []


class PollOptionOut(_Out):
    uid: str = ""
    label: Optional[str] = None
    count: Optional[int] = None
    votes: Optional[int] = None
    pct: Optional[int] = None


class PollOut(_Out):
    uid: str = ""
    question: Optional[str] = None
    options: list[PollOptionOut] = []
    total: int = 0
    my_choice: Optional[str] = None
    voted: Optional[str] = None


class BadgeOut(_Out):
    name: Optional[str] = Field(None, alias="badge_name")
    icon: Optional[str] = None
    description: Optional[str] = None
    created_at: Optional[str] = None
    model_config = ConfigDict(populate_by_name=True)


class ProjectLinkOut(_Out):
    uid: str = ""
    name: Optional[str] = None
    slug: Optional[str] = None
    url: Optional[str] = None


class PostOut(_Out):
    uid: str = ""
    slug: Optional[str] = None
    user_uid: Optional[str] = None
    title: Optional[str] = None
    content: Optional[str] = None
    topic: Optional[str] = None
    stars: Optional[int] = None
    image: Optional[str] = None
    project_uid: Optional[str] = None
    created_at: Optional[str] = None
    updated_at: Optional[str] = None


class GistOut(_Out):
    uid: str = ""
    slug: Optional[str] = None
    user_uid: Optional[str] = None
    title: Optional[str] = None
    description: Optional[str] = None
    source_code: Optional[str] = None
    language: Optional[str] = None
    stars: Optional[int] = None
    created_at: Optional[str] = None
    updated_at: Optional[str] = None


class ProjectOut(_Out):
    uid: str = ""
    slug: Optional[str] = None
    user_uid: Optional[str] = None
    title: Optional[str] = None
    description: Optional[str] = None
    project_type: Optional[str] = None
    status: Optional[str] = None
    platforms: Optional[Any] = None
    stars: Optional[int] = None
    is_private: Optional[bool] = None
    read_only: Optional[bool] = None
    release_date: Optional[str] = None
    demo_date: Optional[str] = None
    website_url: Optional[str] = None
    repo_url: Optional[str] = None
    cover_attachment_uid: Optional[str] = None
    logo_attachment_uid: Optional[str] = None
    created_at: Optional[str] = None
    updated_at: Optional[str] = None


class ProjectFileOut(_Out):
    uid: str = ""
    path: str = ""
    name: Optional[str] = None
    type: Optional[str] = None
    is_binary: Optional[bool] = None
    mime_type: Optional[str] = None
    size: Optional[int] = None
    url: Optional[str] = None
    updated_at: Optional[str] = None


class ProjectFileRawOut(ProjectFileOut):
    content: Optional[str] = None


class ProjectFilesOut(_Out):
    project: ProjectOut
    files: list[ProjectFileOut] = []
    is_owner: bool = False
    read_only: bool = False
    is_private: bool = False


class NewsOut(_Out):
    uid: str = ""
    slug: Optional[str] = None
    title: Optional[str] = None
    description: Optional[str] = None
    content: Optional[str] = None
    url: Optional[str] = None
    source_name: Optional[str] = None
    author: Optional[str] = None
    grade: Optional[int] = None
    ai_grade: Optional[int] = None
    status: Optional[str] = None
    image_url: Optional[str] = None
    featured: Optional[int] = None
    has_unique_image: Optional[int] = None
    article_published: Optional[str] = None
    created_at: Optional[str] = None
    synced_at: Optional[str] = None


class CommentOut(_Out):
    uid: str = ""
    user_uid: Optional[str] = None
    content: Optional[str] = None
    parent_uid: Optional[str] = None
    target_type: Optional[str] = None
    target_uid: Optional[str] = None
    created_at: Optional[str] = None


class CommentEditOut(_Out):
    uid: str = ""
    content: str = ""
    url: str = ""
    updated_at: Optional[str] = None


class CommentItemOut(_Out):
    comment: CommentOut
    author: Optional[UserOut] = None
    time_ago: Optional[str] = None
    votes: VotesOut = VotesOut()
    my_vote: int = 0
    children: list["CommentItemOut"] = []
    attachments: list[AttachmentOut] = []
    reactions: ReactionsOut = ReactionsOut()


class NotificationOut(_Out):
    uid: str = ""
    type: Optional[str] = None
    message: Optional[str] = None
    read: Optional[bool] = None
    related_uid: Optional[str] = None
    target_url: Optional[str] = None
    created_at: Optional[str] = None


class MessageOut(_Out):
    uid: str = ""
    sender_uid: Optional[str] = None
    receiver_uid: Optional[str] = None
    content: Optional[str] = None
    read: Optional[bool] = None
    created_at: Optional[str] = None


CommentItemOut.model_rebuild()

