import os

from qgis.core import QgsVectorLayer
from qgis.PyQt import uic
from qgis.PyQt.QtGui import QColor
from qgis.PyQt.QtWidgets import (
    QAbstractItemView,
    QHeaderView,
    QTableWidgetItem,
    QWizard,
    QWizardPage,
)

from plui_versionning.core.plui_loader import Mode, PLUiLoader
from plui_versionning.toolbelt import PlgOptionsManager


class PLUiWizard(QWizard):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.plg_settings = PlgOptionsManager()

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

        self.setPage(0, ProcedureWizard(self))
        self.setPage(1, ThematiqueWizard(self))
        self.setPage(2, ProjetWizard(self))
        self.setPage(3, VersionWizard(self))


class ProcedureWizard(QWizardPage):
    def __init__(self, parent):
        super().__init__(parent)
        self.db_connection_uri = parent.db_connection_uri
        self.db_schema_name = parent.db_schema_name

        self.procedureLoadUi = uic.loadUi(
            os.path.join(os.path.dirname(__file__), "ui_table.ui"), self
        )
        self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tableWidget.setSelectionMode(QAbstractItemView.SingleSelection)
        self.tableWidget.itemSelectionChanged.connect(self.onSelectedItem)
        self.tableWidget.itemSelectionChanged.connect(self.completeChanged)
        self.registerField("procedure", self.tableWidget, "currentItem")
        self.tableWidget.setRowCount(0)

    def onSelectedItem(self):
        if self.tableWidget.selectedItems():
            self.setField("procedure", self.tableWidget.selectedItems()[0].text())
            print(f"Procédure sélectionnée : {self.field('procedure')}")

    def isComplete(self) -> bool:
        return bool(self.tableWidget.selectedItems())

    def initializePage(self):
        self.projet = self.field("projet")
        self.tableWidget.setRowCount(0)
        self.setHeaders()
        self.setupTable()

    def setHeaders(self):
        self.tableWidget.setColumnCount(3)
        self.tableWidget.setHorizontalHeaderLabels(
            ["Version", "Intitulé", "Commentaire"]
        )
        header = self.tableWidget.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.Stretch)
        header.setSectionResizeMode(1, QHeaderView.Stretch)
        header.setSectionResizeMode(2, QHeaderView.Stretch)

    def setupTable(self):
        query = f"(select * from {self.db_schema_name}.v_pluiv_procedures)"
        source = f"""{self.db_connection_uri} key='id' table="({query})" ()"""
        self.tmpLayer = QgsVectorLayer(source, "temporary", "postgres")

        if self.tmpLayer.isValid():
            for feature in self.tmpLayer.getFeatures():
                self.feature = feature["procedure_plui"]
                rowPosition = self.tableWidget.rowCount()
                self.tableWidget.insertRow(rowPosition)
                self.tableWidget.setItem(
                    rowPosition, 0, QTableWidgetItem(str(feature["procedure_plui"]))
                )
                self.tableWidget.setItem(
                    rowPosition, 1, QTableWidgetItem(str(feature["intitule"]))
                )
                self.tableWidget.setItem(
                    rowPosition, 2, QTableWidgetItem(str(feature["commentaires"]))
                )

    def loadProcedures(self):
        query = f"(select * from {self.db_schema_name}.pluiv_procedures)"
        source = f"""{self.db_connection_uri} key='id' table="({query})" ()"""
        tmpLayer = QgsVectorLayer(source, "cycles de numerisation", "postgres")
        if tmpLayer.isValid():
            for feature in tmpLayer.getFeatures():
                self.listWidget.addItem(feature["procedure_plui"])


