#! python3  # noqa: E265

"""Main plugin module."""
import os
from configparser import ConfigParser
# standard
from functools import partial
from pathlib import Path

# PyQGIS
from qgis.core import Qgis, QgsApplication, QgsSettings
from qgis.gui import QgisInterface
from qgis.PyQt.QtCore import QCoreApplication, QLocale, QTranslator, QUrl
from qgis.PyQt.QtGui import QDesktopServices, QIcon, QKeySequence
from qgis.PyQt.QtWidgets import QAction

# project
from scientific_color_maps.__about__ import (
    DIR_PLUGIN_ROOT,
    __icon_path__,
    __title__,
    __uri_homepage__,
)
from scientific_color_maps.gui.dlg_settings import PlgOptionsFactory
from scientific_color_maps.gui.dlg_file_browser import ColorRampBrowserDialog

from scientific_color_maps.toolbelt import PlgLogger

# ############################################################################
# ########## Classes ###############
# ##################################


class ScientificColorMap:
    def __init__(self, iface: QgisInterface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class which \
        provides the hook by which you can manipulate the QGIS application at run time.
        :type iface: QgsInterface
        """
        self.iface = iface
        self.log = PlgLogger().log
        self.file_browser_dialog = None

        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # print version number
        config = ConfigParser()
        config.read(f'{self.plugin_dir}/metadata.txt')
        print(f"{config.get('general', 'name')} {config.get('general', 'version')} loaded")

        # translation
        # initialize the locale
        self.locale: str = QgsSettings().value("locale/userLocale", QLocale().name())[0:2]
        locale_path: Path = (DIR_PLUGIN_ROOT / "resources" / "i18n" / f"plugin_translation_{self.locale}.qm")
        self.log(message=f"Translation: {self.locale}, {locale_path}", log_level=Qgis.MessageLevel.Critical)

        if locale_path.exists():
            self.translator = QTranslator()
            self.translator.load(str(locale_path.resolve()))
            QCoreApplication.installTranslator(self.translator)

    def initGui(self):
        """Set up plugin UI elements."""

        # settings page within the QGIS preferences menu
        self.options_factory = PlgOptionsFactory()
        self.iface.registerOptionsWidgetFactory(self.options_factory)

        # -- Actions
        self.action_help = QAction(
            QgsApplication.getThemeIcon("mActionHelpContents.svg"),
            self.tr("Help"),
            self.iface.mainWindow(),
        )
        self.action_help.triggered.connect(
            partial(QDesktopServices.openUrl, QUrl(__uri_homepage__))
        )

        self.action_settings = QAction(
            QgsApplication.getThemeIcon("console/iconSettingsConsole.svg"),
            self.tr("Settings"),
            self.iface.mainWindow(),
        )
        self.action_settings.triggered.connect(
            lambda: self.iface.showOptionsDialog(
                currentPage="mOptionsPage{}".format(__title__)
            )
        )

        self.action_file_browser = QAction(
            QgsApplication.getThemeIcon("mActionFileOpen.svg"),
            self.tr("Browse XML Color Maps"),
            self.iface.mainWindow(),
        )
        self.action_file_browser.setShortcut(QKeySequence("Ctrl+Alt+S"))
        self.action_file_browser.triggered.connect(self.open_file_browser)

        # -- Menu
        self.iface.addPluginToMenu(__title__, self.action_file_browser)
        self.iface.addPluginToMenu(__title__, self.action_settings)
        self.iface.addPluginToMenu(__title__, self.action_help)

        # -- Plugin menu icon
        plugin_menu = self.iface.pluginMenu()
        for action in plugin_menu.actions():
            if action.text() == __title__:
                action.setIcon(QIcon(str(__icon_path__)))
                break

        # -- Help menu

        # documentation
        self.iface.pluginHelpMenu().addSeparator()
        self.action_help_plugin_menu_documentation = QAction(
            QIcon(str(__icon_path__)),
            f"{__title__} - Documentation",
            self.iface.mainWindow(),
        )
        self.action_help_plugin_menu_documentation.triggered.connect(
            partial(QDesktopServices.openUrl, QUrl(__uri_homepage__))
        )

        self.iface.pluginHelpMenu().addAction(
            self.action_help_plugin_menu_documentation
        )

    def tr(self, message: str) -> str:
        """Get the translation for a string using Qt translation API.

        :param message: string to be translated.
        :type message: str

        :returns: Translated version of message.
        :rtype: str
        """
        return QCoreApplication.translate(self.__class__.__name__, message)

    def unload(self):
        """Cleans up when plugin is disabled/uninstalled."""
        # -- Clean up menu
        self.iface.removePluginMenu(__title__, self.action_help)
        self.iface.removePluginMenu(__title__, self.action_settings)
        self.iface.removePluginMenu(__title__, self.action_file_browser)

        # -- Clean up preferences panel in QGIS settings
        self.iface.unregisterOptionsWidgetFactory(self.options_factory)

        # remove from QGIS help/extensions menu
        if self.action_help_plugin_menu_documentation:
            self.iface.pluginHelpMenu().removeAction(
                self.action_help_plugin_menu_documentation
            )

        # remove actions
        del self.action_settings
        del self.action_help
        del self.action_file_browser

        # close dialog if open
        if self.file_browser_dialog:
            self.file_browser_dialog.close()
            self.file_browser_dialog = None

    def open_file_browser(self):
        """Open the color ramp browser dialog."""
        if self.file_browser_dialog is None:
            self.file_browser_dialog = ColorRampBrowserDialog(self.iface.mainWindow())

        self.file_browser_dialog.show()
        self.file_browser_dialog.raise_()
        self.file_browser_dialog.activateWindow()

    def run(self):
        """Main process.

        :raises Exception: if there is no item in the feed
        """
        try:
            self.log(
                message=self.tr("Everything ran OK."),
                log_level=Qgis.MessageLevel.Success,
                push=False,
            )
        except Exception as err:
            self.log(
                message=self.tr("Houston, we've got a problem: {}".format(err)),
                log_level=Qgis.MessageLevel.Critical,
                push=True,
            )
