import logging
from multiprocessing import Lock

from modelcommon.events import DialogEventType
from sysactions import close_asynch_dialog, show_messagebox

message_lock_dict = Lock()
message_lock = {}
wait_dlg_id = {}
last_error_id = {}


class MessageDialogInteractor(object):
    def __init__(self, pos_id=None):
        # type: (str) -> None

        self.pos_id = pos_id
        self.dialog_id = None
        self.params = None
        self.event_type = None
        self.logger = logging.getLogger("PosActions")

    def configure(self, params, event_type=None):
        # type: (dict, str) -> None

        self.pos_id = str(params.get("pos_id", None))
        self.dialog_id = str(params.get("uuid", None))
        self.params = params
        self.event_type = event_type

    def wait_messages(self):
        # type: () -> None

        global wait_dlg_id
        global last_error_id

        try:
            with self._get_pos_lock(self.pos_id):
                if self.pos_id not in wait_dlg_id:
                    wait_dlg_id[self.pos_id] = {}

                if self.pos_id not in last_error_id:
                    last_error_id[self.pos_id] = None

                message = self.params.get("message", None)

                if self.event_type == DialogEventType.SHOW_WAIT_SCREEN:
                    if self.dialog_id != last_error_id[self.pos_id]:
                        message_id = show_messagebox(self.pos_id, message, timeout=120000, asynch=True, buttons="")
                        wait_dlg_id[self.pos_id][self.dialog_id] = message_id

                    last_error_id[self.pos_id] = None

                if self.event_type == DialogEventType.HIDE_WAIT_SCREEN:
                    if self.dialog_id in wait_dlg_id[self.pos_id]:
                        if close_asynch_dialog(self.pos_id, wait_dlg_id[self.pos_id][self.dialog_id]):
                            del wait_dlg_id[self.pos_id][self.dialog_id]
                        return

                    if last_error_id[self.pos_id] is not None:
                        error_message = "Invalid Id {} for Hide Message on POS {}"
                        self.logger.error(error_message.format(self.dialog_id, str(self.pos_id)))
                    last_error_id[self.pos_id] = self.dialog_id

        except (Exception,):
            self.logger.exception("Error wait messages")

    def clear_pending_messages(self):
        # type: () -> None

        global wait_dlg_id

        with self._get_pos_lock(self.pos_id):
            for dialog in wait_dlg_id.get(self.pos_id, []):
                dialog_id = wait_dlg_id[self.pos_id][dialog]
                close_asynch_dialog(self.pos_id, dialog_id)
            wait_dlg_id[self.pos_id] = {}

    @staticmethod
    def _get_pos_lock(pos_id):
        # type: (str) -> None

        global message_lock
        global message_lock_dict

        with message_lock_dict:
            if pos_id not in message_lock:
                message_lock[pos_id] = Lock()
            return message_lock[pos_id]
