from typing import Optional

import axipy
from axipy import Plugin
from axipy.da import Feature, Style, Table, TextBackgroundType, TextStyle
from axipy.mi import Text

from ..data_types import SearchGroupPatterns
from ..widgets.style_widget_interface import SelectByStyleWidgetInterface
from ..widgets.text_widget import TextWidget
from .strategy_base import SelectStrategy


class TextStrategy(SelectStrategy):
    """
    Стратегия для поиска текстовых объектов по заданному паттерну
    """

    def __init__(self, f: Feature, table: Table) -> None:
        super().__init__(f, table)
        self.__effects = axipy.tr("Эффекты")
        self.__bg_color = axipy.tr("Цвет фона")
        self.__font_color = axipy.tr("Цвет шрифта")
        self.__text = axipy.tr("Текст")
        self.__patterns = [self.__effects, self.__font_color, self.__bg_color, self.__text]

    def identify(self, style: Style) -> bool:
        return isinstance(style, TextStyle)

    def string_pattern_group_key(self) -> str:
        return "text_key"

    def fill_widget(self, widget: TextWidget):
        widget.search_patterns = {p: True for p in self.__patterns}

    def settings_widget(self, iface: Plugin) -> Optional[SelectByStyleWidgetInterface]:
        geom = self.feature.geometry
        if not isinstance(geom, Text):
            return None
        text_widget = TextWidget.make_text_widget(iface, geom)
        text_widget.text_property_key = self.string_pattern_group_key()
        self.fill_widget(text_widget)
        return text_widget

    def is_supported_style(self, target: TextStyle, source: TextStyle, group_patterns: SearchGroupPatterns) -> bool:
        assert isinstance(target, TextStyle)
        assert isinstance(source, TextStyle)
        patterns = group_patterns[self.string_pattern_group_key()]
        if source.fontname != target.fontname:
            return False

        effects_is_equal: bool = (
            source.bold == target.bold
            and source.italic == target.italic
            and source.shadow == target.shadow
            and source.spacing == target.spacing
            and source.underline == target.underline
            and source.capital == target.capital
        )
        if patterns[self.__effects] and not effects_is_equal:
            return False

        if patterns[self.__font_color] and source.color != target.color:
            return False
        # если отрисовка фона текста отключена, то нет смысла проверять цвета
        if source.bg_type != TextBackgroundType.NoBackground:
            if patterns[self.__bg_color] and source.bg_color != target.bg_color:
                return False
        return True

    def is_supported_geometry(self, target: Text, group_patterns: SearchGroupPatterns) -> bool:
        assert isinstance(target, Text)
        patterns = group_patterns[self.string_pattern_group_key()]
        if patterns[self.__text]:
            return target.text == patterns[TextWidget.text_key()]
        return True
