"use client";

import { Map, InfoWindow, useApiIsLoaded } from "@vis.gl/react-google-maps";
import { useMemo, useState, useCallback, useEffect } from "react";
import MapMarker from "./MapMarker";
import InfoWindowContent from "./InfoWindowContent";
import { MapContainerProps, Place } from "./types";
import { useTranslations } from "next-intl";
import Loader from "@/components/shared/Loader/Loader";

export default function MapContainer({
  places,
  iconSize = 40,
  height = "50vh",
  width = "100%",
  className = "",
  initialCenter,
  initialZoom = 16,
}: MapContainerProps) {
  const isLoaded = useApiIsLoaded();

  // Calculate center based on places positions
  const calculatedCenter = useMemo(() => {
    if (!places || places.length === 0) {
      // return { lat: 24.7535, lng: 46.6555 }; // Default center
      return null;
    }

    // Calculate center as average of all positions
    const totalLat = places.reduce((sum, place) => sum + place.position.lat, 0);
    const totalLng = places.reduce((sum, place) => sum + place.position.lng, 0);

    return {
      lat: totalLat / places.length,
      lng: totalLng / places.length,
    };
  }, [places]);

  // Calculate appropriate zoom level based on distance between markers
  const calculatedZoom = useMemo(() => {
    if (!places || places.length === 0) {
      return 16; // Default zoom
    }

    if (places.length === 1) {
      return 16; // Close zoom for single location
    }

    // Find bounds of all places
    const lats = places.map((place) => place.position.lat);
    const lngs = places.map((place) => place.position.lng);

    const minLat = Math.min(...lats);
    const maxLat = Math.max(...lats);
    const minLng = Math.min(...lngs);
    const maxLng = Math.max(...lngs);

    // Calculate distance between bounds
    const latDiff = maxLat - minLat;
    const lngDiff = maxLng - minLng;
    const maxDiff = Math.max(latDiff, lngDiff);

    // Add padding to ensure all markers are visible
    const padding = maxDiff * 0.2; // 20% padding
    const adjustedDiff = maxDiff + padding;

    // Calculate zoom based on adjusted distance
    if (adjustedDiff > 0.5) return 7; // Very far zoom
    if (adjustedDiff > 0.2) return 8; // Far zoom
    if (adjustedDiff > 0.1) return 9; // Medium-far zoom
    if (adjustedDiff > 0.05) return 10; // Medium zoom
    if (adjustedDiff > 0.02) return 11; // Medium-close zoom
    if (adjustedDiff > 0.01) return 12; // Close zoom
    if (adjustedDiff > 0.005) return 13; // Very close zoom
    if (adjustedDiff > 0.002) return 14; // Extremely close zoom
    return 15; // Maximum zoom for very close locations
  }, [places]);

  const defaultCenter = useMemo(() => ({ lat: 24.7535, lng: 46.6555 }), []);

  // Only use calculated center if we have places, otherwise use initialCenter or default
  const center = useMemo(() => {
    if (calculatedCenter) {
      return calculatedCenter;
    }
    return initialCenter || defaultCenter;
  }, [calculatedCenter, initialCenter, defaultCenter]);

  const [mapCenter, setMapCenter] = useState(center);
  const [zoom, setZoom] = useState(calculatedZoom || initialZoom);
  const [selectedId, setSelectedId] = useState<number | null>(null);

  // Update map center and zoom when calculated values change
  useEffect(() => {
    if (calculatedCenter) {
      setMapCenter(calculatedCenter);
    }
    if (calculatedZoom) {
      setZoom(calculatedZoom);
    }
  }, [calculatedCenter, calculatedZoom]);

  const selectedPlace = useMemo(
    () => places.find((p) => p.id === selectedId) ?? null,
    [places, selectedId]
  );

  const handleMarkerClick = useCallback((place: Place) => {
    setSelectedId(place.id);
  }, []);

  const t = useTranslations("LocationPage.map");

  if (!isLoaded) return <Loader />;

  return (
    <div className={`${className}`} style={{ height, width }}>
      <Map
        defaultCenter={center}
        defaultZoom={initialZoom}
        center={mapCenter}
        zoom={zoom}
        gestureHandling="greedy"
        disableDefaultUI={true}
        onCameraChanged={(ev) => {
          setMapCenter(ev.detail.center);
          setZoom(ev.detail.zoom);
        }}
      >
        {places.map((place) => (
          <MapMarker
            key={place.id}
            place={place}
            onMarkerClick={handleMarkerClick}
            iconSize={iconSize}
          />
        ))}

        {selectedPlace && (
          <InfoWindow
            position={selectedPlace.position}
            onCloseClick={() => setSelectedId(null)}
            shouldFocus
            disableAutoPan
          >
            <InfoWindowContent place={selectedPlace} />
          </InfoWindow>
        )}
      </Map>
    </div>
  );
}
