// SPDX-FileCopyrightText: 2025 Contributors to the CitrineOS Project
//
// SPDX-License-Identifier: Apache-2.0
'use client';
// @ts-nocheck

import type { LocationDto } from '@citrineos/base';
import type { MapMarkerData, MapProps } from '@lib/client/components/map/types';
import { ActionType, ResourceType } from '@lib/utils/access.types';
import { CanAccess } from '@refinedev/core';
import React, { useEffect, useMemo, useRef, useState } from 'react';

// Martinique center coordinates
const MARTINIQUE_CENTER = { lat: 14.6415, lng: -61.0242 };
const MARTINIQUE_ZOOM = 11;

let leafletCssLoaded = false;

function loadLeafletCss() {
  if (leafletCssLoaded || typeof document === 'undefined') return;
  leafletCssLoaded = true;

  // Remove any existing leaflet CSS
  document.querySelectorAll('link[href*="leaflet"]').forEach(el => el.remove());

  // Load Leaflet CSS from CDN
  const link = document.createElement('link');
  link.rel = 'stylesheet';
  link.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';
  link.integrity = 'sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=';
  link.crossOrigin = '';
  document.head.appendChild(link);
}

export const LocationMap: React.FC<MapProps> = ({
  locations = [],
  defaultCenter = MARTINIQUE_CENTER,
  zoom = MARTINIQUE_ZOOM,
  onMarkerClick,
  selectedMarkerId,
}) => {
  return (
    <CanAccess resource={ResourceType.LOCATIONS} action={ActionType.LIST}>
      <OsmMap
        locations={locations}
        defaultCenter={defaultCenter}
        zoom={zoom}
        onMarkerClick={onMarkerClick}
        selectedMarkerId={selectedMarkerId}
      />
    </CanAccess>
  );
};

const OsmMap: React.FC<MapProps> = ({
  locations = [],
  defaultCenter,
  zoom: initialZoom = MARTINIQUE_ZOOM,
  onMarkerClick,
  selectedMarkerId,
}) => {
  const mapContainerRef = useRef<HTMLDivElement>(null);
  const mapInstanceRef = useRef<any>(null);
  const markersRef = useRef<any>(null);
  const [isReady, setIsReady] = useState(false);
  const LRef = useRef<any>(null);

  // Load Leaflet CSS from CDN
  useEffect(() => {
    loadLeafletCss();
  }, []);

  // Compute markers from locations
  const stationMarkers: MapMarkerData[] = useMemo(() => {
    const markers: MapMarkerData[] = [];
    locations.forEach((loc) => {
      if (!loc.coordinates?.coordinates) return;
      const locLat = loc.coordinates.coordinates[1];
      const locLng = loc.coordinates.coordinates[0];

      (loc.chargingPool || []).forEach((station) => {
        const coords = station.coordinates || loc.coordinates;
        if (!coords?.coordinates) return;
        markers.push({
          position: { lat: coords.coordinates[1], lng: coords.coordinates[0] },
          identifier: station.ocppConnectionName || station.id,
          type: 'station' as const,
          locationId: loc.id!.toString(),
          status: station.isOnline ? 'online' as const : 'offline' as const,
          color: station.isOnline ? '#22c55e' : '#ef4444',
        });
      });

      // Also add location marker
      markers.push({
        position: { lat: locLat, lng: locLng },
        identifier: loc.id!.toString(),
        type: 'location' as const,
        status: 'online' as const,
        color: '#3b82f6',
      });
    });
    return markers;
  }, [locations]);

  // Initialize map
  useEffect(() => {
    if (!mapContainerRef.current || mapInstanceRef.current) return;
    let map: any;
    let markersGroup: any;

    import('leaflet').then((L) => {
      LRef.current = L;

      const center = defaultCenter || MARTINIQUE_CENTER;
      map = L.map(mapContainerRef.current!, {
        center: [center.lat, center.lng],
        zoom: initialZoom,
        zoomControl: true,
        attributionControl: true,
      });

      L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
        maxZoom: 19,
      }).addTo(map);

      markersGroup = L.layerGroup().addTo(map);
      mapInstanceRef.current = map;
      markersRef.current = markersGroup;
      setIsReady(true);
    });

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

  // Update markers
  useEffect(() => {
    if (!mapInstanceRef.current || !markersRef.current || !isReady || !LRef.current) return;

    const L = LRef.current;
    markersRef.current.clearLayers();

    const validMarkers = stationMarkers.filter(
      (m) => m.position.lat !== 0 && m.position.lng !== 0,
    );

    validMarkers.forEach((marker) => {
      const icon = L.divIcon({
        className: 'custom-marker-icon',
        html: `<div style="background:${marker.color};width:14px;height:14px;border-radius:50%;border:2px solid #fff;box-shadow:0 1px 3px rgba(0,0,0,0.4);"></div>`,
        iconSize: [14, 14],
        iconAnchor: [7, 7],
      });

      const m = L.marker([marker.position.lat, marker.position.lng], { icon });
      m.on('click', () => onMarkerClick?.(marker.identifier, marker.type));
      m.bindTooltip(marker.identifier, { direction: 'top', offset: [0, -10] });
      m.addTo(markersRef.current);
    });

    // Fit bounds to markers if we have valid ones
    if (validMarkers.length > 0) {
      const bounds = L.latLngBounds(
        validMarkers.map((m) => [m.position.lat, m.position.lng]),
      );
      mapInstanceRef.current.fitBounds(bounds, { padding: [30, 30], maxZoom: 15 });
    } else {
      // Fallback to Martinique
      mapInstanceRef.current.setView([MARTINIQUE_CENTER.lat, MARTINIQUE_CENTER.lng], MARTINIQUE_ZOOM);
    }
  }, [stationMarkers, isReady, onMarkerClick]);

  // Pan to selected
  useEffect(() => {
    if (!mapInstanceRef.current || !selectedMarkerId) return;
    const sel = stationMarkers.find((m) => m.identifier === selectedMarkerId);
    if (sel && sel.position.lat !== 0) {
      mapInstanceRef.current.panTo([sel.position.lat, sel.position.lng]);
    }
  }, [selectedMarkerId, stationMarkers]);

  return (
    <div
      style={{
        width: '100%',
        height: '100%',
        minHeight: '350px',
        borderRadius: '8px',
        overflow: 'hidden',
        position: 'relative',
      }}
    >
      <div
        ref={mapContainerRef}
        style={{
          width: '100%',
          height: '100%',
          minHeight: '350px',
        }}
      />
    </div>
  );
};
