/* Mapa Google — TECOS ELITE */

const DEFAULT_MAP_LAT = 20.659698;
const DEFAULT_MAP_LNG = -103.349609;
/** Pin en mapa: logo + pin rojo de Google debajo */
const MARKER_ICON_W = 56;
const MARKER_ICON_H = 56;
/** Pin rojo debajo del logo (bloque único con rebote) */
const GOOGLE_PIN_HEIGHT = 40;
const MARKER_STACK_H = MARKER_ICON_H + GOOGLE_PIN_HEIGHT;

const TECOS_MAP_STYLES = [
  { elementType: 'geometry', stylers: [{ color: '#0b1528' }] },
  { elementType: 'labels.text.fill', stylers: [{ color: '#7eb8ff' }] },
  { elementType: 'labels.text.stroke', stylers: [{ color: '#061018' }] },
  { featureType: 'road', elementType: 'geometry', stylers: [{ color: '#1a3050' }] },
  { featureType: 'road', elementType: 'geometry.stroke', stylers: [{ color: '#2a6cff' }] },
  { featureType: 'road.highway', elementType: 'geometry', stylers: [{ color: '#1e4a8a' }] },
  { featureType: 'water', elementType: 'geometry', stylers: [{ color: '#051525' }] },
  { featureType: 'water', elementType: 'labels.text.fill', stylers: [{ color: '#3d8bfd' }] },
  { featureType: 'poi', elementType: 'geometry', stylers: [{ color: '#122038' }] },
  { featureType: 'poi.park', elementType: 'geometry', stylers: [{ color: '#0f2840' }] },
  { featureType: 'transit', elementType: 'geometry', stylers: [{ color: '#152a45' }] },
  { featureType: 'administrative', elementType: 'geometry.stroke', stylers: [{ color: '#00b4ff', weight: 0.6 }] },
];

function getGoogleMapsApiKey () {
  return window.SUPABASE_CONFIG?.googleMapsApiKey
    || window.GOOGLE_MAPS_API_KEY
    || '';
}

function loadGoogleMapsApi () {
  const key = getGoogleMapsApiKey();
  if (!key) return Promise.reject(new Error('Sin API key de Google Maps'));
  if (window.google?.maps) return Promise.resolve(window.google.maps);

  return new Promise((resolve, reject) => {
    const existing = document.getElementById('tecos-google-maps-js');
    if (existing) {
      const wait = () => {
        if (window.google?.maps) resolve(window.google.maps);
        else setTimeout(wait, 80);
      };
      wait();
      return;
    }
    const script = document.createElement('script');
    script.id = 'tecos-google-maps-js';
    script.src = `https://maps.googleapis.com/maps/api/js?key=${encodeURIComponent(key)}&v=weekly`;
    script.async = true;
    script.defer = true;
    script.onload = () => (window.google?.maps ? resolve(window.google.maps) : reject(new Error('Google Maps no cargó')));
    script.onerror = () => reject(new Error('No se pudo cargar Google Maps'));
    document.head.appendChild(script);
  });
}

function formatLocationAddress (loc) {
  if (!loc) return '';
  const cityLine = [loc.address_city, loc.address_state, loc.address_postal].filter(Boolean).join(', ');
  return [loc.address_street, cityLine, loc.address_country].filter(Boolean).join('\n');
}

function buildGoogleMapsOpenUrl (loc) {
  if (!loc) return 'https://www.google.com/maps';
  if (loc.google_maps_url?.trim()) return loc.google_maps_url.trim();
  const lat = Number(loc.latitude);
  const lng = Number(loc.longitude);
  if (!Number.isNaN(lat) && !Number.isNaN(lng)) {
    return `https://www.google.com/maps/search/?api=1&query=${lat},${lng}`;
  }
  const q = formatLocationAddress(loc).replace(/\n/g, ', ');
  return `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(q)}`;
}

function getLocationMarkerUrl (loc, cacheKey) {
  if (!loc?.map_marker_image_path) return null;
  const base = typeof getStoragePublicUrl === 'function'
    ? getStoragePublicUrl('public-assets', loc.map_marker_image_path)
    : null;
  if (!base) return null;
  const v = cacheKey ?? loc.map_marker_image_path;
  return `${base}${base.includes('?') ? '&' : '?'}v=${encodeURIComponent(String(v))}`;
}

