"use client";

import {
  MapContainer,
  TileLayer,
  Marker,
  Popup,
  Circle,
  useMapEvents,
} from "react-leaflet";

import "leaflet/dist/leaflet.css";
import "leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css";
import "leaflet-defaulticon-compatibility";
import { cn } from "~/lib/utils";
import MapMarker from "~/components/map/map_marker";
import { Marker as CustomMarker } from "~/components/map/custom_marker";
import { Home } from "lucide-react";

type LatLon = {
  lat: number;
  lng: number;
  alt?: number;
};
type posData = {
  pos: LatLon;
  popupTxt?: string;
  onClick?: () => void;
  markerTxt?: string;
};

type GroupProps = {
  isGroup: true;
  groupData: posData[];
};

type SingleProps = {
  isGroup?: false;
  groupData?: never;
};

type MapProps = {
  posix: posData;
  autocenter?: boolean;
  zoom?: number;
  markerType: "precise" | "circle" | "price" | "home";
  markerRadius?: number;
  scrollWheelZoom?: boolean;
  width?: string;
  height?: string;
  onMapClick?: () => void;
} & (GroupProps | SingleProps);

const defaults = {
  zoom: 15,
  width: "500px",
  height: "500px",
};

const MedianPoint = (pos: posData[]) => {
  const lat = pos.map((p) => p.pos.lat).reduce((a, b) => a + b) / pos.length;
  const lng = pos.map((p) => p.pos.lng).reduce((a, b) => a + b) / pos.length;
  return { lat, lng };
};

const Map = ({
  posix,
  autocenter,
  zoom = defaults.zoom,
  markerType,
  markerRadius,
  scrollWheelZoom = false,
  width = defaults.width,
  height = defaults.height,
  isGroup,
  groupData,
  onMapClick,
}: MapProps) => {
  const APIs = () => {
    useMapEvents({
      click: () => {
        if (onMapClick) {
          onMapClick();
        }
      },
    });
    return null;
  };

  const MarkerComp = ({ pos }: { pos: posData }) => {
    switch (markerType) {
      case "price":
        return (
          <CustomMarker
            position={pos.pos}
            eventHandlers={pos.onClick && { click: pos.onClick }}
            title={pos.markerTxt}
            icon={
              <MapMarker
                label={
                  <span className="inline-block whitespace-nowrap">
                    {pos.markerTxt}
                  </span>
                }
                color="primary"
                size="sm"
              />
            }
          >
            {pos.popupTxt && <Popup>{pos.popupTxt}</Popup>}
          </CustomMarker>
        );

      case "precise":
        return (
          <Marker
            position={pos.pos}
            eventHandlers={pos.onClick && { click: pos.onClick }}
            title={pos.markerTxt}
          >
            {pos.popupTxt && <Popup>{pos.popupTxt}</Popup>}
          </Marker>
        );
      case "circle":
        return (
          <Circle
            center={pos.pos}
            pathOptions={{ color: "red" }}
            radius={markerRadius || 100}
            eventHandlers={pos.onClick && { click: pos.onClick }}
          >
            {pos.popupTxt && <Popup>{pos.popupTxt}</Popup>}
          </Circle>
        );
      case "home":
        return (
          <>
            <Circle
              center={pos.pos}
              pathOptions={{ color: "#ec4899" }}
              fillOpacity={1}
              radius={markerRadius || 100}
              eventHandlers={pos.onClick && { click: pos.onClick }}
            >
              {pos.popupTxt && <Popup>{pos.popupTxt}</Popup>}
            </Circle>
            <CustomMarker
              position={pos.pos}
              eventHandlers={pos.onClick && { click: pos.onClick }}
              title={pos.markerTxt}
              icon={
                <div className="relative flex size-10 items-center justify-center rounded-full bg-pink-500 p-2">
                  <Home className="absolute size-3/4 stroke-white" />
                </div>
              }
            >
              {pos.popupTxt && <Popup>{pos.popupTxt}</Popup>}
            </CustomMarker>
          </>
        );
    }
  };

  const hashKey = JSON.stringify(
    groupData ? groupData.map((p) => p.pos) : posix.pos,
  );

  return (
    <MapContainer
      key={hashKey}
      center={
        autocenter ? MedianPoint(isGroup ? groupData : [posix]) : posix.pos
      }
      zoom={zoom}
      scrollWheelZoom={scrollWheelZoom}
      style={{
        height: height,
        width: width,
        borderRadius: "8px",
      }}
      className={cn("")}
    >
      <APIs />
      <TileLayer
        url="/api/tiles/{s}/{z}/{x}/{y}"
        //url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
      />

      {isGroup ? (
        groupData.map((pos, i) => <MarkerComp key={i} pos={pos} />)
      ) : (
        <MarkerComp pos={posix} />
      )}
    </MapContainer>
  );
};

