import os
from qgis.PyQt.QtWidgets import QWidget, QVBoxLayout, QGridLayout, QComboBox, QGroupBox, QHBoxLayout, QToolButton, QSizePolicy, QSpacerItem, QLabel
from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, Qt
from qgis.PyQt.QtGui import QIcon, QMouseEvent
from SAGisXPlanung import BASE_DIR
from SAGisXPlanung.core.buildingtemplate.template_item import BuildingTemplateCellDataType

class QBuildingTemplateEdit(QWidget):
    cellDataChanged = pyqtSignal(BuildingTemplateCellDataType, int)
    rowCountChanged = pyqtSignal(int, list)
    styleChanged = pyqtSignal(str, object)

    def __init__(self, cells, rows, parent=None):
        super(QBuildingTemplateEdit, self).__init__(parent)
        self.cells = cells
        self.columns = 2
        self.rows = rows
        self._layout = QVBoxLayout()
        self._layout.setContentsMargins(0, 0, 0, 0)
        self.template_form = SelectTemplateFormWidget(default_rows=self.rows)
        self.template_form.rowCountChanged.connect(self.onRowCountChanged)
        self._layout.addWidget(self.template_form)
        self.template_grid_container = QGroupBox('Zellwerte der Nutzungschablone')
        self.template_grid = QGridLayout()
        self.build_template()
        self._layout.addWidget(self.template_grid_container)
        self.setLayout(self._layout)

    def build_template(self):
        QWidget().setLayout(self.template_grid)
        self.template_grid = QGridLayout()
        for i in range(self.rows):
            for j in range(self.columns):
                index = i * self.columns + j % self.columns
                cb = QComboBox()
                cb.setProperty('template-index', index)
                for x in BuildingTemplateCellDataType:
                    cb.addItem(x.value.name, x.name)
                index = cb.findData(self.cells[index].name)
                if index >= 0:
                    cb.setCurrentIndex(index)
                cb.currentIndexChanged.connect(self.onComboBoxIndexChanged)
                self.template_grid.addWidget(cb, i, j)
        self.template_grid_container.setLayout(self.template_grid)

    @pyqtSlot(int)
    def onComboBoxIndexChanged(self, index: int):
        cell_index = self.sender().property('template-index')
        item_value = self.sender().itemData(index)
        item = BuildingTemplateCellDataType[item_value]
        self.cellDataChanged.emit(item, cell_index)

    @pyqtSlot(int)
    def onRowCountChanged(self, row_count: int):
        row_difference = self.rows - row_count
        if row_difference > 0:
            del self.cells[-1 * abs(row_difference) * self.columns:]
        elif row_difference < 0:
            all_cell_types = set([x for x in BuildingTemplateCellDataType])
            unused_cell_types = [x for x in all_cell_types if x not in self.cells]
            for i in range(abs(row_difference) * self.columns):
                self.cells.append(unused_cell_types[i])
        self.rows = row_count
        self.rowCountChanged.emit(self.rows, self.cells)
        self.build_template()

class SelectTemplateFormWidget(QGroupBox):
    rowCountChanged = pyqtSignal(int)

    def __init__(self, default_rows=None, parent=None):
        super(SelectTemplateFormWidget, self).__init__('Form der Nutzungschablone')
        self._layout = QHBoxLayout()
        self.button_small = LabeledButton(QIcon(os.path.join(BASE_DIR, 'gui/resources/grid2x2.svg')), '2 x 2', 2)
        self.button_medium = LabeledButton(QIcon(os.path.join(BASE_DIR, 'gui/resources/grid2x3.svg')), '2 x 3', 3)
        self.button_large = LabeledButton(QIcon(os.path.join(BASE_DIR, 'gui/resources/grid2x4.svg')), '2 x 4', 4)
        self.button_small.buttonToggled.connect(self.onButtonToggled)
        self.button_medium.buttonToggled.connect(self.onButtonToggled)
        self.button_large.buttonToggled.connect(self.onButtonToggled)
        self._buttons = [self.button_small, self.button_medium, self.button_large]
        if default_rows == 2:
            self.button_small.toggleButton(True)
        elif default_rows == 3:
            self.button_medium.toggleButton(True)
        elif default_rows == 4:
            self.button_large.toggleButton(True)
        self._layout.addWidget(self.button_small)
        self._layout.addWidget(self.button_medium)
        self._layout.addWidget(self.button_large)
        self._layout.setSpacing(25)
        self.setLayout(self._layout)
        self.setStyleSheet('\n        QToolButton {\n            border: 0px;\n        }\n        ')

    @pyqtSlot(bool, int)
    def onButtonToggled(self, checked: bool, row_count: int):
        if not checked:
            return
        self.rowCountChanged.emit(row_count)
        for b in self._buttons:
            if b == self.sender():
                continue
            b.toggleButton(False)

class LabeledButton(QWidget):
    buttonToggled = pyqtSignal(bool, int)

    def __init__(self, icon, label_text, row_count):
        super(LabeledButton, self).__init__()
        self.row_count = row_count
        self.setLayout(QVBoxLayout())
        self.setMouseTracking(True)
        self.setCursor(Qt.CursorShape.PointingHandCursor)
        self.setObjectName('back')
        self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True)
        self.layout().setContentsMargins(5, 5, 5, 5)
        self._button = QToolButton()
        self._button.setIcon(icon)
        self._button.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents)
        self.layout().addWidget(self._button, 0, Qt.AlignmentFlag.AlignCenter)
        self.layout().addWidget(QLabel(label_text), 0, Qt.AlignmentFlag.AlignCenter)
        self.setStyleSheet('\n        #back:hover {\n            background-color: #E5E7EB;\n            border: none; \n            border-radius: 3px;\n        }\n        #back[checked=true] {\n            border: 1px solid #1D4ED8;\n            border-radius: 3px;\n        }\n        ')

    def toggleButton(self, checked: bool):
        self.setProperty('checked', checked)
        self.style().unpolish(self)
        self.style().polish(self)
        self.update()
        self.buttonToggled.emit(checked, self.row_count)

    def mouseReleaseEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton and (not self.property('checked')):
            self.toggleButton(True)
        super(LabeledButton, self).mousePressEvent(event)

    def button(self):
        return self._button