from pathlib import Path

from qgis.core import (
    Qgis,
    QgsPostgresStringUtils,
    QgsProviderConnectionException,
    QgsProviderRegistry,
)
from qgis.PyQt import uic
from qgis.PyQt.QtCore import Qt
from qgis.PyQt.QtWidgets import QDialog, QTableWidgetItem, QWidget

from plui_versionning.core.utils import CLASSES_ENTITE
from plui_versionning.toolbelt import PlgLogger, PlgOptionsManager


class CreateThematiqueDialog(QDialog):
    def __init__(self, id_procedure: int, parent: QWidget = None, *args, **kwds):
        """
        QDialog Créer une thématique
        """
        super().__init__(parent, *args, **kwds)
        self.log = PlgLogger().log

        # DB connection
        self.db_connection_uri = (
            PlgOptionsManager().get_plg_settings().db_connection_uri
        )
        self.db_schema_name = PlgOptionsManager().get_plg_settings().db_schema_name

        uic.loadUi(Path(__file__).parent / f"{Path(__file__).stem}.ui", self)

        self.id_procedure = (
            id_procedure  # Procédure courante dans laquelle créer la thématique
        )
        self.classe_entite = [
            classe
            for classe in CLASSES_ENTITE
            if classe["name"] == self.btn_grp_classe_entite.checkedButton().text()
        ][0]
        self.btn_grp_classe_entite.buttonClicked.connect(self.change_classe)
        self.wdg_create_thematique.refreshCategories.connect(self.load_categories)
        self.table_categories.itemSelectionChanged.connect(self.load_create_thematique)
        self.lbl_procedure_value.setText(self.get_procedure())
        self.wdg_create_thematique.set_classe_entite(self.classe_entite)
        self.wdg_create_thematique.set_procedure(self.id_procedure)

        self.load_categories()

    def change_classe(self, button):
        self.classe_entite = [
            classe for classe in CLASSES_ENTITE if classe["name"] == button.text()
        ][0]
        self.wdg_create_thematique.set_classe_entite(self.classe_entite)
        self.load_categories()

    def list_categories(self):
        query = """
            select code_cnig, array_agg(stype)  from {}.v_pluiv_categories_disponibles
            where classe_entite = '{}'
            group by code_cnig
        """.format(
            self.db_schema_name, self.classe_entite["code"]
        )
        md = QgsProviderRegistry.instance().providerMetadata("postgres")
        conn = md.createConnection(self.db_connection_uri, {})
        try:
            result = conn.executeSql(query)
            if result:
                return result
        except QgsProviderConnectionException as e:
            self.log(message=e, log_level=Qgis.Critical, push=True)

    def load_categories(self):
        self.wdg_create_thematique.setVisible(False)
        self.table_categories.clearContents()
        self.table_categories.setRowCount(0)

        categories = self.list_categories()
        if categories:
            for c in categories:
                self.table_categories.insertRow(self.table_categories.rowCount())
                categorie_item = QTableWidgetItem(
                    f"{self.classe_entite['thematique']}{c[0]}"
                )
                categorie_item.setData(Qt.UserRole, c[0])
                self.table_categories.setItem(
                    self.table_categories.rowCount() - 1, 0, categorie_item
                )
                stype_item = QTableWidgetItem()
                stypes = []
                for stype in QgsPostgresStringUtils.parseArray(c[1] or ""):
                    stypes.append(stype)
                stype_item.setText(", ".join(stypes))
                self.table_categories.setItem(
                    self.table_categories.rowCount() - 1, 1, stype_item
                )

    def load_create_thematique(self):
        if self.table_categories.selectedItems():
            categorie = self.table_categories.selectedItems()[0].data(Qt.UserRole)
            if categorie:
                self.wdg_create_thematique.setVisible(True)
                self.wdg_create_thematique.set_categorie(categorie)

    def get_procedure(self) -> str:
        """Return procedure_plui in pluiv_procedures table regarding id"""
        query = (
            'select procedure_plui from "{}".v_pluiv_procedures where id = {}'.format(
                self.db_schema_name, self.id_procedure
            )
        )
        md = QgsProviderRegistry.instance().providerMetadata("postgres")
        conn = md.createConnection(self.db_connection_uri, {})
        try:
            result = conn.executeSql(query)
            return result[0][0]
        except QgsProviderConnectionException as e:
            self.log(message=e, log_level=Qgis.Critical, push=True)
        return None
