"use client"

import type React from "react"
import { useState, useCallback, useRef, useEffect } from "react"
import { type ViewState, Map, type MapRef, NavigationControl, GeolocateControl } from "react-map-gl/mapbox"
import { FullscreenControl } from "react-map-gl/mapbox"
import { BASE_BEARING, BASE_LATITUDE, BASE_LONGITUDE, BASE_PITCH, BASE_ZOOM, MAPBOX_STYLES, type MapboxStyle } from "@/app/_utils/const/map"
import "mapbox-gl/dist/mapbox-gl.css"
import MapboxGeocoder from '@mapbox/mapbox-gl-geocoder';
import '@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css';
import mapboxgl from "mapbox-gl"

interface MapViewProps {
  children?: React.ReactNode
  initialViewState?: Partial<ViewState>
  mapStyle?: MapboxStyle
  className?: string
  width?: string | number
  height?: string | number
  mapboxApiAccessToken?: string
  onMoveEnd?: (viewState: ViewState) => void
  customControls?: React.ReactNode
}

export default function MapView({
  children,
  initialViewState,
  mapStyle = MAPBOX_STYLES.Standard,
  className = "w-full h-96",
  width = "100%",
  height = "100%",
  mapboxApiAccessToken = process.env.NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN,
  onMoveEnd,
}: MapViewProps) {
  const mapContainerRef = useRef<MapRef | null>(null);
  const mapRef = useRef<MapRef | null>(null);

  const defaultViewState: Partial<ViewState> = {
    longitude: BASE_LONGITUDE,
    latitude: BASE_LATITUDE,
    zoom: BASE_ZOOM,
    bearing: BASE_BEARING,
    pitch: BASE_PITCH,
    ...initialViewState,
  }

  const geocoder = new MapboxGeocoder(
    {
      accessToken: mapboxApiAccessToken!,
      mapboxgl: mapboxgl as any, // Type assertion to bypass type checking
      marker: false,
      placeholder: "Search for places",
      proximity: {
        longitude: BASE_LONGITUDE,
        latitude: BASE_LATITUDE,
      },
    },
  )

  const fullscreenControl = new mapboxgl.FullscreenControl();
  const navigationControl = new mapboxgl.NavigationControl({
    showCompass: false,
  });

  const handleMapLoad = useCallback(() => {
    if (mapRef.current) {
      // mapRef.current.addControl(geocoder, "top-right")
      mapRef.current.addControl(fullscreenControl, "top-right")
      mapRef.current.addControl(navigationControl, "top-right")
    }
  }, [mapRef, geocoder, fullscreenControl, navigationControl])

  const handleMoveEnd = useCallback(
    (event: any) => {
      if (onMoveEnd) {
        onMoveEnd(event.viewState)
      }
    },
    [onMoveEnd],
  )

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

    const mapElement = mapRef.current.getMap().getContainer();

    // Handle fly to event
    const handleMapFly = (e: CustomEvent) => {
      if (!e.detail || !mapRef.current) return;

      const { center, zoom, bearing, pitch, duration, resetCamera } = e.detail;

      if (resetCamera) {
        // Reset to default view
        mapRef.current.flyTo({
          center: [BASE_LONGITUDE, BASE_LATITUDE],
          zoom: BASE_ZOOM,
          bearing: BASE_BEARING,
          pitch: BASE_PITCH,
          duration,
          essential: true
        });
      } else {
      // Fly to specific location
        mapRef.current.flyTo({
          center,
          zoom,
          bearing,
          pitch,
          duration,
          essential: true
        });
      }
    };

    mapElement.addEventListener('mapbox_fly', handleMapFly as EventListener);

    return () => {
      mapElement.removeEventListener('mapbox_fly', handleMapFly as EventListener);
    };
  }, [mapRef.current]);

  return (
    <div className={`relative ${className}`}>
      <div className="flex h-full">
        <div className="relative flex-grow h-full transition-all duration-300">
          <Map
            ref={mapRef}
            mapStyle={mapStyle}
            mapboxAccessToken={mapboxApiAccessToken}
            initialViewState={defaultViewState}
            onLoad={handleMapLoad}
            onMoveEnd={handleMoveEnd}
            style={{ width: "100%", height: "100%" }}
            attributionControl={false}
            preserveDrawingBuffer={true} // This helps with fullscreen stability
          >
            {/* <FullscreenControl position="top-right" />
            <NavigationControl position="top-right" showCompass={false} /> */}

            {children}
          </Map>
        </div>
      </div>
    </div>
  )
}