import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import 'leaflet.markercluster';
import 'leaflet.markercluster/dist/MarkerCluster.css';
import 'leaflet.markercluster/dist/MarkerCluster.Default.css';
import { useEffect, useRef, useState } from 'react';
import type { Place } from '@/types';

const MAPTILER_API_KEY = import.meta.env.VITE_MAPTILER_API_KEY || 'qkmdHs3dr0gUcmKEW3rK';

interface POI {
  id: string;
  name: string;
  description?: string;
  latitude: number;
  longitude: number;
  category: 'restaurant' | 'attraction' | 'hotel' | 'activity' | 'nature' | 'shopping';
  rating?: number;
  imageUrl?: string;
}

interface MapTilerMapProps {
  places: Place[];
  allPOIs?: POI[];
  onAddPlace?: (poiId: string) => void;
  onRemovePlace?: (placeId: string) => void;
  center?: [number, number];
  zoom?: number;
  className?: string;
}

const getCategoryIcon = (category: string): L.DivIcon => {
  const iconConfig: Record<string, { color: string; icon: string }> = {
    restaurant: { color: '#FF6347', icon: '🍽️' },
    attraction: { color: '#4169E1', icon: '🏛️' },
    hotel: { color: '#9370DB', icon: '🏨' },
    activity: { color: '#FF8C00', icon: '🎈' },
    nature: { color: '#228B22', icon: '🌳' },
    shopping: { color: '#DC143C', icon: '🛍️' },
    default: { color: '#808080', icon: '📍' },
  };

  const config = iconConfig[category.toLowerCase()] || iconConfig.default;

  return L.divIcon({
    className: 'poi-marker',
    html: `
      <div style="
        background-color: ${config.color};
        width: 32px;
        height: 32px;
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        color: white;
        font-size: 16px;
        border: 2px solid white;
        box-shadow: 0 2px 6px rgba(0,0,0,0.3);
        cursor: pointer;
      ">${config.icon}</div>
    `,
    iconSize: [32, 32],
    iconAnchor: [16, 16],
  });
};

const getRouteMarkerIcon = (index: number): L.DivIcon => {
  return L.divIcon({
    className: 'route-marker',
    html: `
      <div style="
        background-color: #4F46E5;
        width: 40px;
        height: 40px;
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        color: white;
        font-weight: bold;
        font-size: 16px;
        border: 3px solid white;
        box-shadow: 0 3px 10px rgba(0,0,0,0.4);
        cursor: pointer;
        z-index: 1000;
      ">${index + 1}</div>
    `,
    iconSize: [40, 40],
    iconAnchor: [20, 20],
  });
};

