# -*- coding: utf-8 -*-
import sysactions
import logging

from sysactions import (
    get_posfunction,
    get_podtype
)

from posot import OrderTakerException
from typing import (
    Any,
    Union,
)

from actions.order.must_sync_ui import must_sync_ui
from custom_sysactions import (
    user_authorized_to_execute_action,
    block_action_if_order_items_not_resolved,
    fix_current_order_in_model,
)

from actions.discount.clean_discounts import clean_order_payments
from actions.util import is_delivery_order
from actions.delivery.save_delivery_order import save_delivery_order

from model.customexception import OrderNotFoundException

logger = logging.getLogger("PosActions")


@sysactions.action
@user_authorized_to_execute_action
@block_action_if_order_items_not_resolved
def doStoreOrder(
    pos_id,                     	# type: Any[Union[str, int]]
    totalize="none",            	# type: str
    from_total_screen="false",  	# type: str
    pos_id_to_show_message=None,    # type: str
    show_popup=True,            	# type: bool
    *args                       	# type: Any
):
    # type: (...) -> None

    from posactions import (
        doTotal,
        fill_customer_properties_in_event,
    )
    if pos_id_to_show_message is None:
        pos_id_to_show_message = pos_id
    model = sysactions.get_model(pos_id)
    sysactions.check_current_order(pos_id, model=model, need_order=True)
    if from_total_screen.lower() == "true":
        must_sync_ui(
            pos_id=pos_id,
            different_than="TOTALED",
        )
    pos_ot = sysactions.get_posot(model)
    xml_order = sysactions.get_current_order(model)
    clean_order_payments(
        pos_id=pos_id,
        pos_id_to_show_message=pos_id_to_show_message,
        order=xml_order,
        check_manual_discounts=True,
        store=True,
    )

    if sysactions.get_current_order(model).get("type") != "SALE":
        sysactions.show_messagebox(
            posid=pos_id_to_show_message,
            message="$THIS_ORDER_TYPE_CANNOT_BE_STORED",
            icon="warning",
        )
        return

    is_dt_or_fc = get_podtype(model=model) in ["DT", "FC"]
    pod_function = get_posfunction(model=model) if is_dt_or_fc else get_podtype(model=model)
    if totalize == "none" and pod_function == "OT":
        totalize = "true"

    if totalize.lower() != "true" or pod_function == "OT":
        fill_customer_properties_in_event(
            pos_id=pos_id,
            pos_ot=pos_ot,
            pod_function=pod_function,
            key_event='onSave',
        )

    if totalize.lower() == "true" and doTotal(pos_id, screen_number="") == "Error":
        return

    order = model.find("CurrentOrder/Order")
    # Pre-venda
    pre_venda = None
    if pod_function == "OT":
        for prop in order.findall("CustomOrderProperties/OrderProperty"):
            key, value = prop.get("key"), prop.get("value")
            if key == "PRE_VENDA":
                pre_venda = value
                break
    try:
        pos_ot.storeOrder(pos_id)

        if pre_venda:
            sysactions.show_messagebox(
                posid=pos_id_to_show_message,
                message="Pre Venda: PV%010d" % int(pre_venda),
            )
        elif _save_order_on_remote_order(order, pos_id, pos_ot):
            if show_popup:
                sysactions.show_messagebox(
                    posid=pos_id_to_show_message,
                    message="$ORDER_SAVED",
                )

        else:
            sysactions.show_messagebox(
                posid=pos_id_to_show_message,
                message="$ERROR_SAVING_ORDER",
            )
    except OrderTakerException as ex:
        error_code = ex.getErrorCode()
        error_description = ex.getErrorDescr()
        if error_code == 1:
            order = model.find("CurrentOrder/Order")
            order_id = order.get("orderId")
            fix_current_order_in_model(
                pos_id=pos_id,
                model=model,
                order_taker=pos_ot,
                order_id=order_id,
            )
            raise OrderNotFoundException(
                error_code=error_code,
                message=error_description,
            )

        sysactions.show_messagebox(
            posid=pos_id_to_show_message,
            message="$ERROR_CODE_INFO|%d|%s" % (error_code, error_description),
        )

    order = model.find("CurrentOrder/Order")
    order_id = order.get("orderId")
    logger.debug("Pedido Salvo - Order %s - PosId %s" % (order_id, pos_id))


def _save_order_on_remote_order(order, pos_id, pos_ot):
    model = sysactions.get_model(pos_id)
    if is_delivery_order(model):
        order_id = order.get("orderId")

        try:
            save_delivery_order(order_id)
        except (Exception,):
            session = sysactions.get_operator_session(model)
            pos_ot.recallOrder(int(pos_id), int(order_id), session)
            return False

    return True
