"""Pydantic models for Nextcloud Collectives app."""

import re

from pydantic import BaseModel, Field, field_validator

from .base import BaseResponse, StatusResponse

# Domain Models


class Collective(BaseModel):
    """A Nextcloud Collective (wiki/knowledge base)."""

    id: int = Field(description="Collective ID")
    circleId: str = Field(description="Linked Circle/Team ID")
    emoji: str | None = Field(default=None, description="Collective emoji")
    name: str = Field(description="Collective name")
    level: int = Field(description="User's membership level")
    canEdit: bool = Field(description="Whether the user can edit")
    canShare: bool = Field(description="Whether the user can share")
    pageMode: int = Field(description="Default page mode: 0=view, 1=edit")


class PageInfo(BaseModel):
    """A page within a Collective."""

    id: int = Field(description="Page ID")
    title: str = Field(description="Page title")
    emoji: str | None = Field(default=None, description="Page emoji")
    fileName: str = Field(description="Markdown file name")
    filePath: str = Field(description="File path within the collective")
    collectivePath: str | None = Field(
        default=None, description="Collective folder path in user's files"
    )
    parentId: int = Field(description="Parent page ID (0 for root)")
    timestamp: int = Field(description="Last modification Unix timestamp")
    size: int = Field(description="Content size in bytes")
    lastUserId: str | None = Field(default=None, description="Last editor user ID")
    lastUserDisplayName: str | None = Field(
        default=None, description="Last editor display name"
    )
    subpageOrder: list[int] = Field(
        default_factory=list, description="Ordered subpage IDs"
    )
    isFullWidth: bool | None = Field(default=None, description="Full-width page layout")
    trashTimestamp: int | None = Field(
        default=None, description="Timestamp when the page was trashed"
    )


class CollectiveTag(BaseModel):
    """A tag within a Collective."""

    id: int = Field(description="Tag ID")
    collectiveId: int = Field(description="Parent collective ID")
    name: str = Field(description="Tag name")
    color: str = Field(description="Hex color code (e.g. 'FF0000')")

    @field_validator("color")
    @classmethod
    def validate_hex_color(cls, v: str) -> str:
        if not re.fullmatch(r"[0-9A-Fa-f]{3}(?:[0-9A-Fa-f]{3})?", v):
            raise ValueError(f"Invalid hex color: {v!r}")
        return v


# Response Models


class ListCollectivesResponse(BaseResponse):
    """Response for listing collectives."""

    collectives: list[Collective] = Field(description="List of collectives")
    total: int = Field(description="Total number of collectives")


class CreateCollectiveResponse(BaseResponse):
    """Response for creating a collective."""

    id: int = Field(description="Created collective ID")
    name: str = Field(description="Created collective name")
    emoji: str | None = Field(default=None, description="Collective emoji")


class CollectiveOperationResponse(StatusResponse):
    """Response for collective update operations."""

    collective_id: int = Field(description="ID of the affected collective")


class ListPagesResponse(BaseResponse):
    """Response for listing pages in a collective."""

    pages: list[PageInfo] = Field(description="List of pages")
    total: int = Field(description="Total number of pages")
    collective_id: int = Field(description="Collective ID")


class GetPageResponse(BaseResponse):
    """Response for getting a single page with content."""

    page: PageInfo = Field(description="Page metadata")
    content: str | None = Field(
        default=None,
        description="Page markdown content (fetched via WebDAV)",
    )


class CreatePageResponse(BaseResponse):
    """Response for creating a page."""

    id: int = Field(description="Created page ID")
    title: str = Field(description="Created page title")
    collective_id: int = Field(description="Collective ID")
    parent_id: int = Field(description="Parent page ID")


class PageOperationResponse(StatusResponse):
    """Response for page operations (update, trash, emoji, tag)."""

    page_id: int = Field(description="ID of the affected page")
    collective_id: int = Field(description="Collective ID")


class SearchPagesResponse(BaseResponse):
    """Response for full-text search within a collective."""

    results: list[PageInfo] = Field(description="Matching pages")
    total: int = Field(description="Total number of results")
    query: str = Field(description="Search query")
    collective_id: int = Field(description="Collective ID")


class ListTrashedPagesResponse(ListPagesResponse):
    """Response for listing trashed pages in a collective."""


class ListTrashedCollectivesResponse(BaseResponse):
    """Response for listing trashed collectives."""

    collectives: list[Collective] = Field(description="List of trashed collectives")
    total: int = Field(description="Total number of trashed collectives")


class ListTagsResponse(BaseResponse):
    """Response for listing tags in a collective."""

    tags: list[CollectiveTag] = Field(description="List of tags")
    total: int = Field(description="Total number of tags")
    collective_id: int = Field(description="Collective ID")


class CreateTagResponse(BaseResponse):
    """Response for creating a tag."""

    id: int = Field(description="Created tag ID")
    name: str = Field(description="Tag name")
    color: str = Field(description="Tag color")
