import os
from pathlib import Path

from qgis.core import Qgis, QgsCoordinateReferenceSystem, QgsProject
from qgis.gui import QgisInterface
from qgis.utils import pluginDirectory

from qkan import QKan, enums, get_default_dir
from qkan.database.dbfunc import DBConnection
from qkan.database.qkan_utils import eval_node_types, loadlayer, fehlermeldung
from qkan.plugin import QKanPlugin
from qkan.tools.k_qgsadapt import qgsadapt
from qkan.utils import get_logger

# noinspection PyUnresolvedReferences
from . import resources  # noqa: F401
from ._import import ImportTask
from .application_dialog import ImportDialog

logger = get_logger("QKan.strakat.import")

class StrakatPorter(QKanPlugin):
    def __init__(self, iface: QgisInterface):
        super().__init__(iface)

        default_dir = get_default_dir()
        self.log.debug(f"StrakatPorter: default_dir: {default_dir}")

        self.import_dlg = ImportDialog(default_dir, tr=self.tr)

    # noinspection PyPep8Naming
    def initGui(self) -> None:
        icon_import = ":/plugins/qkan/strakatporter/res/icon_import.png"
        QKan.instance.add_action(
            icon_import,
            text=self.tr("Import aus STRAKAT"),
            callback=self.run_import,
            parent=self.iface.mainWindow(),
        )

    def unload(self) -> None:
        self.import_dlg.close()

    def run_import(self) -> None:
        """Anzeigen des Importformulars STRAKAT und anschließender Start des Import aus einer STRAKAT-Datenbank"""

        self.import_dlg.show()

        if self.import_dlg.exec_():
            # Read from form and save to config
            QKan.config.database.qkan = self.import_dlg.tf_database.text()
            QKan.config.project.file = self.import_dlg.tf_project.text()

            # Falls der Unterordner 'system' ausgewählt wurde, Ordner darüber festlegen
            strakat_import_dir = self.import_dlg.tf_import.text()
            if os.path.split(strakat_import_dir)[1] == 'system':
                QKan.config.strakat.import_dir = os.path.dirname(strakat_import_dir).split[0]
            else:
                QKan.config.strakat.import_dir = strakat_import_dir

            QKan.config.xml.ordner_bild = self.import_dlg.tf_ordnerbild.text().replace('/', '\\')
            QKan.config.xml.ordner_video = self.import_dlg.tf_ordnervideo.text().replace('/', '\\')

            QKan.config.check_import.haltungen = self.import_dlg.cb_haltungen.isChecked()
            QKan.config.check_import.schaechte = self.import_dlg.cb_schaechte.isChecked()
            QKan.config.strakat.coords_from_rohr = self.import_dlg.cb_rohranfang.isChecked()
            QKan.config.check_import.hausanschluesse = self.import_dlg.cb_hausanschluesse.isChecked()
            QKan.config.check_import.schachtschaeden = self.import_dlg.cb_schachtschaeden.isChecked()
            QKan.config.check_import.haltungsschaeden = self.import_dlg.cb_haltungsschaeden.isChecked()
            QKan.config.check_import.hausanschlussschaeden = self.import_dlg.cb_hausanschlussschaeden.isChecked()

            QKan.config.strakat.maxdiff = float(self.import_dlg.tf_maxdist.text())

            QKan.config.check_import.testmodus = self.import_dlg.cb_testmodus.isChecked()

            if not QKan.config.strakat.import_dir:
                self.log.error_user(
                "Fehler beim Import: Es wurde kein Verzeichnis ausgewählt!")
                raise Exception
            else:
                crs: QgsCoordinateReferenceSystem = self.import_dlg.pw_epsg.crs()

                try:
                    epsg = int(crs.postgisSrid())
                except ValueError:
                    # TODO: Reporting this to the user might be preferable
                    self.log.exception(
                        "Failed to parse selected CRS %s\nauthid:%s\n"
                        "description:%s\nproj:%s\npostgisSrid:%s\nsrsid:%s\nacronym:%s",
                        crs,
                        crs.authid(),
                        crs.description(),
                        crs.findMatchingProj(),
                        crs.postgisSrid(),
                        crs.srsid(),
                        crs.ellipsoidAcronym(),
                    )
                else:
                    # TODO: This should all be run in a QgsTask to prevent the main
                    #  thread/GUI from hanging. However this seems to either not work
                    #  or crash QGIS currently. (QGIS 3.10.3/0e1f846438)
                    QKan.config.epsg = epsg

                    QKan.config.save()

                    self._doimport()


    def _doimport(self) -> bool:
        """Start des Import aus einer STRAKAT-Datenbank

        Einspringpunkt für Test
        """
        self.log.info("Opening QKan DB")
        with DBConnection(dbname=QKan.config.database.qkan, epsg=QKan.config.epsg) as db_qkan:
            if not db_qkan.connected:
                logger.error(
                    "Fehler im STRAKAT-Import"
                    f"QKan-Datenbank {QKan.config.database.qkan} wurde nicht gefunden!\nAbbruch!"
                )
                self.iface.messageBar().pushMessage(
                    "Fehler im STRAKAT-Import",
                    f"QKan-Datenbank {QKan.config.database.qkan} wurde nicht gefunden!\nAbbruch!",
                    level=Qgis.Critical,
                )
                return False

            #
            # sql = 'SELECT count(*) AS anz FROM he.Rohr'
            # db_qkan.sql(sql)
            # datatest = db_qkan.fetchone()
            # self.log.debug(f"Testdaten:\n{datatest}")
            #
            #
            self.log.info("DB creation finished, starting importer")
            imp = ImportTask(db_qkan)
            imp.run()
            del imp

            eval_node_types(db_qkan)  # in qkan.database.qkan_utils

            # Write and load new project file, only if new project
            if QgsProject.instance().fileName() == '':
                QKan.config.project.template = str(
                    Path(pluginDirectory("qkan")) / "templates" / "Projekt.qgs"
                )
                qgsadapt(
                    QKan.config.database.qkan,
                    db_qkan,
                    QKan.config.project.file,
                    QKan.config.project.template,
                    QKan.config.epsg,
                )

                # Load generated project
                # noinspection PyArgumentList
                project = QgsProject.instance()
                project.read(QKan.config.project.file)
                project.reloadAllLayers()

        self.log.debug("Closed DB")

        if not loadlayer(
                enums.LAYERBEZ.STRAKAT_SYMBOLE.value,
                'symbole',
                'geom',
                'STRAKAT-Symbole.qml',
                'qkan_symbole.ui',
                'Symbole',
                2,):
            logger.error(
                f"Fehler beim Einfügen des Layers STRAKAT-Symbole"
            )
            return False

        return True

    def click_help(self) -> None:
        """Reaktion auf Klick auf Help-Schaltfläche"""

        help_file = "https://qkan.eu/Qkan_allgemein.html?highlight=strakat"
        os.startfile(help_file)
