import json
import logging

from application.interactor.get_loyalty_customer import GetLoyaltyCustomerInfoInteractor
from application.interactor.get_loyalty_customer.dto import GetLoyaltyCustomerInfoRequest
from application.model import AsyncUuidMessageProcessor
from application.model.customexception import NotFoundError
from messagebus import (
    DataType,
    Message,
    AckMessage,
    MessageBus,
    Event,
    InternalErrorMessage,
)
from .tokens import ResponseToken

logger = logging.getLogger(__name__)


class GetLoyaltyCustomerInfoProcessor(AsyncUuidMessageProcessor):
    def __init__(
        self,        # type: GetLoyaltyCustomerInfoProcessor
        interactor,  # type: GetLoyaltyCustomerInfoInteractor
    ):
        # type: (...) -> None

        super(GetLoyaltyCustomerInfoProcessor, self).__init__()
        self.interactor = interactor

    def parse_data(
        self,        # type: GetLoyaltyCustomerInfoProcessor
        data,        # type: bytes
        event_type,  # type: str
    ):
        # type: (...) -> GetLoyaltyCustomerInfoRequest

        request = json.loads(data.decode("utf-8"))

        return GetLoyaltyCustomerInfoRequest(
            pos_id=int(request["posId"]),
            loyalty_id=request["loyaltyId"],
            order_id=request["orderId"] or None,
            table_id=request["tableId"] or None,
            seat=request["seat"],
        )

    def call_business(
        self,       # type: GetLoyaltyCustomerInfoProcessor
        request,    # type: GetLoyaltyCustomerInfoRequest
    ):
        # type: (...) -> None

        return self.interactor.get_loyalty_customer_info(request=request)

    def format_response(
        self,         # type: GetLoyaltyCustomerInfoProcessor
        message_bus,  # type: MessageBus
        message,      # type: Message
        event,        # type: Event
        request,      # type: str
        response,     # type: str
    ):
        message_bus.reply_message(
            message=message,
            reply_message=AckMessage(
                data_type=DataType.string,
                data=response
            )
        )

    def format_exception(
        self,
        message_bus,  # type: MessageBus
        message,      # type: Message
        event,        # type: Event
        input_obj,    # type: str
        exception,    # type: Exception
    ):
        if isinstance(exception, NotFoundError):
            message_bus.reply_message(
                message=message,
                reply_message=Message(token=ResponseToken.TK_LOYALTY_ID_NOT_FOUND.value)
            )
        else:
            message_bus.reply_message(
                message=message,
                reply_message=InternalErrorMessage(exception)
            )

    def format_parse_exception(
        self,
        message_bus,   # type: MessageBus
        message,       # type: Message
        event,         # type: Event
        data,          # type: bytes
        exception,     # type: Exception
    ):
        message_bus.reply_message(
            message=message,
            reply_message=InternalErrorMessage(exception)
        )