export default Map;

/*
const PuntiInteresse: {
  title: string;
  lat: number;
  lng: number;
  icon: IconType;
}[] = [
  {
    title: "PIAZZA LIBERTA’",
    lat: 45.766706,
    lng: 11.733919,
    icon: "milestone",
  },
  { title: "PONTE VECCHIO", lat: 45.76752, lng: 11.731148, icon: "milestone" },
  { title: "INFOALLOGGI", lat: 45.764886, lng: 11.736019, icon: "info" },
  { title: "PRATO 1", lat: 45.770066, lng: 11.736306, icon: "parking" },
  { title: "PRATO 2", lat: 45.771495, lng: 11.734107, icon: "parking" },
  {
    title: "STAZIONE FERROVIARIA/BUS",
    lat: 45.766709,
    lng: 11.741204,
    icon: "milestone",
  },
  { title: "GIARDINI PAROLINI", lat: 45.764804, lng: 11.738355, icon: "park" },
  { title: "BIBLIOTECA", lat: 45.765801, lng: 11.735987, icon: "school" },
  { title: "CENTRO STUDIO", lat: 45.754266, lng: 11.733066, icon: "school" },
  { title: "OSPEDALE", lat: 45.747444, lng: 11.744371, icon: "cross" },
  {
    title: "PALARENA CMP",
    lat: 45.747374,
    lng: 11.740302,
    icon: "entertainment",
  },
  { title: "PONTE NUOVO", lat: 45.764594, lng: 11.729995, icon: "milestone" },
  { title: "OSSARIO ", lat: 45.763568, lng: 11.733449, icon: "milestone" },
  { title: "CINEMA METROPOLIS", lat: 45.742997, lng: 11.735622, icon: "film" },
  {
    title: "CENTRO COMMERCIALE GRIFONE",
    lat: 45.744988,
    lng: 11.751847,
    icon: "cart",
  },
  {
    title: "CENTRO COMMERCIALE EMISFERO",
    lat: 45.742368,
    lng: 11.728874,
    icon: "cart",
  },
  {
    title: "SUPERMERCATO Alì s. vito",
    lat: 45.775167,
    lng: 11.750929,
    icon: "cart",
  },
  {
    title: "SUPERMERCATO Alì cà baroncello ",
    lat: 45.758659,
    lng: 11.751037,
    icon: "cart",
  },
  {
    title: "CONAD via passalacqua",
    lat: 45.771366,
    lng: 11.742604,
    icon: "cart",
  },
  {
    title: "CONAD  VIALE PECORI GIRARDI",
    lat: 45.764649,
    lng: 11.720416,
    icon: "cart",
  },
  {
    title: "BIOSAPORI VIALE DE GASPERI",
    lat: 45.761377,
    lng: 11.732186,
    icon: "cart",
  },
  { title: "SUPERMERCATO ALDI ", lat: 45.743694, lng: 11.755435, icon: "cart" },
  {
    title: "SUPERMERCATO TOSANO",
    lat: 45.764982,
    lng: 11.766572,
    icon: "cart",
  },
  {
    title: "POSTE CENTRALI BASSANO",
    lat: 45.762758,
    lng: 11.735091,
    icon: "mail",
  },
  { title: "POSTE VIA ANGARANO", lat: 45.767573, lng: 11.726599, icon: "mail" },
];
*/
