import json
import logging

from typing import (
    Dict,
    Optional,
)

from bustoken import TK_MAINTENANCE_DATABASE_CLEANUP_STATUS
from mw_helper import show_message_options_dialog
from msgbus import (
    FM_STRING,
    TK_SYS_ACK,
)
from pyscripts import mbcontext as mb_context


class MaintenanceInteractor(object):
    def __init__(self):
        # type: (...) -> None

        self.logger = logging.getLogger("PosActions")  # type: logging.Logger

    def verify_clean_databases(
        self,
        period,  # type: str
        pos_id,  # type: str
    ):
        # type: (...) -> None

        status = self._get_status()
        if status:
            cleanup_required = status.get("cleanup_required", False)
            if cleanup_required:
                self._cleanup(period, pos_id)

    def _get_status(self):
        # type: (...) -> Optional[Dict[str, bool]]

        try:
            response = mb_context.MB_EasySendMessage(
                "Maintenance00",
                TK_MAINTENANCE_DATABASE_CLEANUP_STATUS,
                format=FM_STRING,
                timeout=10000 * 1000
            )
            if response.token == TK_SYS_ACK:
                status = json.loads(response.data)
                return status
            else:
                self.logger.error("cannot retrieve database cleanup status from maintenance")
                return None
        except Exception:  # noqa
            self.logger.exception("error retrieving database cleanup status from maintenance")
            return None

    def _cleanup(
        self,
        period,  # type: str
        pos_id,  # type: str
    ):
        # type: (...) -> None

        try:
            response = show_message_options_dialog(
                pos_id,
                "$YES|$NO",
                "$INFORMATION",
                "$CLOSE_DAY_DATABASE_CLEANUP_CONFIRMATION"
            )
            if response is None or response == 1:
                self.logger.info("database cleanup on close day declined by user")
                return

            event_data = {
                "posId": pos_id,
                "businessPeriod": period,
                "vacuum": True,
                "ignoreMaintenanceWindow": True
            }
            mb_context.MB_EasyEvtSend(
                subject="CleanDatabases",
                type="",
                xml=json.dumps(event_data),
                synchronous=False,
                timeout=-1
            )
        except Exception:  # noqa
            self.logger.exception("error sending clean databases event")
