from __future__ import annotations

from typing import Any, Dict, Iterable, List, Optional, Protocol

from db.schemas import (
    ImageShortUrlCreate,
    ImageShortUrlRead,
    IngestRunCreate,
    MagentoConnectionRead,
    MagentoConnectionUpsert,
    MagentoProductSourceSnapshotCreate,
    MagentoSyncItemCreate,
    MagentoSyncJobCreate,
    ProductSupplementalAttributeValueCreate,
    PlytixProductSourceSnapshotCreate,
    ShopifyProductSourceSnapshotCreate,
    ProductSnapshotClose,
    ProductSnapshotCreate,
    RawFeedRowCreate,
)


class IngestRepository(Protocol):
    def create_ingest_run(self, payload: IngestRunCreate) -> int:
        ...

    def update_ingest_run(self, run_id: int, *, status: str, row_count: int) -> None:
        ...

    def add_raw_rows(self, rows: Iterable[RawFeedRowCreate]) -> None:
        ...

    def load_current_snapshot_index(self, skus: List[str]) -> Dict[str, Dict[str, object]]:
        ...

    def close_snapshots(self, snapshots: Iterable[ProductSnapshotClose]) -> None:
        ...

    def add_product_snapshots(self, snapshots: Iterable[ProductSnapshotCreate]) -> None:
        ...

    def close_magento_source_snapshots(self, snapshot_ids: Iterable[int], *, valid_to: Any) -> None:
        ...

    def close_plytix_source_snapshots(self, snapshot_ids: Iterable[int], *, valid_to: Any) -> None:
        ...

    def close_shopify_source_snapshots(self, snapshot_ids: Iterable[int], *, valid_to: Any) -> None:
        ...

    def add_magento_source_snapshots(
        self,
        snapshots: Iterable[MagentoProductSourceSnapshotCreate],
    ) -> None:
        ...

    def add_plytix_source_snapshots(
        self,
        snapshots: Iterable[PlytixProductSourceSnapshotCreate],
    ) -> None:
        ...

    def add_shopify_source_snapshots(
        self,
        snapshots: Iterable[ShopifyProductSourceSnapshotCreate],
    ) -> None:
        ...

    def add_supplemental_attribute_values(
        self,
        rows: Iterable[ProductSupplementalAttributeValueCreate],
    ) -> None:
        ...

    def load_current_magento_source_index(
        self,
        skus: List[str],
        *,
        connection_id: Optional[int] = None,
    ) -> Dict[str, Dict[str, object]]:
        ...

    def load_current_plytix_source_index(self, skus: List[str]) -> Dict[str, Dict[str, object]]:
        ...

    def load_current_shopify_source_index(
        self,
        skus: List[str],
        *,
        connection_id: Optional[int] = None,
    ) -> Dict[str, Dict[str, object]]:
        ...

    def load_current_snapshots(self, skus: List[str]) -> List[dict]:
        ...

    def load_attribute_def_index(self) -> Dict[str, Dict[str, object]]:
        ...

    def load_attribute_option_index(self) -> Dict[str, List[str]]:
        ...

    def add_attribute_discoveries(self, rows: Iterable[dict]) -> None:
        ...

    def get_short_url_by_slug(self, slug: str) -> Optional[ImageShortUrlRead]:
        ...

    def get_short_url_by_destination(self, destination_url: str) -> Optional[ImageShortUrlRead]:
        ...

    def create_short_url(self, payload: ImageShortUrlCreate) -> ImageShortUrlRead:
        ...


class MagentoConnectionRepository(Protocol):
    def get_by_id(self, connection_id: int) -> Optional[MagentoConnectionRead]:
        ...

    def get_active_connection(
        self, tenant_id: Optional[str], environment: str
    ) -> Optional[MagentoConnectionRead]:
        ...

    def upsert_connection(self, payload: MagentoConnectionUpsert) -> int:
        ...

    def list_connections(self, tenant_id: Optional[str] = None) -> List[MagentoConnectionRead]:
        ...

    def update_verification(
        self, connection_id: int, *, success: bool, error: Optional[str] = None
    ) -> None:
        ...


class MagentoSyncRepository(Protocol):
    def create_sync_job(self, payload: MagentoSyncJobCreate) -> int:
        ...

    def update_sync_job(self, job_id: int, **kwargs: Any) -> None:
        ...

    def add_sync_items(self, items: Iterable[MagentoSyncItemCreate]) -> None:
        ...

    def get_job_items(self, job_id: int) -> List[dict]:
        ...

    def get_pending_items(self, job_id: int) -> List[dict]:
        ...

    def update_sync_item(self, item_id: int, **kwargs: Any) -> None:
        ...