class ThematiqueWizard(QWizardPage):
    def __init__(self, parent):
        super().__init__(parent)
        self.db_connection_uri = parent.db_connection_uri
        self.db_schema_name = parent.db_schema_name
        self.procedureLoadUi = uic.loadUi(
            os.path.join(os.path.dirname(__file__), "ui_table.ui"), self
        )
        self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tableWidget.setSelectionMode(QAbstractItemView.SingleSelection)
        self.tableWidget.itemSelectionChanged.connect(self.onSelectedItem)
        self.tableWidget.itemSelectionChanged.connect(self.completeChanged)
        self.registerField("thematique", self.tableWidget, "currentItem")
        self.tableWidget.setRowCount(0)

    def onSelectedItem(self):
        if self.tableWidget.selectedItems():
            for feature in self.tmpLayer.getFeatures():
                if feature["nom"] == self.tableWidget.selectedItems()[0].text():
                    self.setField("thematique", str(feature["thematique"]))
                    print(f"Thématique sélectionnée : {self.field('thematique')}")

    def isComplete(self) -> bool:
        return bool(self.tableWidget.selectedItems())

    def initializePage(self):
        self.procedurePage = self.field("procedure")
        self.tableWidget.setRowCount(0)
        self.setHeaders()
        self.setupTable()

    def setHeaders(self):
        self.tableWidget.setColumnCount(1)
        self.tableWidget.setHorizontalHeaderLabels(["Thématique"])
        header = self.tableWidget.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.Stretch)

    def setupTable(self):
        """
        Charger les différentes classes d'entités dans le tableau : Zonage, Information, Prescription, Habillage

        Returns:
            tmpLayer QgsVectorLayer: Couche temporaire qui contient le résultat de la requête SQL
        """
        query = """
            SELECT distinct(classe_entite),
            case classe_entite
                when 'zoneurba' then 'ZON'
                when 'prescription' then 'P'
                when 'information' then 'I'
                when 'habillage' then 'H'
                else null
            end as thematique,
            case classe_entite
                when 'zoneurba' then 'Zonage'
                when 'prescription' then 'Prescription'
                when 'information' then 'Information'
                when 'habillage' then 'Habillage'
                else null
            end as nom
            FROM {}.pluiv_structure_entites
            """.format(
            self.db_schema_name
        )
        source = """{} key='classe_entite' table="({})" ()""".format(
            self.db_connection_uri, query
        )
        self.tmpLayer = QgsVectorLayer(source, "temporary", "postgres")
        if self.tmpLayer.isValid():
            for feature in self.tmpLayer.getFeatures():
                rowPosition = self.tableWidget.rowCount()
                self.tableWidget.insertRow(rowPosition)
                self.tableWidget.setItem(
                    rowPosition, 0, QTableWidgetItem(str(feature["nom"]))
                )
        return self.tmpLayer


class ProjetWizard(QWizardPage):
    def __init__(self, parent):
        super().__init__(parent)
        self.db_connection_uri = parent.db_connection_uri
        self.db_schema_name = parent.db_schema_name
        self.procedureLoadUi = uic.loadUi(
            os.path.join(os.path.dirname(__file__), "ui_table.ui"), self
        )

        self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tableWidget.setSelectionMode(QAbstractItemView.SingleSelection)
        self.tableWidget.itemSelectionChanged.connect(self.onSelectedItem)
        self.tableWidget.itemSelectionChanged.connect(self.completeChanged)
        self.registerField("projet", self.tableWidget, "currentItem")
        self.tableWidget.setRowCount(0)

    def onSelectedItem(self):
        if self.tableWidget.selectedItems():
            for feature in self.tmpLayer.getFeatures():
                if feature["id_projet"] == self.tableWidget.selectedItems()[0].text():
                    self.setField("projet", str(feature["thematique"]))
                    print(f"Projet sélectionné : {self.field('projet')}")

    def isComplete(self) -> bool:
        return bool(self.tableWidget.selectedItems())

    def initializePage(self):
        self.procedurePage = self.field("procedure")
        self.thematique = self.field("thematique")
        self.tableWidget.setRowCount(0)
        self.setHeaders()
        self.setupTable()

    def setHeaders(self):
        self.tableWidget.setColumnCount(3)
        self.tableWidget.setHorizontalHeaderLabels(
            ["Version", "intitule", "Commentaire"]
        )
        header = self.tableWidget.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.Stretch)
        header.setSectionResizeMode(1, QHeaderView.Stretch)
        header.setSectionResizeMode(2, QHeaderView.Stretch)

    def setupTable(self):
        query = (
            "(SELECT * FROM {}.v_pluiv_projets WHERE procedure_plui = '"
            + self.procedurePage
            + "' AND thematique LIKE '"
            + self.thematique
            + "%'"
            + ")"
        ).format(self.db_schema_name)
        source = f"""{self.db_connection_uri} key='id' table="({query})" ()"""
        self.tmpLayer = QgsVectorLayer(source, "temporary", "postgres")

        if self.tmpLayer.isValid():
            for feature in self.tmpLayer.getFeatures():
                # self.listWidget.addItem(feature["id_version"])
                self.feature = feature["id_procedure"]
                rowPosition = self.tableWidget.rowCount()
                self.tableWidget.insertRow(rowPosition)
                self.tableWidget.setItem(
                    rowPosition, 0, QTableWidgetItem(str(feature["id_projet"]))
                )
                self.tableWidget.setItem(
                    rowPosition, 1, QTableWidgetItem(str(feature["description"]))
                )
                self.tableWidget.setItem(
                    rowPosition, 2, QTableWidgetItem(str(feature["commentaires"]))
                )

    def loadProjet(self):
        query = (
            "(SELECT * FROM {}.v_pluiv_projets WHERE procedure_plui = '"
            + self.procedurePage
            + "' AND thematique LIKE '"
            + self.thematique
            + "%'"
            + ")"
        ).format(self.db_schema_name)
        source = f"""{self.db_connection_uri} key='id' table="({query})" ()"""
        self.tmpLayer = QgsVectorLayer(source, "temporary", "postgres")
        if self.tmpLayer.isValid():
            for feature in self.tmpLayer.getFeatures():
                self.listWidget.addItem(feature["id_projet"])
        return self.tmpLayer


