"""Main plugin class: registers a toolbar button + menu item that toggles the
AIS Guardian dock panel (three tabs: Guardian controls, event log, AIS stream)."""
import os

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

# QAction moved from QtWidgets (Qt5) to QtGui (Qt6). Try Qt6 first, fall back.
try:
    from qgis.PyQt.QtGui import QAction
except ImportError:
    from qgis.PyQt.QtWidgets import QAction

from .source_dialog import StreamWidget
from .guardian_dock import GuardianDock
from .guardian_store import GuardianStore

# Usage/privacy notice shown once per session before the plugin opens. The user
# must accept ('I do') before any AIS/NMEA handling can start.
CONSENT_TEXT = (
    "AIS Watchkeeper is an open-source tool that handles AIS messages from "
    "ships, from multiple sources. It has advanced functions for portrayal, "
    "analysis and storage of those messages, the ship's information and "
    "voyages.\n\n"
    "You, the user of AIS Watchkeeper, understand that you are solely "
    "responsible for compliance with privacy legislation at the position where "
    "you use AIS Watchkeeper, in regard to receiving, handling, portrayal and "
    "storage of AIS messages."
)


def _right_dock_area():
    """Qt.RightDockWidgetArea, enum-safe across Qt5/Qt6."""
    try:
        return Qt.RightDockWidgetArea
    except AttributeError:
        return Qt.DockWidgetArea.RightDockWidgetArea


class AisNmeaSourcePlugin:
    def __init__(self, iface):
        """Store the QGIS interface; GUI objects are created later in initGui."""
        self.iface = iface
        self.action = None
        self.dock = None
        self.store = None
        self.menu = "&AIS Watchkeeper"
        self._consented = False       # usage notice accepted this session?

    def initGui(self):
        """QGIS entry point: register the toolbar button + menu item and make the
        bundled vessel SVGs resolvable."""
        self._register_svg_path()
        icon_path = os.path.join(os.path.dirname(__file__), "icon.png")
        icon = QIcon(icon_path) if os.path.exists(icon_path) else QIcon()
        self.action = QAction(icon, "AIS Watchkeeper", self.iface.mainWindow())
        self.action.setToolTip("Show/hide the AIS Guardian panel "
                               "(keeps running in the background)")
        self.action.triggered.connect(self.toggle_panel)
        self.iface.addToolBarIcon(self.action)
        self.iface.addPluginToMenu(self.menu, self.action)

    def _register_svg_path(self):
        """Add the bundled symbols/ folder to QGIS's SVG search paths so the
        vessel SVGs resolve by filename on any machine (append-only)."""
        try:
            from qgis.core import QgsSettings
            settings = QgsSettings()
            sym_dir = os.path.join(os.path.dirname(__file__), "symbols")
            key = "svg/searchPathsForSVG"
            raw = settings.value(key)
            if raw is None:
                paths = []
            elif isinstance(raw, str):
                paths = raw.split("|") if raw else []
            else:
                paths = list(raw)
            if sym_dir not in paths:
                paths.append(sym_dir)
                settings.setValue(key, paths)
        except Exception:  # nosec B110
            pass

    def unload(self):
        """QGIS exit point: stop background work and remove the dock + toolbar/
        menu entries."""
        if self.dock is not None:
            self.dock.shutdown()          # stop reader/scanner
            try:
                self.iface.removeDockWidget(self.dock)
            except Exception:  # nosec B110
                pass
            self.dock.deleteLater()
            self.dock = None
        if self.action is not None:
            self.iface.removeToolBarIcon(self.action)
            self.iface.removePluginMenu(self.menu, self.action)
            self.action = None

    def toggle_panel(self):
        """Show/hide the Guardian dock. The FIRST push builds the dock (which also
        populates the project layers) and shows it in one go; later pushes toggle
        its visibility. Previously the first push created the dock — added visible
        by addDockWidget — and then immediately toggled it back off, so it took a
        second push to actually see the panel."""
        if self.dock is None:
            if not self._ensure_consent():    # usage notice must be accepted first
                return                         # declined -> stay closed, no feed
            self._create_dock()
            self._set_dock_visible(True)      # first push: create AND show at once
            return
        # QgsDockWidget.isUserVisible reflects the toggled state; fall back to
        # plain visibility if running against a build without it.
        if hasattr(self.dock, "isUserVisible"):
            self._set_dock_visible(not self.dock.isUserVisible())
        else:
            self._set_dock_visible(not self.dock.isVisible())

    def _set_dock_visible(self, visible):
        """Show/hide the dock (QgsDockWidget.setUserVisible when available), and
        raise it to the front when shown."""
        if hasattr(self.dock, "setUserVisible"):
            self.dock.setUserVisible(visible)
        else:
            self.dock.setVisible(visible)
        if visible:
            try:
                self.dock.raise_()
            except Exception:  # nosec B110
                pass

    # ---- usage / privacy consent gate -----------------------------------
    def _ensure_consent(self):
        """Gate the plugin behind the usage/privacy notice. Returns True only if
        the user accepts ('I do'). Consent is per QGIS session: it is asked once,
        the first time the panel is opened. On decline the plugin stays closed and
        NO AIS/NMEA handling starts — the dock (which owns the stream reader) is
        never created — and the notice is shown again on the next icon press."""
        if self._consented:
            return True
        self._consented = bool(self._show_consent_notice())
        if not self._consented:
            try:
                self.iface.messageBar().pushInfo(
                    "AIS Watchkeeper",
                    "Usage notice declined — the plugin stays closed. Press the "
                    "toolbar icon and choose 'I do' to start.")
            except Exception:  # nosec B110
                pass
        return self._consented

    def _show_consent_notice(self):
        """Modal usage/privacy notice with 'I do' (accept) / 'Decline' (reject).
        Closing via the window frame counts as Decline. Returns True on accept."""
        from qgis.PyQt.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout,
                                         QLabel, QPushButton)
        dlg = QDialog(self.iface.mainWindow())
        dlg.setWindowTitle("AIS Watchkeeper — usage notice")
        dlg.setModal(True)
        v = QVBoxLayout(dlg)
        lbl = QLabel(CONSENT_TEXT)
        lbl.setWordWrap(True)
        lbl.setMinimumWidth(460)
        v.addWidget(lbl)
        v.addSpacing(6)
        row = QHBoxLayout()
        row.addStretch(1)
        decline_btn = QPushButton("Decline")
        accept_btn = QPushButton("I do")
        accept_btn.setDefault(True)
        decline_btn.clicked.connect(dlg.reject)
        accept_btn.clicked.connect(dlg.accept)
        row.addWidget(decline_btn)
        row.addWidget(accept_btn)
        v.addLayout(row)
        res = dlg.exec_() if hasattr(dlg, "exec_") else dlg.exec()
        return bool(res)                       # QDialog.Accepted == 1 (truthy)

    def _create_dock(self):
        """Build the persistent store, the stream widget and the Guardian dock,
        and add the dock to the right-hand area. The store is best-effort: the
        panel still works (minus the log) if it can't be opened."""
        # Persistent store (target groups, event log, coverage). Best-effort:
        # if it can't be opened the panel still works, just without the log.
        try:
            self.store = GuardianStore()
            self.store.ensure_with_safeguards()
        except Exception:
            self.store = None
        stream = StreamWidget(self.iface, self.iface.mainWindow())
        self.dock = GuardianDock(self.iface, stream, store=self.store,
                                 parent=self.iface.mainWindow())
        self.iface.addDockWidget(_right_dock_area(), self.dock)
