import json

from typing import Optional

from bustoken import (
    TK_ALERTS_GET_CONFIGURED_ALERTS,
    TK_ALERTS_UPDATE_ALERTS,
)
from msgbus import (
    MBException,
    TK_SYS_ACK,
    TK_SYS_NAK,
)
from sysactions import (
    action,
    close_asynch_dialog,
    get_model,
    show_any_dialog,
    show_messagebox,
    translate_message,
    StopAction,
)

from .. import mb_context
from .configured_alerts_parser import ConfiguredAlertsParser


@action
def show_configured_alerts(
    pos_id,            # type: int
    operator_id=None,  # type: Optional[int]
):
    # type: (...) -> None

    while True:
        resp = _show_configured_alerts(
            pos_id=pos_id,
            operator_id=operator_id,
        )
        if resp is None:
            raise StopAction()

        _update_alerts(
            pos_id,
        )


def _show_configured_alerts(
    pos_id,            # type: int
    operator_id=None,  # type: Optional[int]
):
    # type: (...) -> Optional[str]

    ret = None
    try:
        ret = mb_context.MB_EasySendMessage('Alerts', TK_ALERTS_GET_CONFIGURED_ALERTS)
        if ret.token == TK_SYS_NAK:
            show_messagebox(pos_id, "$GET_CONFIGURED_ALERTS_FAILED", "$ERROR")
            return
    except MBException as ex:
        if "SE_NOTFOUND" in ex.message:
            show_messagebox(
                posid=pos_id,
                message="$COMPONENT_NOT_FOUND|Alerts",
            )
            return None

    parser = ConfiguredAlertsParser(
        pos_id,
        configured_alerts=json.loads(ret.data)
    )

    table_headers = "$USER#$ALERT_TYPE#$ALERT_VALUE"
    table_body = parser.get_data_table()
    table = table_headers + "|" + "|".join(table_body)

    is_manager = not operator_id
    body = dict(isManager=is_manager, rows=table)
    options = json.dumps(body)

    last_updated = parser.get_last_updated()
    last_updated = (
        _unknow_last_updated(pos_id)
        if last_updated is None else last_updated.strftime("%x %X")
    )

    title = "$CONFIGURED_ALERTS_DIALOG_TITLE"
    message = "$CONFIGURED_ALERTS_LAST_UPDATED|{}".format(last_updated)
    buttons = "$UPDATE|$CANCEL"

    resp = show_any_dialog(
        posid=pos_id,
        dlgtype="tabularDataListDialog",
        message=message,
        title=title,
        infotext=options,
        buttons=buttons,
        icon="",
        timeout=600000,
        mask="",
        defvalue="",
        minvalue="",
        maxvalue="",
        contents=None,
        asynch=False,
    )

    return resp


def _update_alerts(
    pos_id,            # type: int
):
    # type: (...) -> None

    wait_dialog_id = show_messagebox(
        posid=pos_id,
        message="$UPDATING_CONFIGURED_ALERTS_PLEASE_WAIT",
        title="$PLEASE_WAIT",
        buttons="",
        asynch=True
    )

    message = "$CONFIGURED_ALERTS_UPDATE_FAILED"
    title = "$ERROR"

    try:
        ret = mb_context.MB_EasySendMessage('Alerts', TK_ALERTS_UPDATE_ALERTS)
        if ret.token == TK_SYS_ACK:
            message = "$CONFIGURED_ALERTS_SUCCESSFULLY_UPDATED"
            title = "$INFORMATION"
    finally:
        close_asynch_dialog(
            posid=pos_id,
            dlgid=wait_dialog_id,
        )
        show_messagebox(
            posid=pos_id,
            message=message,
            title=title,
        )


def _unknow_last_updated(
    pos_id,  # type: int
):
    # type: (...) -> str

    model = get_model(pos_id)
    return translate_message(model, "CONFIGURED_ALERTS_LAST_UPDATED_UNKNOW")
