"""V1 API filter models for type-safe filtering.

These models provide IDE autocomplete and type safety for filter parameters.
All models use `extra='allow'` for forward compatibility - the backend
silently ignores unknown filter fields, and new fields may be added over time.
"""

from typing import Any

from pydantic import BaseModel, ConfigDict


class V1BaseFilters(BaseModel):
    """Base filter model for V1 API resources.

    Common filter fields used across multiple V1 resources.
    """

    model_config = ConfigDict(extra="allow")

    generalSearch: list[str] | None = None
    """Full-text search across multiple fields"""

    fields: dict[str, Any] | None = None
    """Metadata field filters. Structure: {fieldId: {contentType: str, values: list}}"""


class ImageSetFilters(V1BaseFilters):
    """Filter model for ImageSets API (/api/imageSets).

    Example:
        filters = ImageSetFilters(
            ownerId=[1, 2],
            isFavorite=True,
            archived=False,
            name=["Brain Study"],
            workflowId=[10]
        )
        image_sets = client.v1.image_sets.list(filters=filters)
    """

    # ID filters
    ownerId: list[int] | None = None
    """Filter by owner user IDs"""

    imageSetId: list[int] | None = None
    """Filter by specific image set IDs"""

    assignedUserId: list[int] | None = None
    """Filter by assigned user IDs"""

    workflowId: list[int] | None = None
    """Filter by workflow IDs"""

    stageId: list[int] | None = None
    """Filter by workflow stage IDs"""

    organizationId: list[int] | None = None
    """Filter by organization IDs"""

    # Boolean filters
    public: bool | None = None
    """Filter by public/private status"""

    isFavorite: bool | None = None
    """Filter by favorited status"""

    isShared: bool | None = None
    """Filter by shared (not owned by you)"""

    hasEditAccess: bool | None = None
    """Filter by edit permission"""

    archived: bool | None = None
    """Filter by archived status"""

    # String filters
    name: list[str] | None = None
    """Filter by image set names"""

    description: list[str] | None = None
    """Filter by descriptions"""

    status: list[str] | None = None
    """Filter by stage status (case insensitive)"""

    channelGroupName: list[str] | None = None
    """Filter by channel group names"""

    # Date range filters
    created: list[dict[str, str]] | None = None
    """Date range filter. List of date range dicts: [{"start": ISO date, "end": ISO date}]"""

    # Number operation filters
    imageCount: list[list[dict[str, Any]]] | None = None
    """Number comparison operations for image count"""


class ImageFilters(V1BaseFilters):
    """Filter model for Images API (/api/images).

    Example:
        filters = ImageFilters(
            imageSetId=[100],
            hasAnnotations=True,
            isFluorescence=True,
            biomarker=["HER2", "ER"]
        )
        images = client.v1.images.list(filters=filters)
    """

    # ID filters
    imageSetId: list[int] | None = None
    """Filter by parent image set IDs"""

    imageId: list[int] | None = None
    """Filter by specific image IDs"""

    imageFileId: list[int] | None = None
    """Filter by image file IDs"""

    # Boolean filters
    isFluorescence: bool | None = None
    """Filter by fluorescence images"""

    hasOverlays: bool | None = None
    """Filter by images with overlays"""

    hasMultipleZLayers: bool | None = None
    """Filter by images with multiple Z layers"""

    hasAnnotations: bool | None = None
    """Filter by images with annotations"""

    hasAnalysisResults: bool | None = None
    """Filter by images with analysis results"""

    # String filters
    slideName: list[str] | None = None
    """Filter by slide names"""

    name: list[str] | None = None
    """Filter by image names"""

    biomarker: list[str] | None = None
    """Filter by biomarker"""

    fluorescenceChannel: list[str] | None = None
    """Filter by fluorescence channel names"""

    # Status filter (ingestion status codes)
    status: list[int] | None = None
    """Filter by ingestion status (-2, -1, 0, 1, 2, 3)"""

    # Date range filters
    created: list[dict[str, str]] | None = None
    """Date range filter. List of date range dicts: [{"start": ISO date, "end": ISO date}]"""

    # Number operation filters
    objectivePower: list[list[dict[str, Any]]] | None = None
    """Number comparison operations for objective power"""

    filesize: list[list[dict[str, Any]]] | None = None
    """Number comparison operations for file size"""

    # Nested filters
    folder: dict[str, Any] | None = None
    """Nested folder filters (recursive structure)"""

    analysis: dict[str, Any] | None = None
    """Nested analysis job filters"""

    annotation: dict[str, Any] | None = None
    """Nested annotation filters"""


class FolderFilters(V1BaseFilters):
    """Filter model for Folders API (/api/folders).

    Example:
        filters = FolderFilters(
            imageSetId=[100],
            hasMetadata=True,
            name=["Brain Cases"]
        )
        folders = client.v1.folders.list(filters=filters)
    """

    # ID filters
    imageSetId: list[int] | None = None
    """Filter by image set IDs"""

    folderId: list[int] | None = None
    """Filter by specific folder IDs"""

    # Boolean filters
    hasMetadata: bool | None = None
    """Filter by folders that are cases (have metadata)"""

    hasAttachments: bool | None = None
    """Filter by folders with attachments"""

    # String filters
    name: list[str] | None = None
    """Filter by folder names"""

    # Nested filters
    image: dict[str, Any] | None = None
    """Nested image filters to filter folders by their images"""


class MetadataValueFilters(V1BaseFilters):
    """Filter model for MetadataValues API (/api/metadata-values).

    Example:
        filters = MetadataValueFilters(
            imageSetId=[100, 101],
            imageId=[1000],
            resourceType="image"
        )
        values = client.v1.metadata_values.list(filters=filters)
    """

    # Resource ID filters
    imageSetId: list[int] | None = None
    """Filter by image set IDs"""

    imageId: list[int] | None = None
    """Filter by image IDs"""

    folderId: list[int] | None = None
    """Filter by folder IDs"""

    annotationId: list[int] | None = None
    """Filter by annotation IDs"""

    analysisJobId: list[int] | None = None
    """Filter by analysis job IDs"""

    organizationId: list[int] | None = None
    """Filter by organization IDs"""

    moduleId: list[int] | None = None
    """Filter by module IDs"""

    # String filters
    resourceType: str | None = None
    """Filter by resource type (image, folder, annotation, etc.)"""


class AnnotationFilters(V1BaseFilters):
    """Filter model for Annotations API (/api/annotations).

    Example:
        filters = AnnotationFilters(
            imageId=[100],
            text=["ROI"],
            annotationClassId=[5]
        )
        annotations = client.v1.annotations.list(filters=filters)
    """

    # ID filters
    annotationId: list[int] | None = None
    """Filter by specific annotation IDs"""

    imageId: list[int] | None = None
    """Filter by image IDs that annotations belong to"""

    annotationClassId: list[int] | None = None
    """Filter by annotation class IDs"""

    # String filters
    text: list[str] | None = None
    """Filter by annotation text/labels"""
