"""Startup map UX: OpenStreetMap basemap, layer ordering, pan-to-first-contact.

All QGIS access is lazy + best-effort so the module imports under py_compile and
a failure (e.g. offline, no basemap) never breaks the plugin.
"""
OSM_NAME = "OpenStreetMap"
OSM_URI = ("type=xyz&url=https://tile.openstreetmap.org/"
           "%7Bz%7D/%7Bx%7D/%7By%7D.png&zmax=19&zmin=0")


def ensure_osm_basemap():
    """Add an OSM XYZ basemap if one isn't already present, placed at the bottom
    of the layer order. Idempotent (matches by name or source)."""
    try:
        from qgis.core import QgsProject, QgsRasterLayer
    except Exception:
        return None
    proj = QgsProject.instance()
    for lyr in proj.mapLayers().values():
        try:
            src = lyr.source() or ""
        except Exception:
            src = ""
        if lyr.name() == OSM_NAME or "tile.openstreetmap.org" in src:
            return lyr                       # already there — leave it
    layer = QgsRasterLayer(OSM_URI, OSM_NAME, "wms")
    if not layer.isValid():
        return None
    proj.addMapLayer(layer, False)           # add without auto-placing in the tree
    try:
        root = proj.layerTreeRoot()
        root.insertLayer(len(root.children()), layer)   # bottom of the order
    except Exception:
        proj.addMapLayer(layer)
    return layer


def raise_layers_above_basemap(names):
    """Best-effort: keep the named plugin layers above the OSM basemap."""
    try:
        from qgis.core import QgsProject
        proj = QgsProject.instance()
        root = proj.layerTreeRoot()
        for nm in names:
            for lyr in proj.mapLayersByName(nm):
                node = root.findLayer(lyr.id())
                if node is not None and root.children() and \
                        root.children().index(node) > 0:
                    clone = node.clone()
                    root.insertChildNode(0, clone)
                    node.parent().removeChildNode(node)
    except Exception:  # nosec B110
        pass


def pin_project_crs(authid="EPSG:3857"):
    """Explicitly set (and thereby lock) the project CRS so that adding the
    4326 vessel layer doesn't flip the project/canvas CRS away from the web-
    mercator basemap. Returns True on success."""
    try:
        from qgis.core import QgsProject, QgsCoordinateReferenceSystem
        crs = QgsCoordinateReferenceSystem(authid)
        if crs.isValid():
            QgsProject.instance().setCrs(crs)
            return True
    except Exception:  # nosec B110
        pass
    return False


def pan_to(iface, lon, lat, scale=50000):
    """Centre the canvas on a 4326 lon/lat (reprojected to the canvas CRS) and
    set the map scale. Returns True on success."""
    try:
        from qgis.core import (QgsPointXY, QgsCoordinateReferenceSystem,
                               QgsCoordinateTransform, QgsProject)
        canvas = iface.mapCanvas()
        dst = canvas.mapSettings().destinationCrs()
        src = QgsCoordinateReferenceSystem("EPSG:4326")
        pt = QgsPointXY(lon, lat)
        if dst.isValid() and dst.authid() != "EPSG:4326":
            tr = QgsCoordinateTransform(src, dst, QgsProject.instance())
            pt = tr.transform(pt)
        canvas.setCenter(pt)
        canvas.zoomScale(scale)
        canvas.refresh()
        return True
    except Exception:
        return False
