import json

import pyscripts

from xml.etree import cElementTree as eTree

from msgbus import (
    FM_PARAM,
    TK_SYS_ACK,
    TK_PRN_GETSTATUS,
)
from sysactions import (
    action,
    get_model,
    get_cfg,
    print_report,
    get_poslist,
    translate_message,
)
from bustoken import TK_PROD_GET_PRINTERS_INFO
from typing import List

from helper import translate_pos_label
from utilfunctions import get_device_service
from .. import logger

mb_context = pyscripts.mbcontext

printer_ok_message = "OK"
printer_not_ok_message = ""
printer_mobile = ""


@action
def get_printer_status(
    pos_id,     # type: str
):
    # type: (...) -> None

    printer_info_list = []

    model = get_model(
        posid=pos_id,
    )

    _translate_messages(
        model=model,
    )

    _get_production_printer_status(
        printer_info_list=printer_info_list
    )

    _get_printer_status_all_pos(
        printer_info_list=printer_info_list,
    )

    _display_report(
        pos_id=pos_id,
        model=model,
        printer_info_list=printer_info_list,
    )


def _get_production_printer_status(
    printer_info_list,  # type: List[List[str]]
):
    # type: (...) -> None

    msg = mb_context.MB_EasySendMessage(
        dest_name="ProductionSystem",
        token=TK_PROD_GET_PRINTERS_INFO,
        format=FM_PARAM,
    )
    if msg.token == TK_SYS_ACK:
        printers = json.loads(msg.data)
        for printer in printers:
            printer_info = [printer]
            printer_status = _find_status_printer(
                printer=printer,
            )
            printer_info.append(printer_status)
            printer_info_list.append(printer_info)


def _translate_messages(
    model,      # type: eTree.XML
):
    # type: (...) -> None

    global printer_mobile, printer_not_ok_message

    if printer_mobile in ["", None]:
        printer_mobile = translate_message(
            model=model,
            message_key="MOBILE_PRINTER_STATUS",
        )

    if printer_not_ok_message in ["", None]:
        printer_not_ok_message = translate_message(
            model=model,
            message_key="MOBILE_PRINTER_STATUS_FAIL",
        )


def _get_printer_status_all_pos(
    printer_info_list,      # type: List[List[str]]
):
    # type: (...) -> None

    pos_list = get_poslist()
    for pos in sorted(pos_list):
        model = get_model(posid=pos)
        pos_label = translate_pos_label(model=model)
        printer_info = ["{} {}".format(pos_label, str(pos).zfill(2))] if pos != 0 else ["Delivery"]
        try:
            pod_function = get_cfg(pos).key_value('pod')
            if pod_function in ("OT", "DL"):
                continue

            printer = get_device_service(
                pos_id=pos,
                device_type="printer",
            )

            logger.info("Find status printer: POS [{}] - Printer: [{}]".format(pos, printer))
            printer_status = _find_status_printer(
                printer=printer,
            )

            printer_info.append(printer_status)

        except (Exception,) as _:
            logger.exception("Error get printer status all pos")
            printer_info.append(printer_not_ok_message)

        printer_info_list.append(printer_info)


def _find_status_printer(
    printer,    # type: str
):
    # type: (...) -> str

    try:
        if not printer:
            logger.info("Find status printer: printer not informed")
            return printer_not_ok_message

        result = mb_context.MB_EasySendMessage(
            dest_name=printer,
            token=TK_PRN_GETSTATUS,
            format=FM_PARAM,
        )

        logger.info("Find status printer: [{}] - result [{}]".format(printer, result.data))
        if result.data == "0":
            return printer_ok_message
        elif str(result.data).upper() == "MOBILE_PRINT":
            return printer_mobile

    except (Exception,) as _:
        logger.exception("Error Find status printer: [{}]".format(printer))

    return printer_not_ok_message


def _display_report(
    pos_id,                 # type: str
    model,                  # type: eTree.XML
    printer_info_list,      # type: List[List[str]]
):
    # type: (...) -> None

    print_report(
        pos_id,
        model,
        True,
        "printer_report",
        pos_id,
        printer_info_list,
    )
