# -*- coding: utf-8 -*-
"""RUPP GEE LULC Toolkit - main plugin class."""

import os

from qgis.PyQt.QtCore import Qt
from qgis.PyQt.QtGui import QIcon
from qgis.PyQt.QtWidgets import QAction

ICON_DIR = os.path.join(os.path.dirname(__file__), "icons")


def _icon(name):
    path = os.path.join(ICON_DIR, name)
    return QIcon(path) if os.path.exists(path) else QIcon()


def _toolbox_icon():
    """The icon QGIS uses for the Processing Toolbox.

    Pulled from the active QGIS theme so it matches whatever icon set the
    user has (default, Night Mapping, ...). QGIS's own ProcessingPlugin
    uses processingAlgorithm.svg for the Toolbox action; the alternatives
    are tried in case a theme ships a different name. Falls back to the
    plugin icon if none resolve.
    """
    try:
        from qgis.core import QgsApplication
        for nm in ("/processingAlgorithm.svg",
                   "/processingModel.svg",
                   "/providerQgis.svg"):
            ic = QgsApplication.getThemeIcon(nm)
            if ic is not None and not ic.isNull():
                return ic
    except (ImportError, AttributeError, TypeError):  # QGIS API
        pass
    return _icon("icon.png")


class RuppGeeLulcPlugin:
    def __init__(self, iface):
        self.iface = iface
        self.actions = []
        self.toolbar = None
        self.menu = "&GEE LULC Toolkit"
        self.loader_dlg = None
        self.sampling_dlg = None
        self.label_dock = None
        self.classify_dlg = None
        self._setup_win = None
        # shared session state (GEE objects live only in this session)
        self.state = {"stack": None, "aoi": None, "aoi_name": "",
                      "scale": None, "band_names": [], "classified": None}

    # ------------------------------------------------------------ setup
    def _add_action(self, text, callback, icon_name=None, on_toolbar=True,
                    icon=None):
        a = QAction(icon if icon is not None
                    else (_icon(icon_name) if icon_name else QIcon()),
                    text, self.iface.mainWindow())
        a.setToolTip(text.replace("&&", "&"))
        a.triggered.connect(callback)
        self.iface.addPluginToMenu(self.menu, a)
        if on_toolbar and self.toolbar is not None:
            self.toolbar.addAction(a)
        self.actions.append(a)

    def initGui(self):
        self.toolbar = self.iface.addToolBar("GEE LULC Toolkit")
        self.toolbar.setObjectName("GeeLulcToolbar")
        self._add_action("GEE LULC Toolkit",
                         self.show_combined, "icon.png")
        # Menu only: setup is a once-per-machine task, so it does not need
        # to occupy toolbar space. Uses the same icon QGIS gives the
        # Processing Toolbox.
        self._add_action("Setup: connect to Earth Engine",
                         self.show_setup, on_toolbar=False,
                         icon=_toolbox_icon())

    def show_setup(self):
        """Open the Earth Engine setup panel as its own window."""
        from .dialogs.setup_dialog import SetupWindow
        if getattr(self, "_setup_win", None) is None:
            self._setup_win = SetupWindow(self.iface,
                                          self.iface.mainWindow())
        self._setup_win.show()
        self._setup_win.raise_()
        self._setup_win.activateWindow()
        try:
            self._setup_win.panel.refresh()
        except (AttributeError, RuntimeError):  # Qt/QGIS API compatibility
            pass

    def unload(self):
        for a in self.actions:
            self.iface.removePluginMenu(self.menu, a)
        self.actions = []
        if self.toolbar is not None:
            del self.toolbar
            self.toolbar = None
        if self.label_dock:
            self.iface.removeDockWidget(self.label_dock)
            self.label_dock = None
        # These windows have no parent, so Qt will not destroy them with the
        # main window - close them explicitly or they outlive the plugin.
        for attr in ("_setup_win", "_combined"):
            win = getattr(self, attr, None)
            if win is not None:
                try:
                    win.close()
                    win.deleteLater()
                except RuntimeError:        # already destroyed by Qt
                    pass
                setattr(self, attr, None)

    # ------------------------------------------------------------ tools
    def show_combined(self):
        from .combined_dialog import CombinedLulcDialog
        if getattr(self, "_combined", None) is None:
            # parent=None on purpose: an owned window gets no taskbar button
            # on Windows. The strong reference on self keeps it alive.
            self._combined = CombinedLulcDialog(self.iface, None)
        w = self._combined
        w.show()
        # bring it back if the user minimised it earlier
        try:
            st = w.windowState()
            if st & Qt.WindowState.WindowMinimized:
                w.setWindowState((st & ~Qt.WindowState.WindowMinimized)
                                 | Qt.WindowState.WindowActive)
        except (AttributeError, TypeError):  # Qt API compatibility
            pass
        w.raise_()
        w.activateWindow()

    def show_loader(self):
        from .dialogs.loader_dialog import LoaderDialog
        if self.loader_dlg is None:
            self.loader_dlg = LoaderDialog(
                self.iface, self.state, self.iface.mainWindow())
        self.loader_dlg.show()
        self.loader_dlg.raise_()

    def show_sampling(self):
        from .dialogs.sampling_dialog import SamplingDialog
        if self.sampling_dlg is None:
            self.sampling_dlg = SamplingDialog(
                self.iface, self.iface.mainWindow(), self.state)
        self.sampling_dlg.show()
        self.sampling_dlg.raise_()

    def show_labeling(self):
        from .dialogs.labeling_dock import LabelingDock
        if self.label_dock is None:
            self.label_dock = LabelingDock(
                self.iface, self.iface.mainWindow())
            self.label_dock.state = self.state      # share the GEE stack
            self.iface.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, self.label_dock)
        self.label_dock.show()
        self.label_dock.load_layer()

    def show_classify(self):
        from .dialogs.classify_dialog import ClassifyDialog
        if self.classify_dlg is None:
            self.classify_dlg = ClassifyDialog(
                self.iface, self.state, self.iface.mainWindow())
        self.classify_dlg.show()
        self.classify_dlg.raise_()

    def show_signatures(self):
        from .dialogs.signatures_dialog import SignaturesDialog
        if getattr(self, "sig_dlg", None) is None:
            self.sig_dlg = SignaturesDialog(
                self.iface, self.state, self.iface.mainWindow())
        self.sig_dlg.show()
        self.sig_dlg.raise_()

    def make_layout(self):
        import traceback
        from qgis.PyQt.QtWidgets import QMessageBox
        try:
            from .lulc_adminmap import run_lulc_adminmap
            layout = run_lulc_adminmap(self.iface, self.state)
            if layout is not None:
                self.iface.openLayoutDesigner(layout)
        except RuntimeError as e:
            # boundaries data missing -> offer the simple layout instead
            ans = QMessageBox.question(
                self.iface.mainWindow(), "LULC Map Layout",
                str(e) + "\n\nBuild a simple layout instead?",
                QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
            if ans == QMessageBox.StandardButton.Yes:
                from .layout_gen import make_layout
                make_layout(self.iface, self.state)
        except Exception as e:
            QMessageBox.critical(
                self.iface.mainWindow(), "LULC Map Layout",
                "{}\n\n{}".format(e, traceback.format_exc()))