export function MapTilerMap({
  places,
  allPOIs = [],
  onAddPlace,
  onRemovePlace,
  center = [38.6431, 34.8289], // Cappadocia center
  zoom = 11,
  className = '',
}: MapTilerMapProps) {
  const mapContainer = useRef<HTMLDivElement>(null);
  const map = useRef<L.Map | null>(null);
  const markersRef = useRef<L.Marker[]>([]);
  const clusterGroup = useRef<L.MarkerClusterGroup | null>(null);
  const polylineRef = useRef<L.Polyline | null>(null);
  const [isMapReady, setIsMapReady] = useState(false);

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

    // Create map
    map.current = L.map(mapContainer.current, {
      center,
      zoom,
      zoomControl: true,
      attributionControl: true,
    });

    // Add MapTiler tile layer
    L.tileLayer(
      `https://api.maptiler.com/maps/outdoor-v2/{z}/{x}/{y}.png?key=${MAPTILER_API_KEY}`,
      {
        attribution:
          '© <a href="https://www.maptiler.com/">MapTiler</a> © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
        maxZoom: 19,
        tileSize: 512,
        zoomOffset: -1,
      }
    ).addTo(map.current);

    // Create marker cluster group
    clusterGroup.current = L.markerClusterGroup({
      maxClusterRadius: 50,
      spiderfyOnMaxZoom: true,
      showCoverageOnHover: false,
      zoomToBoundsOnClick: true,
      iconCreateFunction: (cluster) => {
        const count = cluster.getChildCount();
        return L.divIcon({
          html: `<div style="
            background-color: rgba(79, 70, 229, 0.8);
            width: 40px;
            height: 40px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            color: white;
            font-weight: bold;
            border: 3px solid white;
            box-shadow: 0 2px 8px rgba(0,0,0,0.3);
          ">${count}</div>`,
          className: 'marker-cluster-custom',
          iconSize: L.point(40, 40),
        });
      },
    });

    map.current.addLayer(clusterGroup.current);
    setIsMapReady(true);

    return () => {
      map.current?.remove();
      map.current = null;
    };
  }, []);

  // Update POI markers
  useEffect(() => {
    if (!map.current || !clusterGroup.current || !isMapReady) return;

    // Clear existing POI markers
    clusterGroup.current.clearLayers();

    // Add POI markers
    allPOIs.forEach((poi) => {
      const marker = L.marker([poi.latitude, poi.longitude], {
        icon: getCategoryIcon(poi.category),
      });

      // Create popup content
      const popupContent = `
        <div style="min-width: 250px; max-width: 300px;">
          ${
            poi.imageUrl
              ? `<img src="${poi.imageUrl}" alt="${poi.name}" style="width: 100%; height: 150px; object-fit: cover; border-radius: 8px; margin-bottom: 8px;" />`
              : ''
          }
          <h3 style="margin: 0 0 8px 0; font-size: 16px; font-weight: bold;">${poi.name}</h3>
          <p style="margin: 0 0 4px 0; font-size: 12px; color: #666;">${poi.category}</p>
          ${poi.rating ? `<p style="margin: 0 0 8px 0; font-size: 12px; color: #FFD700;">⭐ ${poi.rating}/5</p>` : ''}
          <p style="margin: 0 0 12px 0; font-size: 13px; line-height: 1.4;">${poi.description || ''}</p>
          ${
            onAddPlace
              ? `<button 
            id="add-poi-${poi.id}"
            style="
              width: 100%;
              padding: 8px 16px;
              background-color: #4F46E5;
              color: white;
              border: none;
              border-radius: 6px;
              cursor: pointer;
              font-size: 13px;
              font-weight: 500;
              transition: background-color 0.2s;
            "
          >Add to Route</button>`
              : ''
          }
        </div>
      `;

      marker.bindPopup(popupContent, {
        maxWidth: 300,
        className: 'custom-popup',
      });

      // Add click handler for "Add to Route" button
      if (onAddPlace) {
        marker.on('popupopen', () => {
          const button = document.getElementById(`add-poi-${poi.id}`);
          if (button) {
            button.addEventListener('click', () => {
              onAddPlace(poi.id);
              marker.closePopup();
            });
          }
        });
      }

      clusterGroup.current!.addLayer(marker);
    });
  }, [allPOIs, isMapReady, onAddPlace]);

  // Update route markers and polyline
  useEffect(() => {
    if (!map.current || !isMapReady) return;

    // Clear old route markers
    markersRef.current.forEach((marker) => marker.remove());
    markersRef.current = [];

    // Clear old polyline
    if (polylineRef.current) {
      polylineRef.current.remove();
      polylineRef.current = null;
    }

    // Add new route markers
    places.forEach((place, index) => {
      const marker = L.marker([place.latitude, place.longitude], {
        icon: getRouteMarkerIcon(index),
        zIndexOffset: 1000,
      }).addTo(map.current!);

      // Create popup for route marker
      const popupContent = `
        <div style="min-width: 250px;">
          ${
            place.img
              ? `<img src="${place.img}" alt="${place.name}" style="width: 100%; height: 150px; object-fit: cover; border-radius: 8px; margin-bottom: 8px;" />`
              : ''
          }
          <h3 style="margin: 0 0 8px 0; font-size: 16px; font-weight: bold;">${place.name}</h3>
          <p style="margin: 0 0 8px 0; font-size: 13px; line-height: 1.4;">${place.description || ''}</p>
          <p style="margin: 0 0 12px 0; font-size: 12px; color: #666;">Order: ${index + 1}</p>
          ${
            onRemovePlace
              ? `<button 
            id="remove-place-${place.id}"
            style="
              width: 100%;
              padding: 8px 16px;
              background-color: #EF4444;
              color: white;
              border: none;
              border-radius: 6px;
              cursor: pointer;
              font-size: 13px;
              font-weight: 500;
            "
          >Remove from Route</button>`
              : ''
          }
        </div>
      `;

      marker.bindPopup(popupContent, {
        maxWidth: 300,
      });

      // Add click handler for "Remove from Route" button
      if (onRemovePlace) {
        marker.on('popupopen', () => {
          const button = document.getElementById(`remove-place-${place.id}`);
          if (button) {
            button.addEventListener('click', () => {
              onRemovePlace(place.id);
              marker.closePopup();
            });
          }
        });
      }

      markersRef.current.push(marker);
    });

    // Draw route polyline
    if (places.length >= 2) {
      const latLngs: L.LatLngExpression[] = places.map((p) => [p.latitude, p.longitude]);
      polylineRef.current = L.polyline(latLngs, {
        color: '#4F46E5',
        weight: 4,
        opacity: 0.7,
        smoothFactor: 1,
      }).addTo(map.current!);

      // Fit map to route bounds
      map.current!.fitBounds(polylineRef.current.getBounds(), {
        padding: [50, 50],
      });
    } else if (places.length === 1) {
      // Center on single place
      map.current!.setView([places[0].latitude, places[0].longitude], 13);
    }
  }, [places, isMapReady, onRemovePlace]);

  return (
    <div
      ref={mapContainer}
      className={`maptiler-map ${className}`}
      style={{ width: '100%', height: '100%', touchAction: 'pan-x pan-y' }}
    />
  );
}
