import json

from application.interactor.end_of_sale_notes import EndOfSaleNotesInteractor
from application.interactor.end_of_sale_notes.dto import EndOfSaleNotesRequest
from application.model import AsyncUuidMessageProcessor
from mbcontextmessagehandler import MbContextMessageBus
from messagebus import (
    DataType,
    DefaultToken,
    Event,
    Message,
)
from typing import (
    Dict,
    Optional,
)


class EndOfSaleNotesProcessor(AsyncUuidMessageProcessor):

    def __init__(
        self,           # type: EndOfSaleNotesProcessor
        interactor,     # type: EndOfSaleNotesInteractor
    ):
        # type: (...) -> None

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

    def parse_data(
        self,           # type: EndOfSaleNotesProcessor
        data,           # type: str
        event_type,     # type: str
    ):
        # type: (...) -> EndOfSaleNotesRequest

        request_json = json.loads(data)
        return EndOfSaleNotesRequest(
            pos_id=request_json["posId"],
            order_id=request_json["orderId"],
        )

    def call_business(
        self,       # type: EndOfSaleNotesProcessor
        request,    # type: EndOfSaleNotesRequest
    ):
        # type: (...) -> Optional[Dict[str, str]]

        return self.interactor.execute(request=request)

    def format_response(
        self,           # type: EndOfSaleNotesProcessor
        message_bus,    # type: MbContextMessageBus
        message,        # type: Message
        event,          # type: Event
        request,        # type: None
        response,       # type: str
    ):
        # type: (...) -> None

        if response:
            message_bus.reply_message(
                message=message,
                reply_message=Message(
                    token=DefaultToken.TK_SYS_ACK,
                    data_type=DataType.json,
                    data=response,
                ),
            )
        else:
            message_bus.reply_message(
                message=message,
                reply_message=Message(token=DefaultToken.TK_SYS_NAK),
            )

    def format_exception(
        self,           # type: EndOfSaleNotesProcessor
        message_bus,    # type: MbContextMessageBus
        message,        # type: Message
        event,          # type: Event
        input_obj,      # type: None
        exception,      # type: Exception
    ):
        # type: (...) -> None

        message_bus.reply_message(
            message=message,
            reply_message=Message(
                token=DefaultToken.TK_SYS_NAK,
                data_type=DataType.json,
                data=str(exception),
            ),
        )

    def format_parse_exception(
        self,           # type: EndOfSaleNotesProcessor
        message_bus,    # type: MbContextMessageBus
        message,        # type: Message
        event,          # type: Event
        data,           # type: None
        exception,      # type: Exception
    ):
        # type: (...) -> None

        self.format_exception(
            message_bus=message_bus,
            message=message,
            event=event,
            input_obj=data,
            exception=exception,
        )