/** Resplandor neón suave (sin marco); sigue la silueta de la imagen */
function getMarkerNeonFilter () {
  return [
    'drop-shadow(0 0 4px rgba(255,255,255,0.38))',
    'drop-shadow(0 0 9px rgba(126,184,255,0.42))',
    'drop-shadow(0 0 14px rgba(42,108,255,0.32))',
    'drop-shadow(0 2px 5px rgba(0,0,0,0.28))',
  ].join(' ');
}

function bindMapOverlayRedraw (map, overlay) {
  if (!map || !overlay) return () => {};
  const redraw = () => { if (typeof overlay.draw === 'function') overlay.draw(); };
  const events = ['bounds_changed', 'center_changed', 'zoom_changed', 'drag', 'dragend', 'idle', 'resize'];
  const listeners = events.map((name) => map.addListener(name, redraw));
  return () => listeners.forEach((l) => l.remove());
}

const GOOGLE_PIN_SVG = '<svg class="tecos-google-pin-svg" width="26" height="36" viewBox="0 0 26 36" aria-hidden="true" style="display:block;margin-top:-2px"><path fill="#EA4335" stroke="#C5221F" stroke-width="0.6" d="M13 0C5.82 0 0 5.82 0 13c0 9.7 13 22.65 13 22.65S26 22.7 26 13C26 5.82 20.18 0 13 0z"/><circle fill="#6B2C0F" cx="13" cy="12.5" r="4.5"/></svg>';

function createMapNeonMarkerOverlay (maps, map, position, markerUrl) {
  const neonFilter = getMarkerNeonFilter();
  class TecosNeonMarkerOverlay extends maps.OverlayView {
    constructor (pos, url) {
      super();
      this.pos = pos;
      this.url = url;
      this.div = null;
      this._unbindRedraw = null;
    }

    onAdd () {
      const wrap = document.createElement('div');
      wrap.className = 'tecos-map-marker-pin tecos-map-marker-bounce';
      wrap.style.cssText = [
        'position:absolute',
        'pointer-events:none',
        `width:${MARKER_ICON_W}px`,
        'display:flex',
        'flex-direction:column',
        'align-items:center',
      ].join(';');
      const img = document.createElement('img');
      img.src = this.url;
      img.alt = '';
      img.className = 'tecos-map-marker-neon';
      img.style.cssText = [
        `width:${MARKER_ICON_W}px`,
        `height:${MARKER_ICON_H}px`,
        'object-fit:contain',
        'display:block',
        `filter:${neonFilter}`,
      ].join(';');
      wrap.appendChild(img);
      const pinWrap = document.createElement('div');
      pinWrap.innerHTML = GOOGLE_PIN_SVG;
      wrap.appendChild(pinWrap);
      this.div = wrap;
      const pane = this.getPanes().floatPane || this.getPanes().overlayMouseTarget;
      pane.appendChild(wrap);
      const m = this.getMap();
      if (this._unbindRedraw) this._unbindRedraw();
      this._unbindRedraw = bindMapOverlayRedraw(m, this);
    }

    draw () {
      if (!this.div) return;
      const proj = this.getProjection();
      if (!proj) return;
      const pt = proj.fromLatLngToDivPixel(this.pos);
      if (!pt) return;
      this.div.style.left = `${pt.x - MARKER_ICON_W / 2}px`;
      this.div.style.top = `${pt.y - MARKER_STACK_H}px`;
    }

    setPosition (pos) {
      this.pos = pos;
      this.draw();
    }

    onRemove () {
      if (this._unbindRedraw) {
        this._unbindRedraw();
        this._unbindRedraw = null;
      }
      if (this.div?.parentNode) this.div.parentNode.removeChild(this.div);
      this.div = null;
    }
  }
  const overlay = new TecosNeonMarkerOverlay(position, markerUrl);
  overlay.setMap(map);
  return overlay;
}

function loadLeaflet () {
  if (window.L) return Promise.resolve(window.L);
  return new Promise((resolve, reject) => {
    if (!document.getElementById('tecos-leaflet-css')) {
      const link = document.createElement('link');
      link.id = 'tecos-leaflet-css';
      link.rel = 'stylesheet';
      link.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';
      document.head.appendChild(link);
    }
    const existing = document.getElementById('tecos-leaflet-js');
    if (existing) {
      const wait = () => (window.L ? resolve(window.L) : setTimeout(wait, 80));
      wait();
      return;
    }
    const script = document.createElement('script');
    script.id = 'tecos-leaflet-js';
    script.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js';
    script.async = true;
    script.onload = () => (window.L ? resolve(window.L) : reject(new Error('Leaflet no cargó')));
    script.onerror = () => reject(new Error('No se pudo cargar Leaflet'));
    document.head.appendChild(script);
  });
}

