from xml.etree import cElementTree as eTree

from actions.config import get_tab_enabled
from actions.table.deselect_table import (
    check_can_return_to_original_table,
    confirm_operation_on_mode_tabs_with_tabs,
    deselect_table,
    check_tab_user_sector,
)
from application.interactor import ReopenTableInteractor
from custom_sysactions import user_authorized_to_execute_action
from msgbusboundary import MsgBusTableService as tableService
from mw_helper import show_message_options_dialog
from sysactions import (
    StopAction,
    action,
    get_current_order,
)
from thread_local import get_current_model
from typing import (
    Dict,
    Optional,
    Tuple,
    Union,
)


@action
@user_authorized_to_execute_action
def reopen_table(
    pos_id,     # type: Union[str, int]
    table_id,   # type: str
):
    # type: (...) -> bool

    from table_actions import create_table_modified_event

    try:
        table_picture = eTree.XML(tableService().get_table_info(
            pos_id=pos_id,
            table_id=table_id,
        ))
        is_a_tab = tableService().is_a_tab(
            pos_id=pos_id,
            table_id=table_id,
            table_picture=table_picture,
        )

        if is_a_tab:
            table_picture, _ = confirm_operation_on_mode_tabs_with_tabs(
                pos_id=pos_id,
                table_picture=table_picture,
            )
            table_id = table_picture.get("id")

        changed_user = False
        slice_source_id = table_picture.get("sliceSourceTableId")
        tab_name = table_picture.get("name")

        if is_a_tab and slice_source_id and not tab_name:
            transferred, changed_user = _reopen_sliced_service(
                pos_id=pos_id,
                table_id=table_id,
                slice_source_id=slice_source_id,
                table_picture=table_picture,
            )
            if transferred is not None:
                return transferred

        model = get_current_model()
        order = get_current_order(model=model)

        from actions.discount.clean_discounts import clean_orders_discounts

        if order is not None:
            clean_orders_discounts(
                pos_id=pos_id,
                orders=[order],
                message="$CLEAR_MANUAL_DISCOUNTS_CONFIRMATION",
            )

        reopen_table_interactor = ReopenTableInteractor(table_service=tableService())
        table_picture = reopen_table_interactor.execute(
            pos_id=pos_id,
            table_id=table_id,
        )
        create_table_modified_event(
            pos_id=pos_id,
            table_picture=table_picture,
        )

        if changed_user:
            deselect_table(
                pos_id=pos_id,
                pre_selected_option=True,
            )

        return True

    except StopAction:
        return False


def _reopen_sliced_service(
    pos_id,             # type: str
    table_id,           # type: str
    slice_source_id,    # type: str
    table_picture,      # type: eTree.Element
):
    # type: (...) -> Tuple[Optional[bool], Optional[bool]]

    can_return_to_original_table = check_can_return_to_original_table(
        pos_id=pos_id,
        slice_source_id=slice_source_id,
        current_table_picture=table_picture,
    )

    options = _get_reopen_options()
    ret = show_message_options_dialog(
        pos_id=pos_id,
        buttons=options["options"],
        message="$CHOOSE_REOPEN_TYPE",
    )

    if ret == options["cancel"]:
        raise StopAction()

    if ret == options["transfer_table"]:

        from table_actions import do_transfer_table

        transferred = do_transfer_table(
            pos_id=pos_id,
            parent_table_id=table_id,
            destination_table_id=slice_source_id if can_return_to_original_table else None,
            select_destination_table=False,
            ignore_totaled_orders=True,
        )
        return transferred, None

    if ret == options["create_tab"]:
        table_picture, changed_user = check_tab_user_sector(
            table_picture=table_picture,
            pos_id=pos_id,
            reopen=True,
        )
        if table_picture is None:
            raise StopAction()

        return None, changed_user


def _get_reopen_options():
    # type: (...) -> Dict[str, Optional[int]]

    if not get_tab_enabled():
        options = "$BACK_FROM_SOURCE_TABLE|$CANCEL"
        transfer_table = 0
        create_tab = None
        cancel = 1
    else:
        options = "$BACK_FROM_SOURCE_TABLE|$CREATE_TAB|$CANCEL"
        transfer_table = 0
        create_tab = 1
        cancel = 2

    return {
        "options": options,
        "cancel": cancel,
        "transfer_table": transfer_table,
        "create_tab": create_tab,
    }
