import os

import pyeodh.ades
import requests
from qgis.core import Qgis, QgsMessageLog
from qgis.PyQt import QtCore, QtWidgets, uic

from eodh_qgis.gui.wf_editor_widget import WorkflowEditorWidget
from eodh_qgis.gui.wf_executor_widget import WorkflowExecutorWidget
from eodh_qgis.worker import Worker

# This loads your .ui file so that PyQt can populate your plugin with the elements from
# Qt Designer
FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), "../ui/workflows.ui"))


class WorkflowsWidget(QtWidgets.QWidget, FORM_CLASS):
    def __init__(self, ades_svc: pyeodh.ades.Ades, parent=None):
        """Constructor."""
        super().__init__(parent)
        self.setupUi(self)
        self.ades_svc = ades_svc
        self.processes: list[pyeodh.ades.Process] = []
        self.row_selected = False
        self.threadpool = QtCore.QThreadPool()
        self.new_button: QtWidgets.QPushButton
        self.edit_button: QtWidgets.QPushButton
        self.execute_button: QtWidgets.QPushButton
        self.refresh_button: QtWidgets.QPushButton
        self.remove_button: QtWidgets.QPushButton
        self.table: QtWidgets.QTableWidget

        self.table.cellClicked.connect(self.handle_table_click)
        self.execute_button.clicked.connect(self.handle_execute)
        self.refresh_button.clicked.connect(self.load_workflows)
        # self.new_button.clicked.connect(self.handle_new)
        # self.edit_button.clicked.connect(self.handle_update)
        # self.remove_button.clicked.connect(self.handle_remove)

        # Hide New, Remove, Edit buttons
        self.new_button.hide()
        self.remove_button.hide()
        self.edit_button.hide()

        self.load_workflows()

    def handle_new(self):
        editor = WorkflowEditorWidget(ades_svc=self.ades_svc, parent=self.parent())
        self.parent().addWidget(editor)
        self.parent().setCurrentWidget(editor)

    def handle_update(self):
        editor = WorkflowEditorWidget(
            ades_svc=self.ades_svc,
            update_mode=True,
            process=self.get_selected_process(),
            parent=self.parent(),
        )
        self.parent().addWidget(editor)
        self.parent().setCurrentWidget(editor)

    def handle_execute(self):
        process = self.get_selected_process()
        executor = WorkflowExecutorWidget(
            process_id=process.id,
            ades_svc=self.ades_svc,
            parent=self.parent(),
        )
        self.parent().addWidget(executor)
        self.parent().setCurrentWidget(executor)

    def get_selected_process(self):
        selected_rows = self.table.selectionModel().selectedRows()
        process = self.processes[selected_rows[0].row()]
        return process

    def handle_table_click(self, row, col):
        self.row_selected = True
        self.execute_button.setEnabled(True)
        self.edit_button.setEnabled(True)
        self.remove_button.setEnabled(True)

    def populate_table(self, processes: list[pyeodh.ades.Process]):
        QgsMessageLog.logMessage(f"Loaded {len(processes)} workflows", "EODH", Qgis.Info)
        self.processes = processes
        headers = {
            "id": "ID",
            "title": "Title",
            "description": "Description",
            "version": "Version",
            "keywords": "Keywords",
        }
        self.table.setRowCount(len(processes))
        self.table.setColumnCount(len(headers))
        self.table.setHorizontalHeaderLabels(list(headers.values()))

        for row_index, proc in enumerate(processes):
            for col_index, key in enumerate(headers.keys()):
                self.table.setItem(
                    row_index,
                    col_index,
                    QtWidgets.QTableWidgetItem(str(getattr(proc, key, ""))),
                )

        self.table.show()

    def _on_load_workflows_error(self, error_tuple):
        exctype, value, tb = error_tuple
        QgsMessageLog.logMessage(f"Error loading workflows: {value}\n{tb}", "EODH", Qgis.Critical)

    def load_workflows(self):
        self.lock_form(True)
        QgsMessageLog.logMessage("Loading workflows...", "EODH", Qgis.Info)

        def load_data(*args, **kwargs):
            return self.ades_svc.get_processes()

        worker = Worker(load_data)
        worker.signals.result.connect(self.populate_table)
        worker.signals.error.connect(self._on_load_workflows_error)
        worker.signals.finished.connect(lambda: self.lock_form(False))
        self.threadpool.start(worker)

    def lock_form(self, locked: bool):
        self.new_button.setEnabled(not locked)
        self.edit_button.setEnabled(not locked and self.row_selected)
        self.execute_button.setEnabled(not locked and self.row_selected)
        self.remove_button.setEnabled(not locked and self.row_selected)
        self.table.setEnabled(not locked)

    def handle_remove(self):
        self.lock_form(True)
        process = self.get_selected_process()

        resp = QtWidgets.QMessageBox.question(self, "Confirm", f"Delete {process.id}?")
        if resp != QtWidgets.QMessageBox.Yes:
            self.lock_form(False)
            return

        try:
            process.delete()
        except requests.HTTPError as e:
            QtWidgets.QMessageBox.critical(self, "Error", f"Error un-deploying process {process.id}!\n{e}")
        else:
            QtWidgets.QMessageBox.information(self, "Success", f"Successfully un-deployed {process.id}.")
        finally:
            self.load_workflows()
