# This file was auto-generated by Fern from our API Definition.

import typing
import urllib.parse
from json.decoder import JSONDecodeError

import httpx
import pydantic

from ...core.api_error import ApiError
from ...environment import GroTradeFlowEnvironment
from .errors.bad_request_error import BadRequestError
from .errors.not_found_error import NotFoundError


class TradeFlowClient:
    def __init__(self, *, environment: GroTradeFlowEnvironment = GroTradeFlowEnvironment.PRODUCTION):
        self._environment = environment

    def list_countries(self, *, freq: str) -> typing.List[str]:
        _response = httpx.request(
            "GET",
            urllib.parse.urljoin(f"{self._environment.value}/", "trade-flows/list_countries"),
            params={"freq": freq},
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.List[str], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def list_items(
        self, *, country: str, freq: str, partner_region: typing.Optional[str] = None
    ) -> typing.List[typing.Dict[str, str]]:
        _response = httpx.request(
            "GET",
            urllib.parse.urljoin(f"{self._environment.value}/", "trade-flows/list_items"),
            params={"country": country, "freq": freq, "partner_region": partner_region},
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.List[typing.Dict[str, str]], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_import_value(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_6_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        in_usd: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        _response = httpx.request(
            "GET",
            urllib.parse.urljoin(f"{self._environment.value}/", "trade-flows/get_import_value"),
            params={
                "country": country,
                "item": item,
                "hs6_code": hs_6_code,
                "partner_region": partner_region,
                "in_usd": in_usd,
                "freq": freq,
            },
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_export_value(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_6_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        in_usd: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        _response = httpx.request(
            "GET",
            urllib.parse.urljoin(f"{self._environment.value}/", "trade-flows/get_export_value"),
            params={
                "country": country,
                "item": item,
                "hs6_code": hs_6_code,
                "partner_region": partner_region,
                "in_usd": in_usd,
                "freq": freq,
            },
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_import_volume(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_6_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        _response = httpx.request(
            "GET",
            urllib.parse.urljoin(f"{self._environment.value}/", "trade-flows/get_import_volume"),
            params={
                "country": country,
                "item": item,
                "hs6_code": hs_6_code,
                "partner_region": partner_region,
                "freq": freq,
            },
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_export_volume(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_6_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        _response = httpx.request(
            "GET",
            urllib.parse.urljoin(f"{self._environment.value}/", "trade-flows/get_export_volume"),
            params={
                "country": country,
                "item": item,
                "hs6_code": hs_6_code,
                "partner_region": partner_region,
                "freq": freq,
            },
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_all_for_time(
        self,
        *,
        metric: str,
        year: int,
        month: typing.Optional[int] = None,
        quarter: typing.Optional[int] = None,
        item: typing.Optional[str] = None,
        hs_6_code: typing.Optional[str] = None,
        country: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        in_usd: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        _response = httpx.request(
            "GET",
            urllib.parse.urljoin(f"{self._environment.value}/", "trade-flows/get_all_for_time"),
            params={
                "metric": metric,
                "year": year,
                "month": month,
                "quarter": quarter,
                "item": item,
                "hs6_code": hs_6_code,
                "country": country,
                "partner_region": partner_region,
                "in_usd": in_usd,
            },
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)


class AsyncTradeFlowClient:
    def __init__(self, *, environment: GroTradeFlowEnvironment = GroTradeFlowEnvironment.PRODUCTION):
        self._environment = environment

    async def list_countries(self, *, freq: str) -> typing.List[str]:
        async with httpx.AsyncClient() as _client:
            _response = await _client.request(
                "GET",
                urllib.parse.urljoin(f"{self._environment.value}/", "trade-flows/list_countries"),
                params={"freq": freq},
                timeout=60,
            )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.List[str], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def list_items(
        self, *, country: str, freq: str, partner_region: typing.Optional[str] = None
    ) -> typing.List[typing.Dict[str, str]]:
        async with httpx.AsyncClient() as _client:
            _response = await _client.request(
                "GET",
                urllib.parse.urljoin(f"{self._environment.value}/", "trade-flows/list_items"),
                params={"country": country, "freq": freq, "partner_region": partner_region},
                timeout=60,
            )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.List[typing.Dict[str, str]], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_import_value(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_6_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        in_usd: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        async with httpx.AsyncClient() as _client:
            _response = await _client.request(
                "GET",
                urllib.parse.urljoin(f"{self._environment.value}/", "trade-flows/get_import_value"),
                params={
                    "country": country,
                    "item": item,
                    "hs6_code": hs_6_code,
                    "partner_region": partner_region,
                    "in_usd": in_usd,
                    "freq": freq,
                },
                timeout=60,
            )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_export_value(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_6_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        in_usd: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        async with httpx.AsyncClient() as _client:
            _response = await _client.request(
                "GET",
                urllib.parse.urljoin(f"{self._environment.value}/", "trade-flows/get_export_value"),
                params={
                    "country": country,
                    "item": item,
                    "hs6_code": hs_6_code,
                    "partner_region": partner_region,
                    "in_usd": in_usd,
                    "freq": freq,
                },
                timeout=60,
            )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_import_volume(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_6_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        async with httpx.AsyncClient() as _client:
            _response = await _client.request(
                "GET",
                urllib.parse.urljoin(f"{self._environment.value}/", "trade-flows/get_import_volume"),
                params={
                    "country": country,
                    "item": item,
                    "hs6_code": hs_6_code,
                    "partner_region": partner_region,
                    "freq": freq,
                },
                timeout=60,
            )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_export_volume(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_6_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        async with httpx.AsyncClient() as _client:
            _response = await _client.request(
                "GET",
                urllib.parse.urljoin(f"{self._environment.value}/", "trade-flows/get_export_volume"),
                params={
                    "country": country,
                    "item": item,
                    "hs6_code": hs_6_code,
                    "partner_region": partner_region,
                    "freq": freq,
                },
                timeout=60,
            )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_all_for_time(
        self,
        *,
        metric: str,
        year: int,
        month: typing.Optional[int] = None,
        quarter: typing.Optional[int] = None,
        item: typing.Optional[str] = None,
        hs_6_code: typing.Optional[str] = None,
        country: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        in_usd: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        async with httpx.AsyncClient() as _client:
            _response = await _client.request(
                "GET",
                urllib.parse.urljoin(f"{self._environment.value}/", "trade-flows/get_all_for_time"),
                params={
                    "metric": metric,
                    "year": year,
                    "month": month,
                    "quarter": quarter,
                    "item": item,
                    "hs6_code": hs_6_code,
                    "country": country,
                    "partner_region": partner_region,
                    "in_usd": in_usd,
                },
                timeout=60,
            )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)
