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;

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

    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: 45, // ACTIVATION DU TILT 3D PAR DÉFAUT (globe incliné)
      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);
          // Restore pitch from storage, default to 45 if not saved
          map.setPitch(typeof v.pitch === "number" ? v.pitch : 45);
          // Restore bearing (rotation) if saved
          if (typeof v.bearing === "number") {
            map.setBearing(v.bearing);
          }
          hadLastView = true;
        }
      }
    } catch {}
    setHasLastView(hadLastView);

    map.addControl(new maplibregl.NavigationControl({ showCompass: true, showZoom: true }), "top-right");
    mapRef.current = map;

    try { setViewParams(getViewFromMap(map)); } catch {}
    const initialTimer = setTimeout(() => {
      try { setViewParams(getViewFromMap(map)); } catch {}
    }, 300);

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

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

    map.on("load", () => {
      setViewParams(getViewFromMap(map));
      // Don't force pitch on load - let it stay as configured
      try {
        map.__swForceFetchAt = Date.now();
        map.fire("moveend");
        setTimeout(() => {
          try {
            map.__swForceFetchAt = Date.now();
            map.fire("moveend");
          } catch {}
        }, 650);
      } catch {}

      // Weather/special pins will be handled via /api/map-pins endpoint (TODO)
    });

    map.on("moveend", () => {
      const vp = getViewFromMap(map);
      setViewParams(vp);
      try {
        // Use map.getCenter() directly for accurate geographic center
        // (bounds.getCenter() can be offset when pitch is applied)
        const center = map.getCenter();
        localStorage.setItem(
          LAST_VIEW_KEY,
          JSON.stringify({
            lat: center.lat,
            lon: center.lng,
            zoom: map.getZoom(),
            pitch: map.getPitch(),
            bearing: map.getBearing()
          })
        );
      } catch {}
    });

    return () => {
      clearTimeout(initialTimer);
      clearAllMarkers(markersRef, expandedElRef);
      map.remove();
      mapRef.current = null;
    };
  }, []);

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

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