from ...store import broadwork_entities as bre
from .report_entities import external_number

# nodes needed for graph generation
NODES = []
MAX_LEVEL = 30


def call_flow_module(node: object, data_store: object):
    # create mapping for easier searchability when gathering nodes
    data_store.build_number_mapping()

    # traverses the enities that forward to eachother and adds all to NODES
    _traverse_connecting_entities(node, data_store)

    return NODES


def _traverse_connecting_entities(entity: object, data_store: object, visited=None):
    if visited is None:
        visited = []

    if entity in visited:
        return
    else:
        visited.append(entity)

    try:
        if isinstance(entity, bre.User):
            # Checks to see if the number is external first and creates external number object for parsing later
            if (
                data_store.number_mapping.get(entity.call_forwarding_always) is None
                and len(str(entity.call_forwarding_always)) >= 3
                and str(entity.call_forwarding_always)[2].isdigit()
            ):
                entity.call_forwarding_always = external_number(
                    str(entity.call_forwarding_always)
                )
            else:
                entity.call_forwarding_always = data_store.number_mapping.get(
                    entity.call_forwarding_always
                )
                if (
                    entity.call_forwarding_always
                    and entity.call_forwarding_always not in visited
                ):
                    _traverse_connecting_entities(
                        entity.call_forwarding_always, data_store, visited
                    )

            if (
                data_store.number_mapping.get(entity.call_forwarding_busy) is None
                and len(str(entity.call_forwarding_busy)) >= 3
                and str(entity.call_forwarding_busy)[2].isdigit()
            ):
                entity.call_forwarding_busy = external_number(
                    str(entity.call_forwarding_busy)
                )
            else:
                entity.call_forwarding_busy = data_store.number_mapping.get(
                    entity.call_forwarding_busy
                )
                if (
                    entity.call_forwarding_busy
                    and entity.call_forwarding_busy not in visited
                ):
                    _traverse_connecting_entities(
                        entity.call_forwarding_busy, data_store, visited
                    )

            if (
                data_store.number_mapping.get(entity.call_forwarding_no_answer) is None
                and len(str(entity.call_forwarding_no_answer)) >= 3
                and str(entity.call_forwarding_no_answer)[2].isdigit()
            ):
                entity.call_forwarding_no_answer = external_number(
                    str(entity.call_forwarding_no_answer)
                )
            else:
                entity.call_forwarding_no_answer = data_store.number_mapping.get(
                    entity.call_forwarding_no_answer
                )
                if (
                    entity.call_forwarding_no_answer
                    and entity.call_forwarding_no_answer not in visited
                ):
                    _traverse_connecting_entities(
                        entity.call_forwarding_no_answer, data_store, visited
                    )

            if (
                data_store.number_mapping.get(entity.call_forwarding_not_reachable)
                is None
                and len(str(entity.call_forwarding_not_reachable)) >= 3
                and str(entity.call_forwarding_not_reachable)[2].isdigit()
            ):
                entity.call_forwarding_not_reachable = external_number(
                    str(entity.call_forwarding_not_reachable)
                )
            else:
                entity.call_forwarding_not_reachable = data_store.number_mapping.get(
                    entity.call_forwarding_not_reachable
                )
                if (
                    entity.call_forwarding_not_reachable
                    and entity.call_forwarding_not_reachable not in visited
                ):
                    _traverse_connecting_entities(
                        entity.call_forwarding_not_reachable, data_store, visited
                    )

        if isinstance(entity, bre.CallCenter):
            if entity.bounced_calls_enabled:
                # Checks to see if the number is external first and creates external number object for parsing later
                if (
                    data_store.number_mapping.get(
                        str(entity.bounced_calls_transfer_to_phone_number)
                    )
                    is None
                    and len(str(entity.bounced_calls_transfer_to_phone_number)) >= 3
                    and str(entity.bounced_calls_transfer_to_phone_number)[2].isdigit()
                ):
                    entity.bounced_calls_transfer_to_phone_number = external_number(
                        str(entity.bounced_calls_transfer_to_phone_number)
                    )
                else:
                    entity.bounced_calls_transfer_to_phone_number = (
                        data_store.number_mapping.get(
                            str(entity.bounced_calls_transfer_to_phone_number)
                        )
                    )
                    if (
                        entity.bounced_calls_transfer_to_phone_number
                        and entity.bounced_calls_transfer_to_phone_number not in visited
                    ):
                        _traverse_connecting_entities(
                            entity.bounced_calls_transfer_to_phone_number,
                            data_store,
                            visited,
                        )

            if entity.overflow_calls_action:
                if (
                    data_store.number_mapping.get(
                        str(entity.overflow_calls_transfer_to_phone_number)
                    )
                    is None
                    and len(str(entity.overflow_calls_transfer_to_phone_number)) >= 3
                    and str(entity.overflow_calls_transfer_to_phone_number)[2].isdigit()
                ):
                    entity.overflow_calls_transfer_to_phone_number = external_number(
                        str(entity.overflow_calls_transfer_to_phone_number)
                    )
                else:
                    entity.overflow_calls_transfer_to_phone_number = (
                        data_store.number_mapping.get(
                            str(entity.overflow_calls_transfer_to_phone_number)
                        )
                    )
                    if (
                        entity.overflow_calls_transfer_to_phone_number
                        and entity.overflow_calls_transfer_to_phone_number
                        not in visited
                    ):
                        _traverse_connecting_entities(
                            entity.overflow_calls_transfer_to_phone_number,
                            data_store,
                            visited,
                        )

            if entity.stranded_calls_action:
                if (
                    data_store.number_mapping.get(
                        str(entity.stranded_calls_transfer_to_phone_number)
                    )
                    is None
                    and len(str(entity.stranded_calls_transfer_to_phone_number)) >= 3
                    and str(entity.stranded_calls_transfer_to_phone_number)[2].isdigit()
                ):
                    entity.stranded_calls_transfer_to_phone_number = external_number(
                        str(entity.stranded_calls_transfer_to_phone_number)
                    )
                else:
                    entity.stranded_calls_transfer_to_phone_number = (
                        data_store.number_mapping.get(
                            str(entity.stranded_calls_transfer_to_phone_number)
                        )
                    )
                    if (
                        entity.stranded_calls_transfer_to_phone_number
                        and entity.stranded_calls_transfer_to_phone_number
                        not in visited
                    ):
                        _traverse_connecting_entities(
                            entity.stranded_calls_transfer_to_phone_number,
                            data_store,
                            visited,
                        )

            if entity.stranded_call_unavailable_action:
                if (
                    data_store.number_mapping.get(
                        str(entity.stranded_call_unavailable_transfer_to_phone_number)
                    )
                    is None
                    and len(
                        str(entity.stranded_call_unavailable_transfer_to_phone_number)
                    )
                    >= 3
                    and str(entity.stranded_call_unavailable_transfer_to_phone_number)[
                        2
                    ].isdigit()
                ):
                    entity.stranded_call_unavailable_transfer_to_phone_number = external_number(
                        str(entity.stranded_call_unavailable_transfer_to_phone_number)
                    )
                else:
                    entity.stranded_call_unavailable_transfer_to_phone_number = data_store.number_mapping.get(
                        str(entity.stranded_call_unavailable_transfer_to_phone_number)
                    )
                    if (
                        entity.stranded_call_unavailable_transfer_to_phone_number
                        and entity.stranded_call_unavailable_transfer_to_phone_number
                        not in visited
                    ):
                        _traverse_connecting_entities(
                            entity.stranded_call_unavailable_transfer_to_phone_number,
                            data_store,
                            visited,
                        )

        if isinstance(entity, bre.HuntGroup):
            if entity.forward_after_timeout_enabled:
                if (
                    data_store.number_mapping.get(
                        entity.no_answer_forward_to_phone_number
                    )
                    is None
                    and len(str(entity.no_answer_forward_to_phone_number)) >= 4
                    and str(entity.no_answer_forward_to_phone_number)[2].isdigit()
                ):
                    entity.no_answer_forward_to_phone_number = external_number(
                        str(entity.no_answer_forward_to_phone_number)
                    )
                else:
                    entity.no_answer_forward_to_phone_number = (
                        data_store.number_mapping.get(
                            str(entity.no_answer_forward_to_phone_number)
                        )
                    )
                    if (
                        entity.no_answer_forward_to_phone_number
                        and entity.no_answer_forward_to_phone_number not in visited
                    ):
                        _traverse_connecting_entities(
                            entity.no_answer_forward_to_phone_number,
                            data_store,
                            visited,
                        )

            if entity.call_forward_not_reachable_enabled:
                if (
                    data_store.number_mapping.get(
                        str(entity.call_forward_not_reachable_transfer_to_phone_number)
                    )
                    is None
                    and len(
                        str(entity.call_forward_not_reachable_transfer_to_phone_number)
                    )
                    >= 3
                    and str(entity.call_forward_not_reachable_transfer_to_phone_number)[
                        2
                    ].isdigit()
                ):
                    entity.call_forward_not_reachable_transfer_to_phone_number = external_number(
                        str(entity.call_forward_not_reachable_transfer_to_phone_number)
                    )
                else:
                    entity.call_forward_not_reachable_transfer_to_phone_number = data_store.number_mapping.get(
                        str(entity.call_forward_not_reachable_transfer_to_phone_number)
                    )
                    if (
                        entity.call_forward_not_reachable_transfer_to_phone_number
                        and entity.call_forward_not_reachable_transfer_to_phone_number
                        not in visited
                    ):
                        _traverse_connecting_entities(
                            entity.call_forward_not_reachable_transfer_to_phone_number,
                            data_store,
                            visited,
                        )

        if isinstance(entity, bre.AutoAttendant):
            for key in entity.business_hours_menu.keys:
                if "Transfer" in key.action:
                    if (
                        data_store.number_mapping.get(str(key.phone_number)) is None
                        and len(str(key.phone_number)) >= 3
                        and str(key.phone_number)[2].isdigit()
                    ):
                        key.phone_number = external_number(str(key.phone_number))
                    else:
                        key.phone_number = data_store.number_mapping.get(
                            str(key.phone_number)
                        )
                        if key.phone_number and key.phone_number not in visited:
                            _traverse_connecting_entities(
                                key.phone_number, data_store, visited
                            )

            for key in entity.after_hours_menu.keys:
                if "Transfer" in key.action:
                    if (
                        data_store.number_mapping.get(str(key.phone_number)) is None
                        and len(str(key.phone_number)) >= 3
                        and str(key.phone_number)[2].isdigit()
                    ):
                        key.phone_number = external_number(str(key.phone_number))
                    else:
                        key.phone_number = data_store.number_mapping.get(
                            str(key.phone_number)
                        )
                        if key.phone_number and key.phone_number not in visited:
                            _traverse_connecting_entities(
                                key.phone_number, data_store, visited
                            )
    except TypeError:
        # this object is further up the tree and a loop has occured - Move one and come back
        pass

    NODES.append(entity)  # Append outside of the if condition
