# -*- coding: utf-8 -*-
"""
/***************************************************************************
 opencage_geocoder
                                 A QGIS plugin
 Geocoding using the OpenCage API
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2023-01-11
        copyright            : (C) 2023 by opencage
        email                : info@byteroad.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
 This script initializes the plugin, making it known to QGIS.
"""

__author__ = 'doublebyte'
__date__ = '2023-01-11'
__copyright__ = '(C) 2023 by opencage'

import pdb
#from functools import partial

from qgis.PyQt import uic
from qgis.PyQt.QtCore import (
    QCoreApplication,
    QThread
)
from qgis.PyQt.QtWidgets import (
    QPushButton
)

from qgis.core import (
    QgsSettings,
    Qgis,
    QgsApplication
)
from qgis.gui import (
    QgsOptionsPageWidget,
    QgsGeocoderLocatorFilter,
    QgsOptionsWidgetFactory
)


from opencage_geocoder.gui_utils import GuiUtils
from opencage_geocoder.processing.provider import OpenCageProvider

from qgis.PyQt.QtCore import pyqtRemoveInputHook
# These lines allow you to set a breakpoint in the app
pyqtRemoveInputHook()

message_bar_widget=None

# noinspection PyPep8Naming
def classFactory(iface):  # pylint: disable=invalid-name
    """Load OpenCage class from file OpenCageProcessing.

    :param iface: A QGIS interface instance.
    :type iface: QgsInterface
    """
    #
    return OpenCagePlugin(iface)

OPTIONS_WIDGET, OPTIONS_BASE = uic.loadUiType(
    GuiUtils.get_ui_path('settings.ui'))

class OpenCageOptionsPage(OPTIONS_WIDGET, QgsOptionsPageWidget):
    """
    OpenCage options widget
    """

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        self.setObjectName('OpenCageOptions')

        self.plugin = None

    def set_plugin(self, plugin):
        self.plugin = plugin
        self.api_key_line_edit.setText(plugin.api_key)

    def apply(self):
        """
        Applies the new settings
        """
        self.plugin.set_api_key(self.api_key_line_edit.text())

class OpenCageOptionsFactory(QgsOptionsWidgetFactory):
    """
    Factory class for OpenCage options widget
    """

    def __init__(self, plugin):  # pylint: disable=useless-super-delegation
        super().__init__()
        self.plugin = plugin

    def icon(self):  # pylint: disable=missing-function-docstring
        return GuiUtils.get_icon('icon.svg')

    def createWidget(self, parent):  # pylint: disable=missing-function-docstring
        page = OpenCageOptionsPage(parent)
        page.set_plugin(self.plugin)
        return page


class OpenCagePlugin:
    def __init__(self, iface):
        self.iface = iface

        settings = QgsSettings()
        self.geocoder = None
        self.filter = None
        self.api_key = settings.value('/plugins/opencage/api_key', '', str)

        self.options_factory = None

        # processing framework
        self.provider = OpenCageProvider()

    @staticmethod
    def tr(message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('OpenCageGeocoder', message)

    def initProcessing(self):
        """Create the Processing provider"""
        QgsApplication.processingRegistry().addProvider(self.provider)

    def initGui(self):
        self.initProcessing()
        self.register()

        self.options_factory = OpenCageOptionsFactory(self)
        self.options_factory.setTitle(self.tr('OpenCage'))
        self.iface.registerOptionsWidgetFactory(self.options_factory)
        self.check_api_key()

    def unload(self):
        self.unregister()
        QgsApplication.processingRegistry().removeProvider(self.provider)
        self.iface.unregisterOptionsWidgetFactory(self.options_factory)

    def unregister(self):
        if self.filter is not None:
            self.filter = None
            self.geocoder = None

    def register(self):
        if self.api_key:
            self.provider.set_config(self.api_key, "pt")

    def set_api_key(self, api_key):
        settings = QgsSettings()
        settings.setValue('/plugins/opencage/api_key', api_key)
        self.api_key = api_key
        self.unregister()
        self.register()
        self.check_api_key()


    def check_api_key(self):
        """
        Checks if an API key has been entered, and warns if not.
        """

        if not self.api_key:
            if QCoreApplication.instance().thread() == QThread.currentThread():
                # Main thread, safe to create a button
                bar = self.iface.messageBar()
                widget = bar.createMessage(self.tr('OpenCage'), 
                    self.tr("No API key entered, please configure"), bar)
                message_bar_widget=widget
                settings_button = QPushButton("Enter API Key…", 
                    pressed=self.open_settings)
                widget.layout().addWidget(settings_button)
                bar.pushWidget(widget, Qgis.Critical)

            return False

        return True  

    def open_settings(self, message_bar_widget=None):
        """
        Opens the settings dialog at the OpenCage page
        """

        # pdb.set_trace()
        # logging.debug('opensettings')

        self.iface.showOptionsDialog(self.iface.mainWindow(), currentPage='OpenCageOptions')
        if message_bar_widget:
            self.iface.messageBar().popWidget(message_bar_widget)
            message_bar_widget=None
