from typing import Iterable, Union, cast

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


def check_geom(g: axipy.Geometry) -> bool:
    if isinstance(g, axipy.Polygon):
        return True
    elif isinstance(g, axipy.LineString):
        points = cast(Iterable[axipy.Pnt], g.points)
        points = list(points)
        return points[0] == points[-1]
    elif isinstance(g, axipy.GeometryCollection):
        return any(map(lambda elem: isinstance(elem, axipy.Polygon), g))

    return False


def test_value() -> bool:
    selection_table = axipy.data_manager.selection
    if selection_table is None:
        return False
    count = selection_table.count()
    if count == 1:
        f = next(selection_table.items())
        g = f.geometry
        if g is None:
            return False
        return check_geom(g)

    return False


class ChooseStartingPointObserver(_ObserverABC):
    @property
    def name(self) -> str:
        return "ru_axioma_gis_axipy_cadtools_ChooseStartingPointObserver"

    @property
    def signals(self) -> Union[Signal, Iterable[Signal]]:
        return axipy.selection_manager.changed, axipy.ObserverManager.SelectionEditableIsSame.changed

    def test_value(self) -> bool:
        return test_value() and axipy.ObserverManager.SelectionEditableIsSame.value

    def active_map_view(self) -> axipy.MapView:
        return cast(axipy.MapView, axipy.view_manager.active)

    def selection_table(self) -> axipy.SelectionTable:
        return cast(axipy.SelectionTable, axipy.data_manager.selection)
