import logging

from aiohttp.web import Request, Response

from maps_adv.common.protomallow import with_schemas
from maps_adv.geosmb.telegraphist.server.lib.domain import Domain

from . import schemas

logger = logging.getLogger(__name__)

__all__ = ["Resources"]


class ApiProvider:
    __slots__ = "_domain"

    _domain: Domain

    def __init__(self, domain: Domain):
        self._domain = domain

    @with_schemas(input_schema=schemas.v1.EmailNotificationSchema)
    async def send_notification_v1(self, **kwargs):
        await self._domain.send_notification(**kwargs)

    @with_schemas(
        input_schema=schemas.v2.NotificationSchema,
        output_schema=schemas.v2.NotificationResultSchema,
    )
    async def send_notification_v2(self, **kwargs):
        return await self._domain.send_notification_v2(**kwargs)

    @with_schemas(
        input_schema=schemas.v2.NotificationForBusinessSchema,
        output_schema=schemas.v2.NotificationResultSchema,
    )
    async def send_notification_for_business(self, **kwargs):
        return await self._domain.send_notification_for_business(**kwargs)

    @with_schemas(
        input_schema=schemas.v3.NotificationSchema,
        output_schema=schemas.v3.NotificationResultSchema,
    )
    async def send_notification_v3(self, **kwargs):
        return await self._domain.send_notification_v3(**kwargs)


class Resources:
    __slots__ = ("_provider",)

    _provider: ApiProvider

    def __init__(self, domain: Domain):
        self._provider = ApiProvider(domain)

    async def ping(self, _: Request) -> Response:
        return Response(status=204)

    async def send_notification_v1(self, request: Request) -> Response:
        body = await request.read()

        await self._provider.send_notification_v1(data=body)

        return Response(status=204)

    async def send_notification_v2(self, request: Request) -> Response:
        body = await request.read()

        result = await self._provider.send_notification_v2(data=body)

        return Response(status=200, body=result)

    async def send_notification_for_business(self, request: Request) -> Response:
        body = await request.read()

        result = await self._provider.send_notification_for_business(data=body)

        return Response(status=200, body=result)

    async def send_notification_v3(self, request: Request) -> Response:
        body = await request.read()

        result = await self._provider.send_notification_v3(data=body)

        return Response(status=200, body=result)
