"use client";

import { useCallback } from "react";
import Map from "react-map-gl/maplibre";
import { DeckGL } from "@deck.gl/react";
import { ZoomIn, ZoomOut, Crosshair } from "lucide-react";
import { Button } from "@/components/ui/button";
import type { PointDatum } from "@/types/trajectory";

export type ViewState = {
  longitude: number;
  latitude: number;
  zoom: number;
  pitch?: number;
  bearing?: number;
};

interface MapViewProps {
  viewState: ViewState;
  setViewState: React.Dispatch<React.SetStateAction<ViewState>>;
  layers: React.ComponentProps<typeof DeckGL>["layers"];
  onClick: (opts: { object?: PointDatum }) => void;
  getTooltip: (opts: { object?: PointDatum }) => { text: string } | null;
  mapStyle: string;
  /** When provided, shows a button to fit the map view to all particles. */
  onFitToParticles?: () => void;
}

export function MapView({
  viewState,
  setViewState,
  layers,
  onClick,
  getTooltip,
  mapStyle,
  onFitToParticles,
}: MapViewProps) {
  const zoomIn = useCallback(() => {
    setViewState((v) => ({
      ...v,
      zoom: Math.min(18, (v.zoom ?? 7.5) + 1),
    }));
  }, [setViewState]);

  const zoomOut = useCallback(() => {
    setViewState((v) => ({
      ...v,
      zoom: Math.max(2, (v.zoom ?? 7.5) - 1),
    }));
  }, [setViewState]);

  return (
    <>
      <DeckGL
        viewState={viewState}
        onViewStateChange={({ viewState: vs }) =>
          setViewState((prev) => ({ ...prev, ...vs }))
        }
        controller
        layers={layers}
        onClick={({ object }) => onClick({ object: object as PointDatum })}
        getTooltip={({ object }) =>
          getTooltip({ object: object as PointDatum })
        }
      >
        <Map mapStyle={mapStyle} />
      </DeckGL>
      <div className="absolute right-4 top-1/2 z-10 -translate-y-1/2 flex flex-col gap-1 rounded-xl border border-slate-600/80 bg-slate-800/95 shadow-xl backdrop-blur-sm p-1">
        {onFitToParticles && (
          <>
            <Button
              variant="outline"
              size="icon"
              className="h-11 w-11 rounded-lg border-slate-600 bg-slate-700/80 text-slate-200 hover:bg-slate-600 hover:text-white focus:ring-2 focus:ring-teal-500/50"
              onClick={onFitToParticles}
              title="Zoom a les partícules"
              aria-label="Zoom a les partícules"
            >
              <Crosshair className="size-5" />
            </Button>
            <div className="h-px bg-slate-600/80 mx-1" />
          </>
        )}
        <Button
          variant="outline"
          size="icon"
          className="h-11 w-11 rounded-lg border-slate-600 bg-slate-700/80 text-slate-200 hover:bg-slate-600 hover:text-white focus:ring-2 focus:ring-teal-500/50"
          onClick={zoomIn}
          aria-label="Zoom in"
        >
          <ZoomIn className="size-5" />
        </Button>
        <div className="h-px bg-slate-600/80 mx-1" />
        <Button
          variant="outline"
          size="icon"
          className="h-11 w-11 rounded-lg border-slate-600 bg-slate-700/80 text-slate-200 hover:bg-slate-600 hover:text-white focus:ring-2 focus:ring-teal-500/50"
          onClick={zoomOut}
          aria-label="Zoom out"
        >
          <ZoomOut className="size-5" />
        </Button>
      </div>
    </>
  );
}
