"""Public /v1 predictions."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

from ...models.v1.pagination import Page, Pagination
from ...models.v1.predictions import (
    BulkPredictionsResult,
    PredictionDetail,
    PredictionSummaryStats,
    PredictionTypeSummary,
)
from ._helpers import parse_detail, parse_page

if TYPE_CHECKING:
    from ..._http import HttpTransport


class PredictionsResource:
    """client.predictions — /v1/predictions."""

    def __init__(self, http: HttpTransport) -> None:
        self._http = http

    def types(self) -> Page[PredictionTypeSummary]:
        return parse_page(self._http.get("/predictions/types"), PredictionTypeSummary)

    def get_type(self, type_id: str) -> PredictionTypeSummary:
        return parse_detail(self._http.get(f"/predictions/types/{type_id}"), PredictionTypeSummary)

    def list(
        self,
        *,
        factory_id: str,
        prediction_type_id: str | None = None,
        worker_id: str | None = None,
        label: str | None = None,
        run_id: str | None = None,
        page_size: int = 50,
        cursor: str | None = None,
    ) -> Page[PredictionDetail]:
        params: dict[str, Any] = {
            "factory_id": factory_id,
            "page_size": page_size,
        }
        for key, value in {
            "cursor": cursor,
            "prediction_type_id": prediction_type_id,
            "worker_id": worker_id,
            "label": label,
            "run_id": run_id,
        }.items():
            if value is not None:
                params[key] = value
        return parse_page(self._http.get("/predictions", params=params), PredictionDetail)

    def get_for_clip(
        self,
        clip_id: str,
        *,
        prediction_type_id: str | None = None,
    ) -> Page[PredictionDetail]:
        params: dict[str, Any] | None = None
        if prediction_type_id is not None:
            params = {"prediction_type_id": prediction_type_id}
        return parse_page(self._http.get(f"/predictions/by-clip/{clip_id}", params=params), PredictionDetail)

    def get_for_frame(
        self,
        frame_id: str,
        *,
        prediction_type_id: str | None = None,
    ) -> Page[PredictionDetail]:
        result = self.by_frames([frame_id], prediction_type_id=prediction_type_id)
        return Page[PredictionDetail](
            data=result.data.get(frame_id, []),
            pagination=Pagination(page_size=len(result.data.get(frame_id, []))),
            request_id=result.request_id,
        )

    def by_frames(
        self,
        frame_ids: list[str],
        *,
        prediction_type_id: str | None = None,
    ) -> BulkPredictionsResult:
        body: dict[str, Any] = {"frame_ids": frame_ids}
        if prediction_type_id is not None:
            body["prediction_type_id"] = prediction_type_id
        return BulkPredictionsResult.model_validate(self._http.post("/predictions/by-frames", json=body))

    def by_clips(
        self,
        clip_ids: list[str],
        *,
        prediction_type_id: str | None = None,
    ) -> BulkPredictionsResult:
        body: dict[str, Any] = {"clip_ids": clip_ids}
        if prediction_type_id is not None:
            body["prediction_type_id"] = prediction_type_id
        return BulkPredictionsResult.model_validate(self._http.post("/predictions/by-clips", json=body))

    def summary(
        self,
        *,
        factory_id: str,
        prediction_type_id: str | None = None,
    ) -> Page[PredictionSummaryStats]:
        params: dict[str, Any] = {"factory_id": factory_id}
        if prediction_type_id is not None:
            params["prediction_type_id"] = prediction_type_id
        return parse_page(self._http.get("/predictions/summary", params=params), PredictionSummaryStats)
