from __future__ import annotations

from pydantic import BaseModel


class ErrorBody(BaseModel):
    code: str
    message: str
    details: dict[str, str] | None = None


class ErrorResponse(BaseModel):
    error: ErrorBody


class DirectoryEntry(BaseModel):
    name: str
    path: str
    modified: str


class FileEntry(BaseModel):
    name: str
    path: str
    size: int
    modified: str


class BrowseResponse(BaseModel):
    path: str
    directories: list[DirectoryEntry]
    files: list[FileEntry]


class MkdirRequest(BaseModel):
    parent_path: str
    name: str


class MkdirResponse(BaseModel):
    path: str


class RenameRequest(BaseModel):
    path: str
    new_name: str


class RenameResponse(BaseModel):
    path: str


class DeleteRequest(BaseModel):
    path: str
    recursive: bool = False


class DeleteResponse(BaseModel):
    path: str


class UploadResponse(BaseModel):
    path: str
    size: int
    modified: str


class ViewResponse(BaseModel):
    path: str
    name: str
    content_type: str
    encoding: str
    truncated: bool
    size: int
    modified: str
    content: str


class SaveRequest(BaseModel):
    path: str
    content: str
    expected_modified: str


class SaveResponse(BaseModel):
    path: str
    size: int
    modified: str


class ArchivePrepareRequest(BaseModel):
    paths: list[str]


class FileInfoResponse(BaseModel):
    name: str
    path: str
    type: str
    size: int | None = None
    modified: str
    root: str
    extension: str | None = None
    content_type: str | None = None
    owner: str | None = None
    group: str | None = None
    width: int | None = None
    height: int | None = None


class ZipDownloadLimitsResponse(BaseModel):
    max_items: int
    max_total_input_bytes: int
    max_individual_file_bytes: int
    scan_timeout_seconds: float
    symlink_policy: str


class SettingsResponse(BaseModel):
    show_thumbnails: bool
    preferred_startup_path_left: str | None = None
    preferred_startup_path_right: str | None = None
    selected_theme: str
    selected_color_mode: str
    zip_download_limits: ZipDownloadLimitsResponse


class SettingsUpdateRequest(BaseModel):
    show_thumbnails: bool | None = None
    preferred_startup_path_left: str | None = None
    preferred_startup_path_right: str | None = None
    selected_theme: str | None = None
    selected_color_mode: str | None = None


class TaskListItem(BaseModel):
    id: str
    operation: str
    status: str
    source: str
    destination: str
    created_at: str
    finished_at: str | None = None


class TaskListResponse(BaseModel):
    items: list[TaskListItem]


class TaskDetailResponse(BaseModel):
    id: str
    operation: str
    status: str
    source: str
    destination: str
    done_bytes: int | None = None
    total_bytes: int | None = None
    done_items: int | None = None
    total_items: int | None = None
    current_item: str | None = None
    failed_item: str | None = None
    error_code: str | None = None
    error_message: str | None = None
    created_at: str
    started_at: str | None = None
    finished_at: str | None = None


class CopyRequest(BaseModel):
    source: str | None = None
    destination: str | None = None
    sources: list[str] | None = None
    destination_base: str | None = None


class DuplicateRequest(BaseModel):
    paths: list[str]


class TaskCreateResponse(BaseModel):
    task_id: str
    status: str


class MoveRequest(BaseModel):
    source: str | None = None
    destination: str | None = None
    sources: list[str] | None = None
    destination_base: str | None = None


class BookmarkCreateRequest(BaseModel):
    path: str
    label: str


class BookmarkItem(BaseModel):
    id: int
    path: str
    label: str
    created_at: str


class BookmarkListResponse(BaseModel):
    items: list[BookmarkItem]


class BookmarkDeleteResponse(BaseModel):
    id: int


class HistoryItem(BaseModel):
    id: str
    operation: str
    status: str
    source: str | None = None
    destination: str | None = None
    path: str | None = None
    error_code: str | None = None
    error_message: str | None = None
    created_at: str
    finished_at: str | None = None


class HistoryListResponse(BaseModel):
    items: list[HistoryItem]


class SearchResultItem(BaseModel):
    name: str
    path: str
    type: str
    parent_path: str
    root: str


class SearchResponse(BaseModel):
    items: list[SearchResultItem]
    truncated: bool
