from typing import TypedDict


class CvatApiAttribute(TypedDict):
    """Represents an attribute in CVAT API."""

    spec_id: int
    value: str


class CvatApiTag(TypedDict):
    """Represents a tag in CVAT API."""

    id: int
    label_id: int
    color: str
    frame: int
    group: int
    source: str  # e.g., "manual"
    attributes: list[CvatApiAttribute]


class CvatApiShape(TypedDict):
    """Represents a shape in CVAT API."""

    id: int
    label_id: int
    type: str
    frame: int
    group: int
    source: str  # e.g., "manual"
    occluded: bool
    outside: bool
    label_name: str
    z_order: int
    rotation: float
    points: list[float]
    attributes: list[CvatApiAttribute]
    elements: list


class CvatApiJobAnnotations(TypedDict):
    """Represents a job in CVAT API."""

    version: int
    tags: list[CvatApiTag]
    shapes: list[CvatApiShape]
    tracks: list


class CvatApiAttributeDefinition(TypedDict):
    """Represents an attribute definition in CVAT API."""

    id: int
    name: str
    mutable: bool
    input_type: str
    default_value: str
    values: list[str]  # Possible values for the attribute


class CvatApiLabelDefinition(TypedDict):
    """Represents a label in CVAT API."""

    id: int
    name: str
    color: str
    attributes: list[CvatApiAttributeDefinition]
    type: str
    svg: str
    sublabels: list["CvatApiLabelDefinition"]  # Recursive type for nested labels
    project_id: int
    task_id: int
    parent_id: int | None  # ID of the parent label, if any
    has_parent: bool  # Indicates if this label has a parent label


class CvatApiMetainformationFrame(TypedDict):
    """Represents a frame in CVAT API."""

    width: int
    height: int
    name: str
    related_files: bool
    has_related_context: bool


class CvatApiJobMediasMetainformation(TypedDict):
    """Represents the metainformation for a job in CVAT API."""

    chunks_updated_date: str
    chunk_size: int
    size: int
    image_quality: int
    start_frame: int
    stop_frame: int
    frame_filter: str
    frames: list[CvatApiMetainformationFrame]
    deleted_frames: list[int]
    included_frames: list[int] | None


class CvatApiTaskMediasMetainformation(TypedDict):
    """Represents the metainformation for a task in CVAT API."""

    chunks_updated_date: str
    chunk_size: int
    size: int
    image_quality: int
    start_frame: int
    stop_frame: int
    frame_filter: str
    frames: list[CvatApiMetainformationFrame]
    deleted_frames: list[int]
    included_frames: list[int] | None


class CvatApiJobDetails(TypedDict):
    """Represents job details in CVAT API."""

    url: str
    id: int
    task_id: int
    project_id: int
    assignee_id: int | None
    assignee: str | None
    status: str
    stage: str
    state: str
    mode: str
    dimension: str
    start_frame: int
    stop_frame: int
    data_chunk_size: int
    data_compressed_chunk_size: int
    data_original_chunk_size: int
    created_date: str
    updated_date: str
    issue_tracker: str | None
    labels: list[CvatApiLabelDefinition]


class CvatApiTaskDetails(TypedDict):
    """Represents task details in CVAT API."""

    url: str
    id: int
    name: str
    project_id: int
    mode: str
    owner: str
    assignee: str | None
    bug_tracker: str | None
    created_date: str
    updated_date: str
    overlap: int
    segment_size: int
    status: str
    labels: list[CvatApiLabelDefinition]
    segments: list[CvatApiJobDetails]
    data_chunk_size: int
    data_compressed_chunk_size: int
    data_original_chunk_size: int
    size: int
    image_quality: int
    data: int
    dimension: str
    subset: str
    organization: int | None
    target_storage: dict | None
    source_storage: dict | None


class CvatApiTaskAnnotations(TypedDict):
    """Represents annotations for a task in CVAT API."""

    version: int
    tags: list[CvatApiTag]
    shapes: list[CvatApiShape]
    tracks: list
