from typing import Dict

import axipy
from axipy import Plugin
from axipy.da import GeometryType
from axipy.gui import view_manager
from PySide2.QtCore import Qt
from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import (
    QCheckBox,
    QDialog,
    QGridLayout,
    QGroupBox,
    QMessageBox,
    QVBoxLayout,
    QWidget,
)

from ..data_types import (
    NamedSearchPatterns,
    SearchGeometries,
    SearchPatterns,
    SearchSettings,
)
from ..utils import geom_type_to_str
from .style_widget_interface import SelectByStyleWidgetInterface


class SelectByStyleWidget(SelectByStyleWidgetInterface):

    def __init__(self, parent: QWidget, iface: Plugin) -> None:
        super().__init__(parent)
        ui_file = str(iface.plugin_dir / "ui" / "SelectByStyle.ui")
        self.__geom_comboboxes = {}  # type: Dict[GeometryType, QCheckBox]
        self.__patterns_comboboxes = {}  # type: Dict[str, QCheckBox]
        self.__ui = self.load_ui(ui_file)
        self.__name_patterns_group = ""
        self.__ui.patternGroupBox.setVisible(False)
        self.__ui.searchGeometriesGroupBox.setVisible(False)
        self.put_content_on_top(False)

    def put_content_on_top(self, is_content_on_top: bool):
        """
        Активирует режим при котором все графические элементы прижаты к
        верхней части панельки.
        """
        self.__ui.spacerWidget.setVisible(is_content_on_top)

    def load_ui(self, ui_file: str) -> QWidget:
        ui = QUiLoader().load(ui_file, self)
        grid_layout = QGridLayout()
        grid_layout.setHorizontalSpacing(0)
        grid_layout.setVerticalSpacing(0)
        grid_layout.addWidget(ui)
        self.setLayout(grid_layout)
        return ui

    def result(self) -> SearchSettings:
        return SearchSettings({self.__name_patterns_group: self.search_patterns}, self.search_geometries)

    @property
    def search_patterns(self) -> SearchPatterns:
        result = {}  # type: SearchPatterns
        for pattern, cb in self.__patterns_comboboxes.items():
            result[pattern] = cb.isChecked()
        return result

    @search_patterns.setter
    def search_patterns(self, patterns: NamedSearchPatterns):
        self.__ui.patternGroupBox.setVisible(len(patterns.patterns))

        def add_search_patterns(patterns_arg: SearchPatterns, group_box: QGroupBox):
            vlayout = QVBoxLayout(group_box)
            for pattern_name, is_checked in patterns_arg.items():
                cb = QCheckBox(pattern_name)
                cb.setCheckState(Qt.Checked if is_checked else Qt.Unchecked)
                vlayout.addWidget(cb)
                self.__patterns_comboboxes[pattern_name] = cb
            group_box.setLayout(vlayout)

        add_search_patterns(patterns.patterns, self.__ui.patternGroupBox)
        self.__name_patterns_group = patterns.name

    @property
    def search_geometries(self) -> SearchGeometries:
        result = {}  # type: SearchGeometries
        for gtype, cb in self.__geom_comboboxes.items():
            result[gtype] = cb.isChecked()
        return result

    @search_geometries.setter
    def search_geometries(self, geometry_types: Dict[GeometryType, bool]):
        self.__ui.searchGeometriesGroupBox.setVisible(len(geometry_types))
        vlayout = QVBoxLayout(self.__ui.searchGeometriesGroupBox)
        for gtype, is_checked in geometry_types.items():
            cb = QCheckBox(geom_type_to_str(gtype))
            cb.setCheckState(Qt.Checked if is_checked else Qt.Unchecked)
            vlayout.addWidget(cb)
            self.__geom_comboboxes[gtype] = cb
        self.__ui.searchGeometriesGroupBox.setLayout(vlayout)

    def accept(self):
        if not self.result().is_valid():
            message = axipy.tr("Не выбрано ни одного типа геометрии для поиска")
            QMessageBox.information(view_manager.global_parent, axipy.tr("Ошибка"), message)
            return
        super().done(QDialog.Accepted)
