import os

from PyQt5.QtCore import Qt, QSize, pyqtSignal, QUrl
from PyQt5.QtGui import QColor, QDesktopServices
from qgis.PyQt import QtWidgets, uic
from qgis.PyQt.QtWidgets import QHeaderView, QDialogButtonBox
from qgis.core import QgsSingleSymbolRenderer, QgsProject, QgsWkbTypes, QgsApplication, QgsSettings, Qgis, QgsMessageLog


from .chooser_widget import ChooserWidget
from .vectorlayer import get_ordered_layers

BTN_SIZE = QSize(45, 45)
CHECKBOX_COL_IDX = 0
COLOR_COL_IDX = 2
SYMBOL_COL_IDX = 3
NAME_COL_IDX = 1

# This loads your .ui file so that PyQt can populate your plugin with the elements from Qt Designer
FORM_CLASS, _ = uic.loadUiType(os.path.join(
    os.path.dirname(__file__), 'ui/AIAMAS_dialog_base.ui'))


class AIAMASDialog(QtWidgets.QDialog, FORM_CLASS):
    select_signal = pyqtSignal()
    unselect_signal = pyqtSignal()

    def __init__(self, table_rows, parent=None):
        """Constructor."""
        super(AIAMASDialog, self).__init__(parent)
        self.recently_added_layers = []
        self.checked_rows_count = 0

        self.setupUi(self)
        self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
        self.sortCheckBox.setEnabled(False)
        self.sortCheckBox.setChecked(False)

        

        self.table_rows = table_rows

        self.table_rules()

        self.populate_table(self.table_rows)
        QgsProject.instance().layersWillBeRemoved.connect(self.handle_layers_removal)

        self.select_btn.setText("Select All")
        self.select_btn.clicked.connect(self.toggle_selection)

        # Initially disable OK button
        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)

        QgsProject.instance().cleared.connect(self.handle_project_closed)

    def table_rules(self):
        self.tableWidget.verticalHeader().setVisible(False)
        self.tableWidget.setWordWrap(False)
        self.table_header_rules(self.tableWidget.horizontalHeader())
        self.tableWidget.verticalHeader().setDefaultSectionSize(34)
        self.tableWidget.resizeColumnsToContents()

    def handle_project_closed(self):
        """
        Clears the table rows and closes the dialog when the project is cleared or closed.
        """
        self.table_rows.clear()
        self.tableWidget.setRowCount(0)
        self.close()

    @staticmethod
    def table_header_rules(header):
        header.setSectionResizeMode(0, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(1, QHeaderView.Stretch)
        header.setSectionResizeMode(2, QHeaderView.Fixed)
        header.setSectionResizeMode(3, QHeaderView.Fixed)

    def settings_changed(self, table_rows):
        self.table_rows = table_rows

    def handle_layers_removal(self, layer_ids):
        for table_row in self.table_rows:
            vectorlayer = table_row.vectorlayer
            if vectorlayer is None:
                continue
                
            try:
                qgs_layer_id = vectorlayer.qgs_layer_id
                if qgs_layer_id in layer_ids:
                    self.remove_row_from_table(table_row)
                    self.table_rows.remove(table_row)
                    del table_row.vectorlayer
                    del table_row
                    break
            except AttributeError as e:
                QgsMessageLog.logMessage(f"Couldn't access qgs_layer_id: {str(e)}", "AIAMAS", Qgis.Warning)
                continue

    def remove_row_from_table(self, table_row):
        for i in range(self.tableWidget.rowCount()):
            if self.tableWidget.item(i, 1) == table_row.name_field:
                self.tableWidget.removeRow(i)
                break

    def handle_layers_addition(self, new_table_rows):
        for new_table_row in new_table_rows:
            self.table_rows.append(new_table_row)

        self.populate_table(new_table_rows)

    # toggles the button for the selection of all layers
    def toggle_selection(self):
        current_text = self.select_btn.text()

        if current_text == "Select All":
            self.select_signal.emit()
        elif current_text == "Unselect All":
            self.unselect_signal.emit()

    def get_checked_rows(self):
        checked_layer_list = []
        for table_row in self.table_rows:
            try:
                if table_row.vectorlayer.checked:
                    checked_layer_list.append(table_row.vectorlayer)
            except (RuntimeError, AttributeError):
                # Skip if the widget was deleted or vectorlayer is None
                continue
        return checked_layer_list

    # populates the table with the layers and their respective checkboxes, color buttons, and icon buttons
    def populate_table(self, table_rows):
        actual_layers = get_ordered_layers(QgsProject.instance().layerTreeRoot())

        for row_idx, qgs_layer in enumerate(actual_layers):
            for table_row in table_rows:
                if table_row.vectorlayer.qgs_layer_id == qgs_layer.id():
                    self.tableWidget.insertRow(row_idx)
                    self.connect_table_row_btns(table_row)
                    row_data = self.layer_to_row(table_row)

                    for col_idx, col_value in enumerate(row_data):
                        if col_idx == NAME_COL_IDX:
                            self.tableWidget.setItem(row_idx, col_idx, col_value)
                        else:
                            self.tableWidget.setCellWidget(row_idx, col_idx, col_value)

        self.tableWidget.resizeColumnsToContents()
        self.tableWidget.setColumnWidth(NAME_COL_IDX, 250)
        self.tableWidget.setColumnWidth(COLOR_COL_IDX, 75)
        self.tableWidget.setColumnWidth(SYMBOL_COL_IDX, 75)

    def connect_table_row_btns(self, table_row):
        table_row.color_field.clicked.connect(lambda: create_chooser_widget(self, table_row, True))

        if table_row.vectorlayer.qgs_layer.geometryType() is not Qgis.GeometryType.PointGeometry:
            table_row.icon_field.setColor(QColor("gray"))
            table_row.icon_field.setDisabled(True)
        else:
            table_row.icon_field.clicked.connect(lambda: create_chooser_widget(self, table_row, False))

        self.unselect_signal.connect(table_row.unselect_signal_detected)
        self.select_signal.connect(table_row.select_signal_detected)
        
        # Connect the checkbox state changed signal
        table_row.checkbox_state_changed.connect(self.handle_checkbox_state_changed)

    # creates a list of the layers and their respective checkboxes, color buttons, and icon buttons
    @staticmethod
    def layer_to_row(table_row):
        return [table_row.checkbox_container, table_row.name_field, table_row.color_field, table_row.icon_field]
    
    def helpRequest(self):
        help_link = "https://geometalab.gitlab.io/aiamas/aiamas-qgis-plugin/help/"
        QDesktopServices.openUrl(QUrl(help_link))

    def handle_checkbox_state_changed(self, checked):
        """Handle checkbox state changes and update OK button accordingly"""
        if checked:
            self.checked_rows_count += 1
        else:
            self.checked_rows_count -= 1
        
        # Enable OK button if one checkbox is checked
        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(self.checked_rows_count > 0)
        
        # Update button text based on whether all checkboxes are checked
        if self.checked_rows_count == len(self.table_rows):
            self.select_btn.setText("Unselect All")
        elif self.checked_rows_count == 0:
            self.select_btn.setText("Select All")



# creates the color or icon picker widget when the color or icon button is clicked
def create_chooser_widget(parent, table_row, is_color: bool):
    chooser_widget = ChooserWidget(parent=parent, table_row=table_row, is_color=is_color)
    chooser_widget.show()
