from aiohttp.web import Request, Response

from maps_adv.billing_proxy.lib.api.api_providers import OrdersApiProvider
from maps_adv.billing_proxy.lib.api.api_providers.exceptions import OrderDoesNotExist


class Resources:
    __slots__ = ("_provider",)

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

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

    async def retrieve_order(self, request: Request) -> Response:
        order_id = int(request.match_info["order_id"])
        try:
            result = await self._provider.retrieve_order(order_id=order_id)
        except OrderDoesNotExist:
            return Response(status=404)
        else:
            return Response(body=result)

    async def retrieve_order_by_external_id(self, request: Request) -> Response:
        external_id = int(request.match_info["external_id"])
        try:
            result = await self._provider.retrieve_order_by_external_id(
                external_id=external_id
            )
        except OrderDoesNotExist:
            return Response(status=404)
        else:
            return Response(body=result)

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

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

    async def list_agency_orders(self, request: Request) -> Response:
        agency_id = request.match_info["agency_id"]
        if "client_id" in request.query:
            client_id = int(request.query["client_id"])
        else:
            client_id = None

        if agency_id == "internal":
            result = await self._provider.list_internal_orders(client_id=client_id)
        else:
            result = await self._provider.list_agency_orders(
                agency_id=agency_id, client_id=client_id
            )

        return Response(body=result)

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

    async def list_internal_orders(self, request: Request) -> Response:
        if "client_id" in request.query:
            client_id = int(request.query["client_id"])
        else:
            client_id = None

        result = await self._provider.list_internal_orders(client_id=client_id)
        return Response(body=result)

    async def create_deposit_request(self, request: Request) -> Response:
        order_id = int(request.match_info["order_id"])
        body = await request.read()

        result = await self._provider.create_deposit_request(body, order_id=order_id)
        return Response(body=result, status=201)

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

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

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

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

    async def update_order(self, request: Request) -> Response:
        order_id = int(request.match_info["order_id"])
        body = await request.read()

        try:
            result = await self._provider.update_order(body, order_id=order_id)
        except OrderDoesNotExist:
            return Response(status=404)

        return Response(body=result, status=200)

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