"""Pydantic models for Favro API responses."""

from datetime import datetime
from typing import Any, Generic, TypeVar

from pydantic import BaseModel, Field

T = TypeVar("T")


class PaginatedResponse(BaseModel, Generic[T]):
    """Paginated response wrapper."""

    limit: int
    page: int
    pages: int
    request_id: str = Field(alias="requestId")
    entities: list[T]


class User(BaseModel):
    """User model."""

    user_id: str = Field(alias="userId")
    name: str
    email: str
    organization_role: str | None = Field(default=None, alias="organizationRole")


class OrganizationMember(BaseModel):
    """Organization member model."""

    user_id: str = Field(alias="userId")
    role: str
    join_date: datetime | None = Field(default=None, alias="joinDate")


class Organization(BaseModel):
    """Organization model."""

    organization_id: str = Field(alias="organizationId")
    name: str
    thumbnail: str | None = None
    shared_to_users: list[OrganizationMember] = Field(default=[], alias="sharedToUsers")


class Collection(BaseModel):
    """Collection model."""

    collection_id: str = Field(alias="collectionId")
    organization_id: str = Field(alias="organizationId")
    name: str
    archived: bool = False
    background: str | None = None
    public_sharing: str | None = Field(default=None, alias="publicSharing")


class Widget(BaseModel):
    """Widget (board) model."""

    widget_common_id: str = Field(alias="widgetCommonId")
    organization_id: str = Field(alias="organizationId")
    collection_ids: list[str] = Field(default_factory=list, alias="collectionIds")
    name: str
    type: str  # "board" or "backlog"
    color: str | None = None
    owner_role: str | None = Field(default=None, alias="ownerRole")
    edit_role: str | None = Field(default=None, alias="editRole")
    archived: bool = False
    breakdown_card_common_id: str | None = Field(
        default=None, alias="breakdownCardCommonId"
    )


class Column(BaseModel):
    """Column model."""

    column_id: str = Field(alias="columnId")
    organization_id: str = Field(alias="organizationId")
    widget_common_id: str = Field(alias="widgetCommonId")
    name: str
    position: float
    card_count: int = Field(default=0, alias="cardCount")
    time_sum: int | None = Field(default=None, alias="timeSum")
    estimation_sum: float | None = Field(default=None, alias="estimationSum")


class CardAssignment(BaseModel):
    """Card assignment model."""

    user_id: str = Field(alias="userId")
    completed: bool = False


class CardCustomField(BaseModel):
    """Card custom field value."""

    custom_field_id: str = Field(alias="customFieldId")
    value: str | int | float | list[str] | dict[str, Any] | None = None
    total: float | None = None
    link: dict[str, str] | None = None
    members: list[str] | None = None
    status: str | None = None
    color: str | None = None


class CardTimeOnBoard(BaseModel):
    """Time card has spent on board."""

    time: int  # milliseconds
    is_stopped: bool = Field(default=False, alias="isStopped")


class Card(BaseModel):
    """Card model."""

    card_id: str = Field(alias="cardId")
    organization_id: str = Field(alias="organizationId")
    card_common_id: str = Field(alias="cardCommonId")
    name: str
    sequential_id: int = Field(alias="sequentialId")
    widget_common_id: str | None = Field(default=None, alias="widgetCommonId")
    column_id: str | None = Field(default=None, alias="columnId")
    lane_id: str | None = Field(default=None, alias="laneId")
    parent_card_id: str | None = Field(default=None, alias="parentCardId")
    is_lane: bool = Field(default=False, alias="isLane")
    archived: bool = False
    detailed_description: str | None = Field(default=None, alias="detailedDescription")
    tags: list[str] = Field(default_factory=list)
    start_date: datetime | None = Field(default=None, alias="startDate")
    due_date: datetime | None = Field(default=None, alias="dueDate")
    assignments: list[CardAssignment] = Field(default=[])
    num_comments: int = Field(default=0, alias="numComments")
    tasks_total: int = Field(default=0, alias="tasksTotal")
    tasks_done: int = Field(default=0, alias="tasksDone")
    custom_fields: list[CardCustomField] = Field(default=[], alias="customFields")
    time_on_board: CardTimeOnBoard | None = Field(default=None, alias="timeOnBoard")
    todo_list_user_id: str | None = Field(default=None, alias="todoListUserId")
    todo_list_completed: bool | None = Field(default=None, alias="todoListCompleted")
    list_position: float | None = Field(default=None, alias="listPosition")
    sheet_position: float | None = Field(default=None, alias="sheetPosition")


class Tag(BaseModel):
    """Tag model."""

    tag_id: str = Field(alias="tagId")
    organization_id: str = Field(alias="organizationId")
    name: str
    color: str | None = None


class Comment(BaseModel):
    """Comment model."""

    comment_id: str = Field(alias="commentId")
    card_common_id: str = Field(alias="cardCommonId")
    organization_id: str = Field(alias="organizationId")
    user_id: str = Field(alias="userId")
    comment: str
    created: datetime
    last_updated: datetime | None = Field(default=None, alias="lastUpdated")
