from pathlib import Path

from qgis.PyQt.QtCore import QSettings, QTimer
from qgis.PyQt.QtGui import QIcon
from qgis.PyQt.QtWidgets import QAction
from qgis.core import Qgis, QgsMessageLog

from .living_legend_dock import LivingLegendWidget


class LivingLegendPlugin:

    def __init__(self, iface):
        self.iface = iface
        self.action = None
        self.toolbar = None
        self.widget = None
        self.settings = QSettings("LivingLegend", "LivingLegend")

    def log_ignored_exception(self, message, exception):
        QgsMessageLog.logMessage(
            f"{message}: {exception}",
            "Living Legend",
            Qgis.MessageLevel.Info
        )

    def initGui(self):

        icon_path = str(
            Path(__file__).parent /
            "icons" /
            "icon.png"
        )

        self.action = QAction(
            QIcon(icon_path),
            "Living Legend",
            self.iface.mainWindow()
        )

        self.action.setCheckable(True)
        self.action.triggered.connect(self.toggle_widget)

        self.toolbar = self.iface.addToolBar("Living Legend")
        self.toolbar.setObjectName("LivingLegendToolbar")
        self.toolbar.addAction(self.action)

        self.iface.addPluginToMenu(
            "Living Legend",
            self.action
        )

        QTimer.singleShot(500, self.restore_visibility_from_settings)

    def unload(self):
        if self.widget:
            self.widget.close()

        if self.action:
            self.action.setChecked(False)

        if self.toolbar:
            try:
                self.toolbar.removeAction(self.action)
                self.toolbar.deleteLater()
            except Exception as exception:
                self.log_ignored_exception(
                    "Could not remove Living Legend toolbar",
                    exception
                )

            self.toolbar = None

        self.iface.removePluginMenu(
            "Living Legend",
            self.action
        )

    def read_bool_setting(self, key, default_value):
        value = self.settings.value(key, default_value)

        if isinstance(value, bool):
            return value

        if isinstance(value, str):
            return value.lower() in ["true", "1", "yes", "on"]

        return bool(value)

    def set_legend_active_setting(self, active):
        self.settings.setValue("legend_active", bool(active))

    def restore_visibility_from_settings(self):
        should_restore = self.read_bool_setting("legend_active", False)

        if not should_restore:
            if self.action:
                self.action.setChecked(False)
            return

        # During QGIS startup the map canvas viewport can still be too small.
        # If we create/show the living legend too early, its saved position
        # may be clamped to the top-left corner.
        try:
            viewport = self.iface.mapCanvas().viewport()
            viewport_width = viewport.width()
            viewport_height = viewport.height()
        except Exception:
            viewport_width = 0
            viewport_height = 0

        if viewport_width < 100 or viewport_height < 100:
            QTimer.singleShot(300, self.restore_visibility_from_settings)
            return

        if self.widget is None:
            self.widget = LivingLegendWidget(self.iface)

        self.widget.updateLegend()
        self.widget.show()
        self.widget.raise_()

        if self.action:
            self.action.setChecked(True)

    def toggle_widget(self, checked=None):
        if self.widget is None:
            self.widget = LivingLegendWidget(self.iface)

        if self.widget.isVisible():
            self.widget.hide()

            self.set_legend_active_setting(False)

            if self.action:
                self.action.setChecked(False)

        else:
            self.widget.updateLegend()
            self.widget.show()
            self.widget.raise_()

            self.set_legend_active_setting(True)

            if self.action:
                self.action.setChecked(True)