class VersionWizard(QWizardPage):
    def __init__(self, parent):
        super().__init__(parent)
        self.db_connection_uri = parent.db_connection_uri
        self.db_schema_name = parent.db_schema_name
        self.procedureLoadUi = uic.loadUi(
            os.path.join(os.path.dirname(__file__), "ui_versions.ui"), self
        )
        self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tableWidget.setSelectionMode(QAbstractItemView.SingleSelection)
        self.tableWidget.itemSelectionChanged.connect(self.onSelectedItem)
        self.tableWidget.itemSelectionChanged.connect(self.completeChanged)
        self.addButton.clicked.connect(self.addVersion)
        self.duplicateButton.clicked.connect(self.duplicateVersion)
        self.registerField("version", self.tableWidget, "currentItem")
        self.addButton.setEnabled(False)
        self.duplicateButton.setEnabled(False)
        self.tableWidget.setRowCount(0)

    def onSelectedItem(self):
        if self.tableWidget.selectedItems():
            self.addButton.setEnabled(True)
            self.duplicateButton.setEnabled(True)
            self.setField("version", self.tableWidget.selectedItems()[0].text())
            self.version = self.field("version")
            print(f"Version sélectionnée : {self.field('version')}")

    def isComplete(self) -> bool:
        return bool(self.tableWidget.selectedItems())

    def initializePage(self):
        self.procedure = self.field("procedure")
        self.thematique = self.field("thematique")
        self.projet = self.field("projet")
        self.addButton.setEnabled(False)
        self.duplicateButton.setEnabled(False)
        self.tableWidget.setRowCount(0)
        self.setHeaders()
        self.setupTable()

    def setHeaders(self):
        self.tableWidget.setColumnCount(3)
        self.tableWidget.setHorizontalHeaderLabels(["Version", "Statut", "Commentaire"])
        header = self.tableWidget.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.Stretch)
        header.setSectionResizeMode(1, QHeaderView.Stretch)
        header.setSectionResizeMode(2, QHeaderView.Stretch)

    def setupTable(self):
        query = """
            (SELECT v.id_version, pv.libelle, v.commentaires
            FROM {}.v_pluiv_versions v
            JOIN {}.pluiv_versionlibellestatut pv on v.statut = pv.valeur
            WHERE thematique ='{}'
            )
            """.format(
            self.db_schema_name, self.db_schema_name, self.projet
        )
        source = """{} key='id_version' table="({})" ()""".format(
            self.db_connection_uri, query
        )
        self.tmpLayer = QgsVectorLayer(source, "temporary", "postgres")

        colors = {
            "Référence": QColor(50, 150, 235),
            "En cours": QColor(235, 180, 50),
            "Figée": QColor(235, 65, 50),
            "Abandonnée": QColor(55, 55, 55),
            "Validée": QColor(20, 125, 10),
        }
        if self.tmpLayer.isValid():
            for feature in self.tmpLayer.getFeatures():
                rowPosition = self.tableWidget.rowCount()
                self.tableWidget.insertRow(rowPosition)
                self.tableWidget.setItem(
                    rowPosition, 0, QTableWidgetItem(str(feature["id_version"]))
                )
                self.tableWidget.setItem(
                    rowPosition, 1, QTableWidgetItem(str(feature["libelle"]))
                )
                self.tableWidget.item(rowPosition, 1).setBackground(
                    colors.get(str(feature["libelle"]))
                )
                self.tableWidget.setItem(
                    rowPosition, 2, QTableWidgetItem(str(feature["commentaires"]))
                )

    def addVersion(self):
        loader = PLUiLoader(
            Mode.ADD, self.procedure, self.thematique, self.projet, self.version
        )
        loader.loadLayers()

    def duplicateVersion(self):
        loader = PLUiLoader(
            Mode.DUPLICATE, self.procedure, self.thematique, self.projet, self.version
        )
        loader.loadLayers()

    def loadVersion(self):
        query = (
            "(SELECT * FROM {}.pluiv_versions A WHERE SUBSTRING(A.version_mere,0,12)='"
            + self.projet
            + "')"
        ).format(self.db_schema_name)
        source = f"""{self.db_connection_uri} key='id' table="({query})" ()"""
        self.tmpLayer = QgsVectorLayer(source, "temporary", "postgres")

        if self.tmpLayer.isValid():
            for feature in self.tmpLayer.getFeatures():
                self.listWidget.addItem(feature["id_version"])
                self.feature = feature["id_version"]

        return self.tmpLayer, self.feature
