from dataclasses import dataclass
from PyQt5.QtGui import QColor
from qgis.PyQt.QtWidgets import QCheckBox, QHBoxLayout, QWidget, QLabel, QTableWidgetItem
from qgis.PyQt.QtCore import Qt, pyqtSignal, QObject
from .vectorlayer import VectorLayer, symbolize

from .custom_color_button import CustomColorButton
from .custom_symbol_button import CustomSymbolButton
from dataclasses import dataclass

from PyQt5.QtGui import QColor
from qgis.PyQt.QtCore import Qt
from qgis.PyQt.QtWidgets import QCheckBox, QHBoxLayout, QWidget, QLabel, QTableWidgetItem

from .custom_color_button import CustomColorButton
from .custom_symbol_button import CustomSymbolButton
from .vectorlayer import VectorLayer, symbolize


class TableRow(QObject):
    checkbox_state_changed = pyqtSignal(bool)  # Signal to emit checkbox state changes

    def __init__(self, checkbox=None, checkbox_container=None, name_field=None,
                 color_field=None, icon_field=None, vectorlayer=None):
        super().__init__()
        self.checkbox = checkbox
        self.checkbox_container = checkbox_container
        self.name_field = name_field
        self.color_field = color_field
        self.icon_field = icon_field
        self.vectorlayer = vectorlayer
        self.needs_update = False

    @classmethod
    def create_table_rows_after_loading(cls, q_layers):
        layers = VectorLayer.add_layers_after_loading(q_layers)
        return [cls.create_table_row(layer) for layer in layers]

    @classmethod
    def create_table_rows_from_qgis_project(cls):
        layers = VectorLayer.get_all_from_qgs_project()
        return [cls.create_table_row(layer) for layer in layers]

    @classmethod
    def create_table_row(cls, layer: VectorLayer):
        checkbox = QCheckBox()
        checkbox_container = cls.ready_up_checkbox(checkbox)
        name_field = cls.create_name_field(layer)
        color_field = cls.create_color_field(layer)
        icon_fild = cls.create_icon_field(layer)

        new_table_row = cls(checkbox=checkbox, checkbox_container=checkbox_container, name_field=name_field,
                            color_field=color_field, icon_field=icon_fild, vectorlayer=layer)

        new_table_row.configure_CheckBox()
        layer.qgs_layer.nameChanged.connect(new_table_row.handle_name_change)

        return new_table_row

    @classmethod
    def update_table_rows(cls, table_rows):
        table_rows_to_update = []
        for table_row in table_rows:
            if table_row.needs_update:
                table_rows_to_update.append(table_row)
                table_row.needs_update = False

        symbolize([table_row.vectorlayer for table_row in table_rows_to_update])

        for table_row in table_rows_to_update:
            table_row.update_table_row()

    def handle_name_change(self):
        self.needs_update = True

    def update_table_row(self):
        self.update_layer_name()
        self.update_color_field()
        self.update_icon_field()

    def update_layer_name(self):
        self.name_field.setText(str(self.vectorlayer.name))

    def update_color_field(self):
        self.color_field.setColor(self.vectorlayer.suggested_symbol.color())

    def update_icon_field(self):
        self.icon_field.setLayer(self.vectorlayer.qgs_layer)
        cloned_symbol = self.vectorlayer.suggested_symbol.clone()
        self.icon_field.setSymbol(cloned_symbol)

    def select_signal_detected(self):
        return self.checkbox.setChecked(True)

    def unselect_signal_detected(self):
        return self.checkbox.setChecked(False)

    def configure_CheckBox(self):
        self.checkbox.setChecked(False)
        self.update_layer_name_color(False)  # Initial color grey

        self.checkbox.stateChanged.connect(lambda state: self.update_layer_name_color(state == Qt.Checked))
        self.checkbox.stateChanged.connect(lambda state: self.vectorlayer.change_checked(self.checkbox.isChecked()))
        self.checkbox.stateChanged.connect(lambda state: self.checkbox_state_changed.emit(state == Qt.Checked))

    @staticmethod
    def ready_up_checkbox(checkbox: QCheckBox):
        layout = QHBoxLayout()
        layout.addWidget(checkbox)
        layout.setAlignment(checkbox, Qt.AlignCenter)

        cell_widget = QWidget()
        cell_widget.setLayout(layout)

        return cell_widget

    @staticmethod
    def create_name_field(layer: VectorLayer):
        return QTableWidgetItem(str(layer.name))

    @staticmethod
    def create_color_field(layer: VectorLayer):
        color_selector = CustomColorButton()
        color_selector.setColor(layer.suggested_symbol.color())

        return color_selector

    @staticmethod
    def create_icon_field(layer: VectorLayer):
        icon_selector = CustomSymbolButton()
        icon_selector.setLayer(layer.qgs_layer)
        cloned_symbol = layer.suggested_symbol.clone()
        icon_selector.setSymbol(cloned_symbol)

        return icon_selector

    def update_layer_name_color(self, checked: bool):
        if self.name_field:
            color = QColor("black" if checked else "gray")
            self.name_field.setForeground(color)

    @staticmethod
    def ready_up_checkbox(checkbox: QCheckBox):
        layout = QHBoxLayout()
        layout.addWidget(checkbox)
        layout.setAlignment(checkbox, Qt.AlignCenter)

        cell_widget = QWidget()
        cell_widget.setLayout(layout)

        return cell_widget

    @staticmethod
    def create_name_field(layer: VectorLayer):
        return QTableWidgetItem(str(layer.name))

    @staticmethod
    def create_color_field(layer: VectorLayer):
        color_selector = CustomColorButton()
        color_selector.setColor(layer.suggested_symbol.color())

        return color_selector

    @staticmethod
    def create_icon_field(layer: VectorLayer):
        icon_selector = CustomSymbolButton()
        icon_selector.setLayer(layer.qgs_layer)
        cloned_symbol = layer.suggested_symbol.clone()
        icon_selector.setSymbol(cloned_symbol)

        return icon_selector

    def update_layer_name_color(self, checked: bool):
        if self.name_field:
            color = QColor("black" if checked else "gray")
            self.name_field.setForeground(color)
