import sys
from os.path import dirname, join

import qgis
from qgis.PyQt import QtWidgets, uic
from qgis.core import QgsProject

from qaequilibrae.modules.common_tools import ReportDialog
from qaequilibrae.modules.common_tools import standard_path, get_vector_layer_by_name
from qaequilibrae.modules.common_tools.global_parameters import line_types, point_types
from qaequilibrae.modules.network.Network_preparation_procedure import NetworkPreparationProcedure

sys.modules["qgsmaplayercombobox"] = qgis.gui
sys.modules["qgsfieldcombobox"] = qgis.gui
FORM_CLASS, _ = uic.loadUiType(join(dirname(__file__), "forms/ui_network_preparation.ui"))


class NetworkPreparationDialog(QtWidgets.QDialog, FORM_CLASS):
    def __init__(self, iface):
        QtWidgets.QDialog.__init__(self)
        self.iface = iface
        self.setupUi(self)

        self.filename = False
        self.new_layer = False
        self.radioUseNodes.clicked.connect(self.uses_nodes)
        self.radioNewNodes.clicked.connect(self.uses_nodes)

        self.cbb_node_layer.currentIndexChanged.connect(self.set_columns_nodes)

        self.pushOK.clicked.connect(self.run)
        self.pushClose.clicked.connect(self.exit_procedure)

        self.cbb_line_layer.clear()
        self.cbb_node_layer.clear()

        for layer in qgis.utils.iface.mapCanvas().layers():  # We iterate through all layers
            if "wkbType" in dir(layer):
                if layer.wkbType() in line_types:
                    self.cbb_line_layer.addItem(layer.name())
                if layer.wkbType() in point_types:
                    self.cbb_node_layer.addItem(layer.name())

        # loads default path from parameters
        self.path = standard_path()
        self.uses_nodes()
        self.set_columns_nodes()

    def run_thread(self):
        self.worker_thread.signal.connect(self.signal_handler)
        self.worker_thread.start()
        self.show()

    def signal_handler(self, val):
        if val[0] == "start":
            self.progress_label.setText(val[2])
            self.progressbar.setValue(0)
            self.progressbar.setMaximum(val[1])
        elif val[0] == "update":
            self.progressbar.setValue(val[1])
        elif val[0] == "set_text":
            self.progress_label.setText(val[1])
            self.progressbar.reset()
        elif val[0] == "finished":
            self.job_finished_from_thread()

    def set_columns_nodes(self):
        self.cbb_node_fields.clear()
        if self.cbb_node_layer.currentIndex() >= 0:
            layer = get_vector_layer_by_name(self.cbb_node_layer.currentText())
            self.cbb_node_fields.setLayer(layer)

    def uses_nodes(self):
        for_creating_nodes = [self.OutNodes, self.label_9, self.np_node_start, self.label_3]
        for_using_existing_nodes = [self.cbb_node_layer, self.cbb_node_fields, self.label_2, self.label_4]

        if self.radioUseNodes.isChecked():
            for i in for_creating_nodes:
                i.setVisible(False)
            for i in for_using_existing_nodes:
                i.setVisible(True)
        else:
            for i in for_creating_nodes:
                i.setVisible(True)
            for i in for_using_existing_nodes:
                i.setVisible(False)

            self.np_node_start.setEnabled(True)

    def job_finished_from_thread(self):
        if self.worker_thread.error is not None:
            qgis.utils.iface.messageBar().pushMessage(self.tr("Node layer error: "), self.worker_thread.error, level=3)
        else:
            QgsProject.instance().addMapLayer(self.worker_thread.new_line_layer)
            if self.worker_thread.new_node_layer:
                QgsProject.instance().addMapLayer(self.worker_thread.new_node_layer)
        self.exit_procedure()
        if self.worker_thread.report:
            dlg2 = ReportDialog(self.iface, self.worker_thread.report)
            dlg2.show()
            dlg2.exec_()

    def run(self):
        if self.radioUseNodes.isChecked():
            self.pushOK.setEnabled(False)
            self.worker_thread = NetworkPreparationProcedure(
                qgis.utils.iface.mainWindow(),
                self.cbb_line_layer.currentText(),
                self.OutLinks.text(),
                self.cbb_node_layer.currentText(),
                self.cbb_node_fields.currentText(),
            )
            self.run_thread()

        else:
            self.pushOK.setEnabled(False)
            self.worker_thread = NetworkPreparationProcedure(
                qgis.utils.iface.mainWindow(),
                self.cbb_line_layer.currentText(),
                self.OutLinks.text(),
                new_node_layer=self.OutNodes.text(),
                node_start=int(self.np_node_start.text()),
            )
            self.run_thread()

    def exit_procedure(self):
        self.close()
