from __future__ import annotations

from typing import TYPE_CHECKING, AsyncIterator, Dict, Iterator
from urllib.parse import quote

if TYPE_CHECKING:
    from .._core._http_client import APIResponse, AsyncHttpClient, PaginatedResponse, SyncHttpClient


class Manufacturers:
    """Sync manufacturers resource."""

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

    def list(self, params: Dict | None = None) -> PaginatedResponse:
        return self._client.get_paginated("/v1/manufacturers", query=params)

    def list_auto_paging(self, params: Dict | None = None) -> Iterator:
        page = (params or {}).get("page", 1)
        while True:
            result = self.list({**(params or {}), "page": page})
            yield from result.data
            if not result.pagination.total_pages or page >= result.pagination.total_pages:
                break
            page += 1

    def get(self, id: str) -> APIResponse:
        return self._client.get(f"/v1/manufacturers/{quote(id, safe='')}")

    def get_firearms(self, id: str, params: Dict | None = None) -> PaginatedResponse:
        return self._client.get_paginated(
            f"/v1/manufacturers/{quote(id, safe='')}/firearms", query=params
        )

    def get_timeline(self, id: str) -> APIResponse:
        return self._client.get(f"/v1/manufacturers/{quote(id, safe='')}/timeline")

    def get_stats(self, id: str) -> APIResponse:
        return self._client.get(f"/v1/manufacturers/{quote(id, safe='')}/stats")


class AsyncManufacturers:
    """Async manufacturers resource."""

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

    async def list(self, params: Dict | None = None) -> PaginatedResponse:
        return await self._client.get_paginated("/v1/manufacturers", query=params)

    async def list_auto_paging(self, params: Dict | None = None) -> AsyncIterator:
        page = (params or {}).get("page", 1)
        while True:
            result = await self.list({**(params or {}), "page": page})
            for item in result.data:
                yield item
            if not result.pagination.total_pages or page >= result.pagination.total_pages:
                break
            page += 1

    async def get(self, id: str) -> APIResponse:
        return await self._client.get(f"/v1/manufacturers/{quote(id, safe='')}")

    async def get_firearms(self, id: str, params: Dict | None = None) -> PaginatedResponse:
        return await self._client.get_paginated(
            f"/v1/manufacturers/{quote(id, safe='')}/firearms", query=params
        )

    async def get_timeline(self, id: str) -> APIResponse:
        return await self._client.get(f"/v1/manufacturers/{quote(id, safe='')}/timeline")

    async def get_stats(self, id: str) -> APIResponse:
        return await self._client.get(f"/v1/manufacturers/{quote(id, safe='')}/stats")
