import logging
from xml.etree import cElementTree as eTree

from bustoken import TK_ELECTRONIC_PAYMENT_ADD_PAYMENT
from model.customexception import ElectronicPaymentException
from msgbus import (
    FM_PARAM,
    TK_SYS_ACK,
    MBEasyContext,
)
from sysactions import show_messagebox
from systools import sys_log_exception
from typing import (
    Optional,
    List,
)

from actions.eft import (
    get_electronic_payment_component_name,
    get_tender_id
)

logger = logging.getLogger("PosActions")


def request_eft(
    pos_id,                     # type: str
    mb_context,                 # type: MBEasyContext
    model,                      # type: eTree.XML
    electronic_type,            # type: str
    amount,                     # type: float
    _eft_events,                # type: List
    is_table_service=False,     # type: bool
):
    # type: (...) -> Optional[str]

    from poslistener import eft_status_finish

    order = model.find("CurrentOrder/Order")
    totaled_state = order.findall("StateHistory/State[@state='TOTALED']")[-1]
    last_totaled = totaled_state.get("timestamp").replace("-", "").replace(":", "")
    order_id = order.get("orderId")
    all_tenders = order.find("TenderHistory").findall("Tender")
    tender_id = get_tender_id(all_tenders, is_table_service)
    fiscal_date = last_totaled[:8]
    fiscal_time = last_totaled[9:15]
    operator = model.find("Operator").get("id")
    session_id = model.find("Operator").get("sessionId")
    eft_name = get_electronic_payment_component_name(pos_id=pos_id)
    if eft_name is None:
        raise Exception("None eft found")

    try:
        component_name = eft_name
        evt_data = [eft_name, None, pos_id, order_id]
        _eft_events.append(evt_data)

        data = "%s;%s;%s;%s;%s;%s;%s;%s;%s" % (
            str(pos_id),
            str(order_id),
            str(session_id),
            str(operator),
            str(electronic_type),
            str(amount),
            fiscal_date,
            fiscal_time,
            tender_id,
        )

        log_msg = "Performing electronic payment. {}#{}. TenderId/Amount: {}/{}"
        logger.info(log_msg.format(pos_id, order_id, tender_id, amount))

        response = mb_context.MB_EasySendMessage(
            dest_name=component_name,
            token=TK_ELECTRONIC_PAYMENT_ADD_PAYMENT,
            format=FM_PARAM,
            data=data
        )
        if response.token != TK_SYS_ACK:
            raise ElectronicPaymentException(response.data)

        return response.data
    except Exception as ex: # noqa
        show_messagebox(pos_id, "$ERROR_PROCESSING_TEF|{}".format(ex.message), "$EFT", asynch=True, buttons="$OK")
        error_msg = "Error processing TEF. {}#{}".format(pos_id, order_id)
        logger.exception(error_msg)
        sys_log_exception(error_msg)
        raise
    finally:
        eft_status_finish([pos_id])
