"""Pydantic models for GA4GH Beacon v2."""

from __future__ import annotations

from enum import Enum
from typing import Any

from ai4gh.core.types import GA4GHBase


class Granularity(str, Enum):
    """Beacon response granularity levels."""

    boolean = "boolean"
    count = "count"  # type: ignore[assignment]
    record = "record"


class Similarity(str, Enum):
    """Beacon similarity matching."""

    exact = "exact"
    high = "high"
    medium = "medium"
    low = "low"


class Operator(str, Enum):
    """Filter operators."""

    equals = "="
    less_than = "<"
    greater_than = ">"
    not_equals = "!"
    less_or_equal = "<="
    greater_or_equal = ">="


class FilteringTerm(GA4GHBase):
    """Beacon filtering term."""

    id: str
    scope: str | None = None
    include_descendant_terms: bool = True
    similarity: Similarity = Similarity.exact


class AlphanumericFilter(GA4GHBase):
    """Beacon alphanumeric filter."""

    id: str
    operator: Operator = Operator.equals
    value: str | int | float
    scope: str | None = None


class OntologyFilter(GA4GHBase):
    """Beacon ontology filter."""

    id: str
    scope: str | None = None
    include_descendant_terms: bool = True
    similarity: Similarity = Similarity.exact


class CustomFilter(GA4GHBase):
    """Beacon custom filter."""

    id: str
    scope: str | None = None


class BeaconQuery(GA4GHBase):
    """Beacon v2 query."""

    filters: list[FilteringTerm | AlphanumericFilter | OntologyFilter | CustomFilter] | None = None
    include_resultset_responses: str | None = None
    pagination: dict[str, int] | None = None
    request_parameters: dict[str, Any] | None = None
    test_mode: bool = False


class BeaconRequestMeta(GA4GHBase):
    """Beacon request metadata."""

    api_version: str = "v2.0.0"
    requested_schemas: list[dict[str, str]] | None = None


class BeaconRequest(GA4GHBase):
    """Beacon v2 request body."""

    meta: BeaconRequestMeta = BeaconRequestMeta()
    query: BeaconQuery = BeaconQuery()


class BeaconResultsetResponse(GA4GHBase):
    """A single resultset in a Beacon response."""

    id: str
    set_type: str | None = None
    exists: bool | None = None
    results_count: int | None = None
    results: list[dict[str, Any]] | None = None


class BeaconResponseMeta(GA4GHBase):
    """Beacon response metadata."""

    beacon_id: str | None = None
    api_version: str | None = None
    returned_granularity: Granularity | None = None
    received_request_summary: dict[str, Any] | None = None
    returned_schemas: list[dict[str, str]] | None = None


class BeaconResponse(GA4GHBase):
    """Beacon v2 response."""

    meta: BeaconResponseMeta | None = None
    response_summary: dict[str, Any] | None = None
    response: dict[str, Any] | None = None
    beacon_handovers: list[dict[str, Any]] | None = None


class BeaconInfo(GA4GHBase):
    """Beacon informational endpoint response."""

    id: str
    name: str
    api_version: str | None = None
    environment: str | None = None
    organization: dict[str, Any] | None = None
    description: str | None = None
    version: str | None = None
    welcome_url: str | None = None
    alternative_url: str | None = None
    create_date_time: str | None = None
    update_date_time: str | None = None
    datasets: list[dict[str, Any]] | None = None
