from __future__ import annotations

from typing import TYPE_CHECKING, Any, List, Optional

from cardog.types.research import LineupResponse, ResearchColor, ResearchImage, ResearchVariant

if TYPE_CHECKING:
    from cardog._base_client import AsyncAPIClient, SyncAPIClient


class SyncResearchResource:
    """Vehicle research and variant data."""

    def __init__(self, client: SyncAPIClient) -> None:
        self._client = client

    def get_by_id(self, variant_id: str) -> ResearchVariant:
        """Get a vehicle variant by ID."""
        return self._client._get(f"/research/id/{variant_id}", model=ResearchVariant)

    def get_by_vin(self, vin: str) -> ResearchVariant:
        """Get a vehicle variant by VIN."""
        return self._client._get(f"/research/vin/{vin}", model=ResearchVariant)

    def get_by_listing(self, listing_id: str) -> ResearchVariant:
        """Get a vehicle variant by listing ID."""
        return self._client._get(f"/research/listing/{listing_id}", model=ResearchVariant)

    def get_by_make(self, make: str) -> List[ResearchVariant]:
        """Get all variants for a make."""
        return self._client._get(f"/research/make/{make}")

    def get_by_make_model(self, make: str, model: str) -> List[ResearchVariant]:
        """Get all variants for a make/model."""
        return self._client._get(f"/research/make/{make}/model/{model}")

    def get_by_make_year(self, make: str, year: int) -> List[ResearchVariant]:
        """Get all variants for a make/year."""
        return self._client._get(f"/research/make/{make}/year/{year}")

    def get_by_make_model_year(
        self, make: str, model: str, year: int
    ) -> List[ResearchVariant]:
        """Get all variants for a make/model/year."""
        return self._client._get(f"/research/make/{make}/model/{model}/year/{year}")

    def lineup(
        self,
        make: str,
        *,
        page: Optional[int] = None,
        limit: Optional[int] = None,
        region: Optional[str] = None,
    ) -> LineupResponse:
        """Get the lineup of variants for a make with pagination."""
        return self._client._get(
            f"/research/lineup/{make}",
            params={"page": page, "limit": limit, "region": region},
            model=LineupResponse,
        )

    def images(
        self,
        *,
        make: Optional[str] = None,
        model: Optional[str] = None,
        year: Optional[int] = None,
        shot_type: Optional[str] = None,
        category: Optional[str] = None,
    ) -> List[ResearchImage]:
        """Get vehicle images with filters."""
        return self._client._get(
            "/research/images",
            params={
                "make": make,
                "model": model,
                "year": year,
                "shotType": shot_type,
                "category": category,
            },
        )

    def profile_images(self, make: str, model: str, year: int) -> List[ResearchImage]:
        """Get profile images for a make/model/year."""
        return self._client._get(f"/research/images/profiles/{make}/{model}/{year}")

    def colors(self, **kwargs: Any) -> List[ResearchColor]:
        """Get available colors."""
        return self._client._get("/research/colors", params=kwargs)


class AsyncResearchResource:
    """Vehicle research and variant data (async)."""

    def __init__(self, client: AsyncAPIClient) -> None:
        self._client = client

    async def get_by_id(self, variant_id: str) -> ResearchVariant:
        """Get a vehicle variant by ID."""
        return await self._client._get(f"/research/id/{variant_id}", model=ResearchVariant)

    async def get_by_vin(self, vin: str) -> ResearchVariant:
        """Get a vehicle variant by VIN."""
        return await self._client._get(f"/research/vin/{vin}", model=ResearchVariant)

    async def get_by_listing(self, listing_id: str) -> ResearchVariant:
        """Get a vehicle variant by listing ID."""
        return await self._client._get(
            f"/research/listing/{listing_id}", model=ResearchVariant
        )

    async def get_by_make(self, make: str) -> List[ResearchVariant]:
        """Get all variants for a make."""
        return await self._client._get(f"/research/make/{make}")

    async def get_by_make_model(self, make: str, model: str) -> List[ResearchVariant]:
        """Get all variants for a make/model."""
        return await self._client._get(f"/research/make/{make}/model/{model}")

    async def get_by_make_year(self, make: str, year: int) -> List[ResearchVariant]:
        """Get all variants for a make/year."""
        return await self._client._get(f"/research/make/{make}/year/{year}")

    async def get_by_make_model_year(
        self, make: str, model: str, year: int
    ) -> List[ResearchVariant]:
        """Get all variants for a make/model/year."""
        return await self._client._get(
            f"/research/make/{make}/model/{model}/year/{year}"
        )

    async def lineup(
        self,
        make: str,
        *,
        page: Optional[int] = None,
        limit: Optional[int] = None,
        region: Optional[str] = None,
    ) -> LineupResponse:
        """Get the lineup of variants for a make with pagination."""
        return await self._client._get(
            f"/research/lineup/{make}",
            params={"page": page, "limit": limit, "region": region},
            model=LineupResponse,
        )

    async def images(
        self,
        *,
        make: Optional[str] = None,
        model: Optional[str] = None,
        year: Optional[int] = None,
        shot_type: Optional[str] = None,
        category: Optional[str] = None,
    ) -> List[ResearchImage]:
        """Get vehicle images with filters."""
        return await self._client._get(
            "/research/images",
            params={
                "make": make,
                "model": model,
                "year": year,
                "shotType": shot_type,
                "category": category,
            },
        )

    async def profile_images(
        self, make: str, model: str, year: int
    ) -> List[ResearchImage]:
        """Get profile images for a make/model/year."""
        return await self._client._get(
            f"/research/images/profiles/{make}/{model}/{year}"
        )

    async def colors(self, **kwargs: Any) -> List[ResearchColor]:
        """Get available colors."""
        return await self._client._get("/research/colors", params=kwargs)
