# SPDX-License-Identifier: GNU GPL v3

"""
Pyside6 implementation of ResponseGT user interface.
"""

import os
import sys
from PySide6.QtCore import QObject
from PySide6.QtWidgets import QApplication
from PySide6.QtQml import QQmlApplicationEngine

from .controllers.main_controller import MainController
from .models.image_provider import ImageProvider


class PySideApp(QObject):

    def _initialize_models(self):
        """Initialize the models and providers used by the QML engine."""
        self._ui_engine.addImageProvider("imageProvider", self._image_provider)
        self._ui_engine.rootContext().setContextProperty("metricsModel", self._ctrl.network_ctrl.metricsModel)
        self._ui_engine.rootContext().setContextProperty("rgtFiles", self._ctrl.network_ctrl.rgtFiles)
        self._ui_engine.rootContext().setContextProperty("rgtParamOptions", self._ctrl.network_ctrl.rgtParamOptions)
        self._ui_engine.rootContext().setContextProperty("rgtResponseOptions", self._ctrl.network_ctrl.rgtResponseOptions)
        self._ui_engine.rootContext().setContextProperty("rgtDCParams", self._ctrl.network_ctrl.rgtDCParams)
        self._ui_engine.rootContext().setContextProperty("rgtPotentialOptions", self._ctrl.network_ctrl.rgtPotentialOptions)
        self._ui_engine.rootContext().setContextProperty("rgtPotentialDirections", self._ctrl.network_ctrl.rgtPotentialDirections)
        self._ui_engine.rootContext().setContextProperty("rgtPinnedDirections", self._ctrl.network_ctrl.rgtPinnedDirections)
        self._ui_engine.rootContext().setContextProperty("rgtDisplacedDirections", self._ctrl.network_ctrl.rgtDisplacedDirections)

    def _initialize_controllers(self):
        """Initialize the controllers used by the QML engine."""
        self._ui_engine.rootContext().setContextProperty("mainController", self._ctrl)
        self._ui_engine.rootContext().setContextProperty("themeManager", self._ctrl.theme_ctrl)
        self._ui_engine.rootContext().setContextProperty("networkController", self._ctrl.network_ctrl)

    def __init__(self):
        super().__init__()
        self.app = QApplication(sys.argv)
        self._ui_engine = QQmlApplicationEngine()
        self._qml_file = 'qml/MainWindow.qml'

        # IMPORTANT: register the "qml" directory
        qml_dir = os.path.dirname(os.path.abspath(__file__))
        qml_path = os.path.join(qml_dir, self._qml_file)
        self._ui_engine.addImportPath(os.path.join(qml_dir, "qml"))

        ## Register Controller for Dynamic Updates
        self._ctrl = MainController(qml_app=self.app)
        ## Register Image Provider
        self._image_provider = ImageProvider(self._ctrl)

        # Set Models in QML Context
        self._initialize_models()
        self._initialize_controllers()

        ## Cleanup when the app is closing
        self.app.aboutToQuit.connect(self._ctrl.cleanup_workers)

        # Set Theme for the entire application UI ('Basic', 'Fusion', 'Imagine', 'Material', 'Universal')
        # QQuickStyle.setStyle("Basic")

        # Load the QML file and display it
        self._ui_engine.load(qml_path)
        if not self._ui_engine.rootObjects():
            sys.exit(-1)

    @classmethod
    def start(cls) -> None:
        """
        Initialize and run the PySide GUI application.
        """
        gui_app = cls()
        sys.exit(gui_app.app.exec())
