import json

from xml.etree import cElementTree as eTree
from sysactions import (
    action,
    get_model,
    StopAction,
    show_messagebox,
    get_custom,
)

from typing import (
    Any,
    Union,
    Optional,
)

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


@action
def create_table_order(
    pos_id,     # type: str
    table_id,   # type: str
):
    # type: (...) -> str

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

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

    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 (
        deselect_table,
        select_table_or_tab,
    )

    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
