import itertools

from axipy import Feature, Text, TextStyle, data_manager, tr, view_manager
from axipy.app import Notifications
from axipy.concurrent import (
    AxipyProgressHandler,
    ProgressGuiFlags,
    ProgressSpecification,
    task_manager,
)
from PySide2.QtCore import Qt
from PySide2.QtWidgets import QComboBox, QDialog, QDialogButtonBox, QLabel, QVBoxLayout

counter = 0


class Dialog(QDialog):

    def __init__(self, title):
        super().__init__(view_manager.global_parent)
        self._title = title
        self.setWindowTitle(self._title)

        vbox = QVBoxLayout()

        label = QLabel(tr("Укажите размер текста в пунктах"))
        vbox.addWidget(label)

        self._cbox = QComboBox()
        self._cbox.setEditable(True)
        items = itertools.chain(range(6, 13), range(14, 30, 2), (36, 48, 72))
        items = map(lambda arg: str(arg), items)
        self._cbox.addItems(items)
        vbox.addWidget(self._cbox)

        box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        box.accepted.connect(self.accept)
        self.accepted.connect(self._run)
        box.rejected.connect(self.reject)
        vbox.addWidget(box)

        self.setLayout(vbox)

        self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)  # Выключение значка "?"

    def _run(self):
        spec = ProgressSpecification(
            window_title=self._title, description="Изменение размера текста", flags=ProgressGuiFlags.CANCELABLE
        )
        task_manager.run_and_get(spec, self._change_text_size)

    def _change_text_size(self, ph: AxipyProgressHandler):
        global counter
        counter = 0

        size = int(self._cbox.currentText())
        if size > 1000:
            size = 1000

        selection_table = data_manager.selection
        n = selection_table.count()
        ph.set_max_progress(n)
        items = selection_table.items()

        def update_text_size(f: Feature) -> Feature:
            ph.add_progress(1)
            global counter

            ph.raise_if_canceled()
            style = f.style
            geometry = f.geometry
            if not (isinstance(style, TextStyle) or isinstance(geometry, Text)):
                return f

            counter += 1

            # effects = style.effects
            # effects = (
            #         int(effects.bold) +
            #         int(effects.italic) * 2 +
            #         int(effects.underline) * 4 +
            #         int(effects.shadow) * 32 +
            #         int(effects.capital) * 512 +
            #         int(effects.spacing) * 1024
            # )
            # text_style = TextStyle(style.fontname, size, effects, style.color, style.bg_color)

            text_style = TextStyle(style.fontname, size, 0, style.color, style.bg_color)
            text_style.bold = style.bold
            text_style.italic = style.italic
            text_style.underline = style.underline
            text_style.shadow = style.shadow
            text_style.capital = style.capital
            text_style.spacing = style.spacing

            # style.bold = True
            # text_style = style

            text = Text.create_by_style(
                geometry.text, geometry.startPoint, text_style, view_manager.active, geometry.angle
            )
            f.geometry = text

            return f

        items = map(update_text_size, items)
        try:
            selection_table.update(items)
        except Exception as e:
            print(e)
            counter -= 1
        finally:
            Notifications.push(self._title, f"Изменено объектов: {counter} из {n}.", Notifications.Information)
