import json

from mw_helper import ModelService
from sysactions import (
    action,
    get_model,
    StopAction,
    show_messagebox,
    get_podtype,
)
from typing import (
    Any,
    Union
)

from actions.util import check_sangria
from application.interactor import (
    CreateTableOrderInteractor,
    TableInteractor,
)
from custom_sysactions import block_action_if_pos_is_blocked


@action
@block_action_if_pos_is_blocked
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()

    pod_type = get_podtype(model=model)
    model_service = ModelService(pos_id=pos_id)
    price_list = model_service.get_price_list_from_model(
        pod_type=pod_type,
        sale_type="EAT_IN",
    )

    table_service_period_dict = tableService().get_table_custom_property(
        pos_id=pos_id,
        prop="SERVICE_PERIOD_TABLE",
        table_id=table_id,
    )

    if table_service_period_dict:
        table_service_period_json = table_service_period_dict.get("SERVICE_PERIOD_TABLE", "{}")
        table_service_period = json.loads(table_service_period_json).get("servicePeriod")
        if table_service_period is not None:
            price_list = "{}.{}".format(table_service_period, price_list)

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

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

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

    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
