import logging
from typing import (
    List,
    Optional,
)
from xml.etree import cElementTree as eTree

from custom_sysactions import user_must_be_logged
from sysactions import (
    action,
    show_messagebox,
)

from mw_helper import show_filtered_list_box_dialog
from api.table import get_table_service
from table_manager_api.dto import TableServiceDto
from table_manager_api.dto.exception import TableError

logger = logging.getLogger("TableActions")


@action
@user_must_be_logged
def unlink_tabs(
    pos_id,     # type: str
    tab_id,     # type: str
):
    # type: (...) -> None

    tab_picture_dto = get_table_service(pos_id=pos_id).get_service(table_id=tab_id)

    while True:
        tab_picture_dto = _unlink_tabs(
            pos_id=pos_id,
            tab_picture_dto=tab_picture_dto,
        )
        if tab_picture_dto is None:
            return


def _unlink_tabs(
    pos_id,             # type: str
    tab_picture_dto,    # type: TableServiceDto
):
    # type: (...) -> Optional[TableServiceDto]

    service_children = []
    originator_tab_id = tab_picture_dto.custom_properties.get("ORIGINATOR_TAB_ID")
    for service_child in tab_picture_dto.service_children:
        if originator_tab_id != service_child.table_id:
            service_children.append((service_child.table_name, service_child.table_id))

    if not service_children:
        return

    options = [name.encode("utf-8") for name, _ in service_children]

    selected_index = show_filtered_list_box_dialog(
        pos_id=pos_id,
        options=options,
        title="$SELECT_TAB_TO_UNLINK",
        mask="NOFILTER",
    )

    if selected_index is None:
        return

    tab_picture_dto = unlink_multiple_tabs(
        pos_id=pos_id,
        current_tab_id=tab_picture_dto.table.table_id,
        tabs_to_unlink=[service_children[selected_index][1]],
    )

    if tab_picture_dto is not None:
        from table_actions import create_table_modified_event

        create_table_modified_event(
            pos_id=pos_id,
            table_picture=eTree.tostring(tab_picture_dto.to_xml()),
        )


def unlink_multiple_tabs(
    pos_id,             # type: int
    current_tab_id,     # type: str
    tabs_to_unlink,     # type: List[str]
):
    # type: (...) -> Optional[TableServiceDto]

    try:
        table_picture_dto = get_table_service(pos_id=pos_id).unlink_tabs(
            current_tab_id=current_tab_id,
            tab_ids_to_unlink=tabs_to_unlink,
        )

        return table_picture_dto

    except TableError as ex:
        show_messagebox(
            posid=pos_id,
            message=str(ex),
        )
        logger.info("Error unlinking tabs {} to tab ID {}: {}".format(tabs_to_unlink, current_tab_id, ex))

        return None

    except (Exception,):
        show_messagebox(
            posid=pos_id,
            message="$UNLINK_TABLES_ERROR",
        )
        logger.exception("Error unlinking tabs {} to tab ID {}: ".format(tabs_to_unlink, current_tab_id))

        return None
