from aiohttp.web import Request, Response

from maps_adv.billing_proxy.lib.api.api_providers import ProductsApiProvider
from maps_adv.billing_proxy.lib.api.api_providers.exceptions import ProductDoesNotExist


class Resources:
    __slots__ = ("_provider",)

    def __init__(self, provider: ProductsApiProvider):
        self._provider = provider

    async def retrieve_product(self, request: Request) -> Response:
        product_id = int(request.match_info["product_id"])
        try:
            result = await self._provider.retrieve_product(product_id=product_id)
        except ProductDoesNotExist:
            return Response(status=404)

        return Response(body=result)

    async def list_products(self, request: Request):
        result = await self._provider.list_products()
        return Response(body=result)

    async def list_products_by_service_ids(self, request: Request):
        body = await request.read()
        result = await self._provider.list_products_by_service_ids(body)
        return Response(body=result)

    async def advise_product(self, request: Request) -> Response:
        body = await request.read()
        result = await self._provider.advise_product(body)
        return Response(body=result)

    async def calculate_cpm(self, request: Request) -> Response:
        product_id = int(request.match_info["product_id"])
        body = await request.read()
        result = await self._provider.calculate_cpm(body, product_id=product_id)
        return Response(body=result)

    async def list_clients_bound_to_product(self, request: Request) -> Response:
        product_id = int(request.match_info["product_id"])
        result = await self._provider.list_clients_bound_to_product(
            product_id=product_id
        )
        return Response(body=result)

    async def bind_client_to_product(self, request: Request) -> Response:
        product_id = int(request.match_info["product_id"])
        body = await request.read()
        await self._provider.bind_client_to_product(body, product_id=product_id)
        return Response(status=200)

    async def unbind_client_from_product(self, request: Request) -> Response:
        product_id = int(request.match_info["product_id"])
        body = await request.read()
        await self._provider.unbind_client_from_product(body, product_id=product_id)
        return Response(status=200)

    async def create_product(self, request: Request) -> Response:
        body = await request.read()
        result = await self._provider.create_product(body)
        return Response(body=result, status=201)

    async def update_product(self, request: Request) -> Response:
        product_id = int(request.match_info["product_id"])
        body = await request.read()
        await self._provider.update_product(body, product_id=product_id)
        return Response(status=200)
