import { useEffect, useRef, useState } from "react";
import maplibregl from "maplibre-gl";
import { LAST_VIEW_KEY } from "./mapConfig";
import { getViewFromMap } from "./mapGeo";
import { clearAllMarkers, applyOcclusionForExpanded } from "./markerManager";

function getBaseStyle(theme) {
  const t = theme || "dark";
  let tiles;

  switch (t) {
    case "light":
      tiles = ["https://a.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png"];
      break;
    case "blue":
      tiles = ["https://a.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png"];
      break;
    case "dark":
    default:
      tiles = ["https://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png"];
      break;
  }

  return {
    version: 8,
    sources: {
      "carto-base": {
        type: "raster",
        tiles,
        tileSize: 256,
        attribution: "© OpenStreetMap contributors © CARTO",
      },
    },
    layers: [{ id: "carto-base-layer", type: "raster", source: "carto-base" }],
  };
}

export function useMapCore(theme) {
  const containerRef = useRef(null);
  const mapRef = useRef(null);

  const markersRef = useRef([]);
  const expandedElRef = useRef(null);

  const [viewParams, setViewParams] = useState({ center: null, radiusKm: 750 });
  const [hasLastView, setHasLastView] = useState(false);

  function closeExpandedIfAny() {
    const el = expandedElRef.current;
    if (!el) return;

    // overlay style
    if (el.__swClose) {
      try {
        el.__swClose();
      } catch {}
      expandedElRef.current = null;
      return;
    }

    // legacy marker-expanded style
    if (el.__renderCompact) {
      try {
        el.__renderCompact();
      } catch {}
    }
    expandedElRef.current = null;
  }

  useEffect(() => {
    if (!containerRef.current) return;

    const map = new maplibregl.Map({
      container: containerRef.current,
      style: getBaseStyle(theme || "dark"),
      center: [-95, 40],
      zoom: 3.5,
      pitch: 0,
      bearing: 0,
      antialias: true,
    });

    let hadLastView = false;
    try {
      const raw = localStorage.getItem(LAST_VIEW_KEY);
      if (raw) {
        const v = JSON.parse(raw);
        if (typeof v.lat === "number" && typeof v.lon === "number" && typeof v.zoom === "number") {
          map.setCenter([v.lon, v.lat]);
          map.setZoom(v.zoom);
          hadLastView = true;
        }
      }
    } catch {}
    setHasLastView(hadLastView);

    map.addControl(new maplibregl.NavigationControl(), "top-right");
    mapRef.current = map;

    // ✅ Ensure viewParams is set immediately so posts load without moving the map
    try { setViewParams(getViewFromMap(map)); } catch {}

    const reOcclude = () => {
      const el = expandedElRef.current;
      if (el) applyOcclusionForExpanded(markersRef, el);
    };
    map.on("move", reOcclude);
    map.on("zoom", reOcclude);

    // ignore close while auto actions are happening
    map.on("click", () => { closeExpandedIfAny(); });

    map.on("dragstart", () => { closeExpandedIfAny(); });

    map.on("load", () => setViewParams(getViewFromMap(map)));

    map.on("moveend", () => {
      const vp = getViewFromMap(map);
      setViewParams(vp);
      try {
        const center = vp.center;
        localStorage.setItem(
          LAST_VIEW_KEY,
          JSON.stringify({ lat: center[1], lon: center[0], zoom: map.getZoom() })
        );
      } catch {}
    });

    return () => {
      clearAllMarkers(markersRef, expandedElRef);
      map.remove();
      mapRef.current = null;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    const map = mapRef.current;
    if (!map) return;
    map.setStyle(getBaseStyle(theme || "dark"));
  }, [theme]);

  return { containerRef, mapRef, markersRef, expandedElRef, viewParams, hasLastView };
}
