from pathlib import Path

from qgis.core import Qgis, QgsProviderConnectionException, QgsProviderRegistry
from qgis.PyQt import uic
from qgis.PyQt.QtWidgets import QDialog, QDialogButtonBox

from plui_versionning.toolbelt import PlgLogger, PlgOptionsManager


class NouvelleProcedureDialog(QDialog):
    """Dialog to create a new procedure."""

    def __init__(self, parent):
        super().__init__(parent)
        self.log = PlgLogger().log
        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.code_proc = None
        self.new_procedure = None

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

        self.cb_code_proc.activated.connect(self.code_proc_changed)
        self.edit_intitule.textChanged.connect(self.set_new_procedure)
        self.edit_commentaires.textChanged.connect(self.set_new_procedure)
        self.buttonBox.accepted.connect(self.apply)
        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
        self.fill_code_proc_combobox()

    def fill_code_proc_combobox(self):
        """Fill combobox with ProcedureUrbaType values"""
        # Clear combobox
        self.cb_code_proc.clear()

        sql = 'select nomproc, lib_nomproc from "{}".procedureurbatype'.format(
            self.db_schema_name
        )
        md = QgsProviderRegistry.instance().providerMetadata("postgres")
        conn = md.createConnection(self.db_connection_uri, {})
        try:
            result = conn.executeSql(sql)
            for proc in result:
                self.cb_code_proc.addItem(proc[1], proc[0])
        except QgsProviderConnectionException as e:
            self.log(message=e, log_level=Qgis.Critical, push=True)
        self.cb_code_proc.setCurrentIndex(-1)

    def code_proc_changed(self, index):
        """Event when user change code_procedure in combobox."""
        if index == -1:
            self.code_proc = None
        self.code_proc = self.cb_code_proc.itemData(index)
        self.set_new_procedure()

    def set_new_procedure(self):
        """Set label to new procedure concatening code + num."""
        if self.code_proc is None:
            self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
        else:
            (
                self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(True)
                if (self.edit_intitule.text())
                else self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
            )
            self.new_procedure = self.code_proc + str(self.get_num_procedure() + 1)
            self.lbl_value_procedure.setText(self.new_procedure)

    def get_num_procedure(self):
        """Get num_proc regarding code_proc."""
        sql = """
        select num_proc from \"{}\".pluiv_procedures
        where code_proc = \'{}\'
        """.format(
            self.db_schema_name, self.code_proc
        )
        md = QgsProviderRegistry.instance().providerMetadata("postgres")
        conn = md.createConnection(self.db_connection_uri, {})
        try:
            result = conn.executeSql(sql)
            return result[0][0] if result else 0
        except QgsProviderConnectionException as e:
            self.log(message=e, log_level=Qgis.Critical, push=True)
        return 0

    def apply(self):
        """Insert new procedure in database."""
        if self.new_procedure is None:
            return
        sql = """
        insert into \"{}\".pluiv_procedures
        (code_proc, num_proc, num_phase, intitule, commentaires)
        values(
            \'{}\',
            {},
            1,
            \'{}\',
            \'{}\'
        ) returning id;
        """.format(
            self.db_schema_name,
            self.code_proc,
            self.get_num_procedure() + 1,
            self.edit_intitule.text(),
            self.edit_commentaires.text(),
        )
        md = QgsProviderRegistry.instance().providerMetadata("postgres")
        conn = md.createConnection(self.db_connection_uri, {})
        try:
            result = conn.executeSql(sql)
            if result:
                self.log(
                    message=f"Procédure {self.edit_intitule.text()} créée.",
                    log_level=Qgis.Info,
                    push=True,
                )
        except QgsProviderConnectionException as e:
            self.log(message=e, log_level=Qgis.Critical, push=True)
