"""Repository contracts for the formal acquisition state store."""
from __future__ import annotations

from typing import Any, Protocol
from uuid import UUID

from acquisition.domain import (
    AcquisitionJob,
    AcquisitionRun,
    CandidateItem,
    ItemClassification,
    MediaAsset,
    Query,
    QueryBatch,
)


class AcquisitionRepository(Protocol):
    """Persistence boundary used by acquisition runners and API routes."""

    def create_query_batch(
        self,
        *,
        name: str,
        source_type: str = "manual",
        generation_method: str | None = None,
        target_platforms: list[str] | None = None,
        status: str = "draft",
        metadata: dict[str, Any] | None = None,
    ) -> QueryBatch:
        ...

    def add_query(
        self,
        *,
        batch_id: UUID | None,
        query_text: str,
        axes: dict[str, Any] | None = None,
        keep: bool | None = None,
        filter_reason: str | None = None,
        status: str = "draft",
        sort_order: int = 0,
        metadata: dict[str, Any] | None = None,
    ) -> Query:
        ...

    def list_queries_for_batch(
        self,
        batch_id: UUID,
        *,
        keep: bool | None = None,
    ) -> list[Query]:
        ...

    def get_query_batch(self, batch_id: UUID) -> QueryBatch:
        ...

    def create_acquisition_run(
        self,
        *,
        batch_id: UUID | None = None,
        run_key: str | None = None,
        status: str = "pending",
        note: str | None = None,
        metadata: dict[str, Any] | None = None,
    ) -> AcquisitionRun:
        ...

    def ensure_acquisition_job(
        self,
        *,
        run_id: UUID,
        query_id: UUID | None,
        platform: str,
        search_limit: int | None = None,
        display_limit: int | None = None,
        status: str = "pending",
        metadata: dict[str, Any] | None = None,
    ) -> AcquisitionJob:
        ...

    def update_acquisition_job(
        self,
        job_id: UUID,
        *,
        status: str,
        attempt_count: int | None = None,
        error_message: str | None = None,
        metadata: dict[str, Any] | None = None,
    ) -> AcquisitionJob:
        ...

    def update_acquisition_run(
        self,
        run_id: UUID,
        *,
        status: str,
        error_message: str | None = None,
        metadata: dict[str, Any] | None = None,
    ) -> AcquisitionRun:
        ...

    def upsert_candidate_item(
        self,
        *,
        platform: str,
        job_id: UUID | None = None,
        query_id: UUID | None = None,
        platform_item_id: str | None = None,
        unique_key: str | None = None,
        canonical_url: str | None = None,
        content_type: str | None = None,
        content_mode: str | None = None,
        title: str | None = None,
        author_name: str | None = None,
        body_text: str | None = None,
        raw_summary: str | None = None,
        status: str = "candidate",
        source_payload: dict[str, Any] | None = None,
        metadata: dict[str, Any] | None = None,
        error_message: str | None = None,
    ) -> CandidateItem:
        ...

    def get_candidate_item_by_unique_key(self, unique_key: str) -> CandidateItem | None:
        ...

    def attach_existing_candidate_item(
        self,
        item_id: UUID,
        *,
        job_id: UUID,
        query_id: UUID,
        metadata: dict[str, Any] | None = None,
    ) -> CandidateItem:
        ...

    def add_media_asset(
        self,
        *,
        item_id: UUID,
        media_type: str,
        source_url: str | None = None,
        oss_url: str | None = None,
        cdn_url: str | None = None,
        position: int = 0,
        status: str = "pending",
        source_payload: dict[str, Any] | None = None,
        metadata: dict[str, Any] | None = None,
    ) -> MediaAsset:
        ...

    def add_item_classification(
        self,
        *,
        item_id: UUID,
        is_creation_knowledge: bool | None = None,
        label: str | None = None,
        confidence: float | None = None,
        reason: str | None = None,
        model_name: str | None = None,
        prompt_version: str | None = None,
        result_payload: dict[str, Any] | None = None,
        status: str = "pending",
        error_message: str | None = None,
    ) -> ItemClassification:
        ...

    def get_run_summary(self, run_id: UUID) -> dict[str, Any]:
        ...

    def get_query_detail(self, *, run_id: UUID, query_id: UUID) -> dict[str, Any]:
        ...

    def get_query_detail_for_batch(self, *, batch_id: UUID, query_id: UUID) -> dict[str, Any]:
        ...

    def get_latest_query_result_list(self, query_id: UUID) -> dict[str, Any]:
        ...

    def list_creation_candidate_items(
        self,
        *,
        run_id: UUID | None = None,
        limit: int = 100,
    ) -> list[CandidateItem]:
        ...

    def get_candidate_item(self, item_id: UUID) -> CandidateItem:
        ...

    def list_media_assets_for_item(self, item_id: UUID) -> list[MediaAsset]:
        ...
