import json
import logging
import sysactions

from xml.etree import cElementTree as eTree
from actions.eft import has_electronic_payment, get_electronic_tenders
from bustoken import TK_SITEF_CANCEL_PAYMENT_ORDER
from msgbus import TK_SYS_ACK, FM_PARAM
from sysactions import mbcontext
from typing import Optional

logger = logging.getLogger("EftActions")


def cancel_eft_transactions(
        pos_id,     # type: str
        model,      # type: eTree.XML
        order_id    # type: str
):
    # type: (...) -> Optional[str]

    order_taker = sysactions.get_posot(model)

    if not order_id:
        order_picture = order_taker.orderPicture(pos_id)
    else:
        order_picture = order_taker.orderPicture(orderid=order_id)
    order = eTree.XML(order_picture).find("Order")

    if not has_electronic_payment(order):
        return

    component_name = "Sitef%02d" % int(pos_id)
    last_totaled = order.findall("StateHistory/State[@state='TOTALED']")[-1]
    last_totaled_date = last_totaled.get("timestamp").replace("-", "").replace(":", "")

    tenders = get_electronic_tenders(order)
    for tender in tenders:
        tender_amount = float(tender.get("amount"))
        if tender_amount == 0:
            continue

        tender_type = tender.get("type")
        detail = tender.get("detail")
        data = json.dumps(
            {
                "posId": pos_id,
                "orderId": order_id,
                "tenderType": tender_type,
                "tenderAmount": tender_amount,
                "fiscalDate": last_totaled_date[:8],
                "fiscalTime": last_totaled_date[9:15],
                "tenderDetail": detail
            }
        )
        try:
            timeout = 600000000
            token = TK_SITEF_CANCEL_PAYMENT_ORDER
            result = mbcontext.MB_EasySendMessage(component_name, token, FM_PARAM, data, timeout)

            if result.token == TK_SYS_ACK:
                return json.loads(result.data)

            logger.error("Error cancel payment: {} - Tender: {}".format(result.data, tender.get("id")))
            sysactions.show_messagebox(pos_id, result.data)
        except Exception as _:
            logger.exception("Error cancel payment: Tender: {}".format(tender.get("id")))
            sysactions.show_messagebox(pos_id, "$ERROR_CANCEL_ELECTRONIC_PAYMENTS_ORDER")
