from typing import Union, Iterable, cast, Generator, Any

import axipy
from PySide2.QtCore import Signal
from axipy._internal._observer_abc import _ObserverABC


def get_tables_from_active_map_view() -> Generator[axipy.Table, Any, None]:
    active_view = axipy.view_manager.active
    if isinstance(active_view, axipy.MapView):
        map_view = cast(axipy.MapView, active_view)
        list_layers = map_view.map.layers
        yield from get_tables_from_list_layers(list_layers)

def get_tables_from_list_layers(list_layers: axipy.ListLayers) -> Generator[axipy.Table, Any, None]:
    for elem in list_layers:
        if isinstance(elem, axipy.VectorLayer):
            yield elem.data_object
        elif isinstance(elem, axipy.ListLayers):
            yield from get_tables_from_list_layers(elem)


def check_enabled() -> bool:
    active_view = axipy.view_manager.active
    if not isinstance(active_view, axipy.MapView):
        return False
    map_view = cast(axipy.MapView, active_view)
    return find_vector_layer_recursive(map_view.map.layers)


def find_vector_layer_recursive(list_layers: axipy.ListLayers) -> bool:
    for i in range(len(list_layers)):

        # additional check for unknown layer type
        try:
            elem = list_layers.at(i)
        except Exception:
            continue

        if isinstance(elem, axipy.VectorLayer):
            return True
        elif isinstance(elem, axipy.ListLayers):
            find_vector_layer_recursive(elem)

    return False


class PointsCatalogObserver(_ObserverABC):
    @property
    def name(self) -> str:
        return "ru_axioma_gis_points_catalog_PointsCatalogObserver"

    @property
    def signals(self) -> Union[Signal, Iterable[Signal]]:
        return axipy.view_manager.active_changed

    def test_value(self) -> bool:
        return check_enabled()
