from __future__ import annotations

import functools
from collections.abc import *
from typing import Any

import axipy

SUPPORTED_TYPES: tuple[type[axipy.Geometry], ...] = axipy.Polygon, axipy.MultiPolygon
SUPPORTED_TYPES_MESSAGE: tuple[str, ...] = "Полигон", "Коллекция полигонов"


def _run_in_gui_decor(func: Callable) -> Callable:
    @functools.wraps(func)
    def inner(*args, **kwargs) -> Any:
        return axipy.run_in_gui(func, *args, **kwargs)

    return inner


def _init_feature_geom_generator(
        items: Iterable[axipy.Feature],
        count: int,
        task: axipy.DialogTask,
) -> Generator[tuple[axipy.Feature, axipy.Geometry]]:
    progress_max: int = 1000
    one_step: int = 1
    step_needed: bool = False
    n: int = 0

    if count > progress_max:
        one_step = count // progress_max
        step_needed = True

    if step_needed:
        new_max = progress_max
    else:
        new_max = count

    # TODO: task.max resets value in DialogTask
    if task.max != new_max:
        task.max = new_max

    for f in items:
        if task.is_canceled:
            return None

        if step_needed:
            n += 1
            if n % one_step == 0:
                task.value += 1
        else:
            task.value += 1

        g = f.geometry
        if g is not None:
            yield f, g


def _init_geom_generator(
        items: Iterable[axipy.Feature],
        count: int,
        task: axipy.DialogTask,
) -> Generator[axipy.Geometry]:
    for _, g in _init_feature_geom_generator(items, count, task):
        yield g


def get_fields_names(table: axipy.Table) -> list[str]:
    exclude_keys = (axipy.STYLE_ATTR, axipy.GEOMETRY_ATTR)

    item = next(table.items(), None)
    if item is None:
        return []
    keys = item.keys()

    keys = [k for k in keys if k not in exclude_keys]

    return keys
