import React, { useMemo, useEffect, useRef } from "react";
import { Loader } from "@googlemaps/js-api-loader";

interface GoogleMapWithRadiusProps {
  latitude?: number | string;
  longitude?: number | string;
  mapOptions?: {
    zoom?: number;
  };
}

// Utility function to safely convert coordinates to numbers
const safeParseNumber = (value: number | string | undefined): number | null => {
  if (value === undefined || value === null || value === "") return null;
  const num = typeof value === "string" ? parseFloat(value) : value;
  return !isNaN(num) && isFinite(num) ? num : null;
};

// 2 miles in meters for radius circle
const RADIUS_METERS = 2 * 1609.34;

const GoogleMapWithRadius: React.FC<GoogleMapWithRadiusProps> = ({
  latitude: rawLatitude,
  longitude: rawLongitude,
  mapOptions = {},
}) => {
  // Convert coordinates to numbers safely
  const latitude = safeParseNumber(rawLatitude);
  const longitude = safeParseNumber(rawLongitude);

  // Destructure mapOptions to create stable references
  const { zoom = 12 } = mapOptions;

  // Get API key and Map ID from environment
  const apiKey = process.env.REACT_APP_GOOGLE_MAPS_PUBLIC_API_KEY;
  const mapId = process.env.REACT_APP_GOOGLE_MAPS_MAP_ID;

  // Refs for map container and instances
  const mapRef = useRef<HTMLDivElement>(null);
  const mapInstanceRef = useRef<google.maps.Map | null>(null);
  const circleRef = useRef<google.maps.Circle | null>(null);

  // Memoize map center
  const mapCenter = useMemo(() => {
    if (latitude === null || longitude === null) return null;
    return { lat: latitude, lng: longitude };
  }, [latitude, longitude]);

  // Initialize map
  useEffect(() => {
    if (!apiKey || !mapRef.current || !mapCenter) return;

    const initializeMap = async () => {
      const loader = new Loader({
        apiKey,
        version: "weekly",
      });

      try {
        await loader.importLibrary("maps");

        if (!mapRef.current) return;

        // Create map configuration
        const mapConfig: google.maps.MapOptions = {
          mapId: mapId,
          center: mapCenter,
          zoom: zoom,
          maxZoom: 15, // Prevent users from zooming too close
          zoomControl: true,
          mapTypeControl: false,
          scaleControl: true,
          streetViewControl: false,
          rotateControl: false,
          fullscreenControl: false,
        };

        const map = new google.maps.Map(mapRef.current, mapConfig);

        mapInstanceRef.current = map;

        // Create circle overlay
        const circle = new google.maps.Circle({
          center: mapCenter,
          radius: RADIUS_METERS,
          fillColor: "#6c757d",
          fillOpacity: 0.2,
          strokeColor: "#6c757d",
          strokeOpacity: 0.8,
          strokeWeight: 2,
          map: map,
        });

        circleRef.current = circle;
      } catch (error) {
        console.error("Failed to load Google Maps:", error);
      }
    };

    initializeMap();

    // Cleanup function
    return () => {
      if (circleRef.current) {
        circleRef.current.setMap(null);
      }
      mapInstanceRef.current = null;
    };
  }, [apiKey, mapId, mapCenter, zoom]);

  // Update map center and circle when coordinates change
  useEffect(() => {
    if (!mapInstanceRef.current || !circleRef.current || !mapCenter) return;

    mapInstanceRef.current.setCenter(mapCenter);
    circleRef.current.setCenter(mapCenter);
  }, [mapCenter]);

  // Handle case where no coordinates are available
  if (latitude === null || longitude === null || mapCenter === null) {
    return (
      <div className="mb-4">
        <h5>Location</h5>
        <div
          className="d-flex align-items-center justify-content-center"
          style={{
            height: "300px",
            backgroundColor: "#f8f9fa",
            borderRadius: "8px",
          }}
        >
          <div className="text-center">
            <p className="text-muted small">Map unavailable</p>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="mb-4">
      <h5>Location</h5>
      <div
        ref={mapRef}
        style={{
          height: "300px",
          borderRadius: "8px",
          backgroundColor: "#f8f9fa",
          width: "100%",
        }}
      />
    </div>
  );
};

export default GoogleMapWithRadius;