function buildLeafletNeonIcon (L, markerUrl) {
  const filter = getMarkerNeonFilter();
  const safeUrl = markerUrl.replace(/"/g, '&quot;');
  const stackH = MARKER_ICON_H + GOOGLE_PIN_HEIGHT;
  return L.divIcon({
    className: 'tecos-leaflet-marker-wrap',
    html: [
      `<div class="tecos-leaflet-marker-stack tecos-map-marker-bounce" style="display:flex;flex-direction:column;align-items:center;width:${MARKER_ICON_W}px">`,
      `<img src="${safeUrl}" alt="" class="tecos-map-marker-neon" style="width:${MARKER_ICON_W}px;height:${MARKER_ICON_H}px;object-fit:contain;display:block;filter:${filter}" />`,
      GOOGLE_PIN_SVG,
      '</div>',
    ].join(''),
    iconSize: [MARKER_ICON_W, stackH],
    iconAnchor: [MARKER_ICON_W / 2, stackH],
  });
}

const MapFrame = ({ theme, children, height = 420 }) => (
  <div style={{
    position: 'relative',
    borderRadius: 12,
    overflow: 'hidden',
    height,
    border: `1px solid ${theme.border}`,
    background: theme.bgInput,
  }}>
    {children}
  </div>
);

/** google = Maps JS · leaflet = pin fijo a coordenadas sin API · embed = iframe simple */
const AcademyLocationMap = ({ theme, location, height = 420, showFallbackPin = true }) => {
  const mapRef = React.useRef(null);
  const mapInstanceRef = React.useRef(null);
  const googlePinRef = React.useRef(null);
  const logoOverlayRef = React.useRef(null);
  const leafletMapRef = React.useRef(null);
  const leafletMarkerRef = React.useRef(null);
  const [mapError, setMapError] = React.useState('');
  const hasGoogleKey = !!getGoogleMapsApiKey();
  const [mapEngine, setMapEngine] = React.useState(
    () => (hasGoogleKey ? 'google' : (getLocationMarkerUrl(location) ? 'leaflet' : 'embed')),
  );

  const lat = Number(location?.latitude) || DEFAULT_MAP_LAT;
  const lng = Number(location?.longitude) || DEFAULT_MAP_LNG;
  const zoom = Number(location?.map_zoom) || 16;
  const markerUrl = getLocationMarkerUrl(location);

  React.useEffect(() => {
    if (!mapRef.current) return undefined;

    let cancelled = false;

    const initGoogle = () => {
      setMapEngine('google');
      setMapError('');
      return loadGoogleMapsApi().then((maps) => {
        if (cancelled || !mapRef.current) return;
        const center = { lat, lng };
        if (!mapInstanceRef.current) {
          mapInstanceRef.current = new maps.Map(mapRef.current, {
            center,
            zoom,
            styles: TECOS_MAP_STYLES,
            disableDefaultUI: false,
            zoomControl: true,
            mapTypeControl: false,
            streetViewControl: false,
            fullscreenControl: true,
          });
        } else {
          mapInstanceRef.current.setCenter(center);
          mapInstanceRef.current.setZoom(zoom);
        }

        if (googlePinRef.current) {
          googlePinRef.current.setMap(null);
          googlePinRef.current = null;
        }
        if (logoOverlayRef.current?.setMap) {
          logoOverlayRef.current.setMap(null);
          logoOverlayRef.current = null;
        }

        if (markerUrl) {
          logoOverlayRef.current = createMapNeonMarkerOverlay(
            maps,
            mapInstanceRef.current,
            new maps.LatLng(lat, lng),
            markerUrl,
          );
        } else if (showFallbackPin) {
          googlePinRef.current = new maps.Marker({
            map: mapInstanceRef.current,
            position: center,
            title: location?.venue_name || 'TECOS ELITE',
          });
        }
      });
    };

    const initLeaflet = () => {
      setMapEngine('leaflet');
      setMapError('');
      return loadLeaflet().then((L) => {
        if (cancelled || !mapRef.current) return;
        if (mapInstanceRef.current && mapRef.current) {
          mapRef.current.replaceChildren();
          mapInstanceRef.current = null;
        }
        if (googlePinRef.current) {
          googlePinRef.current.setMap(null);
          googlePinRef.current = null;
        }
        if (logoOverlayRef.current?.setMap) {
          logoOverlayRef.current.setMap(null);
          logoOverlayRef.current = null;
        }
        if (!leafletMapRef.current) {
          leafletMapRef.current = L.map(mapRef.current, { zoomControl: true }).setView([lat, lng], zoom);
          L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '&copy; OpenStreetMap',
            maxZoom: 19,
          }).addTo(leafletMapRef.current);
        } else {
          leafletMapRef.current.setView([lat, lng], zoom);
        }
        if (leafletMarkerRef.current) {
          leafletMarkerRef.current.remove();
          leafletMarkerRef.current = null;
        }
        if (markerUrl) {
          leafletMarkerRef.current = L.marker([lat, lng], {
            icon: buildLeafletNeonIcon(L, markerUrl),
            interactive: false,
          }).addTo(leafletMapRef.current);
        }
        setTimeout(() => leafletMapRef.current?.invalidateSize(), 120);
      });
    };

    const run = () => {
      if (hasGoogleKey) {
        return initGoogle().catch((e) => {
          console.warn('[Tecos] Google Maps', e);
          if (cancelled) return;
          if (markerUrl) return initLeaflet();
          setMapEngine('embed');
          setMapError('');
          return undefined;
        });
      }
      if (markerUrl) return initLeaflet();
      setMapEngine('embed');
      return undefined;
    };

    run().catch((e) => {
      console.warn('[Tecos] Mapa', e);
      if (!cancelled) {
        setMapEngine('embed');
        setMapError('No se pudo cargar el mapa interactivo.');
      }
    });

    return () => {
      cancelled = true;
      if (googlePinRef.current) {
        googlePinRef.current.setMap(null);
        googlePinRef.current = null;
      }
      if (logoOverlayRef.current?.setMap) {
        logoOverlayRef.current.setMap(null);
        logoOverlayRef.current = null;
      }
      if (leafletMarkerRef.current) {
        leafletMarkerRef.current.remove();
        leafletMarkerRef.current = null;
      }
      if (leafletMapRef.current) {
        leafletMapRef.current.remove();
        leafletMapRef.current = null;
      }
      if (mapRef.current) mapRef.current.replaceChildren();
      mapInstanceRef.current = null;
    };
  }, [lat, lng, zoom, markerUrl, location?.venue_name, showFallbackPin, hasGoogleKey]);

  const embedSrc = `https://www.google.com/maps?q=${lat},${lng}&z=${zoom}&output=embed`;

  if (mapEngine === 'embed') {
    return (
      <MapFrame theme={theme} height={height}>
        <iframe
          title="Mapa TECOS ELITE"
          src={embedSrc}
          style={{ border: 0, width: '100%', height: '100%', display: 'block', filter: 'saturate(1.15) contrast(1.05) hue-rotate(-8deg)' }}
          loading="lazy"
          referrerPolicy="no-referrer-when-downgrade"
        />
        {mapError && (
          <div style={{ position: 'absolute', bottom: 8, left: 8, right: 8, fontSize: 11, color: theme.textMute, fontFamily: 'Inter, sans-serif' }}>
            {mapError}
          </div>
        )}
      </MapFrame>
    );
  }

  return (
    <MapFrame theme={theme} height={height}>
      <div ref={mapRef} style={{ width: '100%', height: '100%', zIndex: 0 }} />
      {mapError && mapEngine === 'leaflet' && (
        <div style={{ position: 'absolute', bottom: 8, left: 8, right: 8, fontSize: 11, color: theme.textMute, fontFamily: 'Inter, sans-serif', zIndex: 2 }}>
          {mapError}
        </div>
      )}
    </MapFrame>
  );
};

Object.assign(window, {
  AcademyLocationMap,
  MapFrame,
  NeonMapFrame: MapFrame,
  loadGoogleMapsApi,
  getGoogleMapsApiKey,
  formatLocationAddress,
  buildGoogleMapsOpenUrl,
  getLocationMarkerUrl,
  DEFAULT_MAP_LAT,
  DEFAULT_MAP_LNG,
});
