from sysactions import (
    action,
    get_posfunction,
    StopAction,
    show_messagebox,
)

from typing import (
    Any,
    Union,
)
from xml.etree import cElementTree as eTree
from mw_helper import show_message_dialog

from actions.config import (
    can_create_table_parallel_order,
)
from actions.util import check_sangria
from application.interactor import (
    CreateTableOrderInteractor,
    TableInteractor,
)
from thread_local import get_current_model


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

    from msgbusboundary import (
        MsgBusOrderManager,
        MsgBusTableService as tableService,
    )
    from msgbusboundary.ui import MsgBusScreenChanger

    model = get_current_model()
    check_sangria(model, pos_id)
    order_manager = MsgBusOrderManager()
    screen_changer = MsgBusScreenChanger()

    current_table_picture = eTree.XML(tableService().get_table_picture(
        pos_id=pos_id,
        table_id=table_id,
    ))
    current_pos_id = current_table_picture.get("currentPOSId", None)
    if current_pos_id is None or current_pos_id != str(pos_id):
        validate_if_can_add_order = _validate_if_can_add_order(
            pos_id=pos_id,
            table_id=table_id,
            table_picture=current_table_picture
        )
        if not validate_if_can_add_order:
            return False

    if not tableService().is_a_tab(pos_id, table_id):
        parent_table_id = table_id
        table_id = _select_table_or_related_tab_by_dialog(
            pos_id=pos_id,
            table_id=table_id,
        )

        if "TAB" in table_id and parent_table_id != table_id:
            return "0"

    create_table_order_interactor = CreateTableOrderInteractor(
        table_service=tableService(),
        screen_changer=screen_changer,
        order_manager=order_manager,
    )

    if can_create_table_parallel_order():
        tableService().store_service(
            pos_id=pos_id,
            table_id=str(table_id),
        )

    status_order = create_table_order_interactor.execute(
        pos_id=pos_id,
        table_id=table_id,
    )

    return status_order


def _select_table_or_related_tab_by_dialog(
    pos_id,     # type: Any[Union[str, int]]
    table_id,   # type: Any[Union[str, int]]
):
    # type: (...) -> Any[Union[str, int]]

    from msgbusboundary import MsgBusTableService as tableService
    from table_actions import select_table_or_tab
    from actions.table import deselect_table

    table_interactor = TableInteractor(pos_id, table_id, tableService())
    related_services, totaled_services = table_interactor.get_related_services(
        filter_totaled=True
    )

    if not related_services and totaled_services:
        show_messagebox(pos_id, "$HAS_NO_OPENED_TABS", "$INFORMATION")
        raise StopAction()

    selected_table_id = table_interactor.get_selected_related_services(related_services)
    if selected_table_id != table_id:
        deselect_table(pos_id)
        ret = select_table_or_tab(pos_id, selected_table_id)
        if ret:
            return selected_table_id
        else:
            raise StopAction()

    return selected_table_id


def _validate_if_can_add_order(
    pos_id,         # type: Union[str, int]
    table_id,       # type: str
    table_picture,  # type: eTree.Element
):
    # type: (...) -> bool

    from actions.table import validate_if_table_opened_another_pos
    from table_actions import (
        table_has_order_in_progress,
        ask_user_to_create_parallel_order,
    )

    model = get_current_model()
    pos_function = get_posfunction(model=model)

    table_is_opened_another_pos = validate_if_table_opened_another_pos(
        pos_id=pos_id,
        current_table_picture=table_picture,
    )
    if table_is_opened_another_pos:
        return False

    if table_has_order_in_progress(table_picture=table_picture):
        table_properties = table_picture.find("Properties")
        table_mode = table_properties.get("MODE") if table_properties is not None else None
        if table_mode == "tabs" or pos_function == "CS":
            message = "$TABLE_ORDER_IN_PROGRESS|{}".format(table_id)
            show_message_dialog(pos_id, "$INFORMATION", message)
            return False

        if not ask_user_to_create_parallel_order(pos_id=pos_id):
            return False

    return True
