import { useEffect, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import type { MapData } from './types';

// Leaflet CDN を動的にロードする
let leafletLoaded = false;
let leafletLoadPromise: Promise<void> | null = null;

function loadLeaflet(): Promise<void> {
  if (leafletLoaded) return Promise.resolve();
  if (leafletLoadPromise) return leafletLoadPromise;

  leafletLoadPromise = new Promise<void>((resolve, reject) => {
    // CSS
    const link = document.createElement('link');
    link.rel = 'stylesheet';
    link.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';
    document.head.appendChild(link);

    // JS
    const script = document.createElement('script');
    script.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js';
    script.onload = () => {
      leafletLoaded = true;
      resolve();
    };
    script.onerror = () => reject(new Error('Failed to load Leaflet'));
    document.head.appendChild(script);
  });

  return leafletLoadPromise;
}

declare const L: typeof import('leaflet');

export function MapPlacesDetail({ data }: { data: MapData }) {
  const { t } = useTranslation('embed');
  const { query, places } = data;
  const mapRef = useRef<HTMLDivElement>(null);
  const mapInstanceRef = useRef<import('leaflet').Map | null>(null);

  useEffect(() => {
    if (!mapRef.current || places.length === 0) return;
    let cancelled = false;

    loadLeaflet().then(() => {
      if (cancelled || !mapRef.current) return;

      // 既存のマップがあれば破棄
      if (mapInstanceRef.current) {
        mapInstanceRef.current.remove();
      }

      const center = { lat: places[0]!.lat, lon: places[0]!.lon };
      const map = L.map(mapRef.current).setView([center.lat, center.lon], 13);
      mapInstanceRef.current = map;

      L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
        maxZoom: 19,
      }).addTo(map);

      const markers = places.map((p) =>
        L.marker([p.lat, p.lon])
          .addTo(map)
          .bindPopup(`<b>${p.name}</b><br>${p.address}`),
      );

      if (markers.length > 1) {
        const group = L.featureGroup(markers);
        map.fitBounds(group.getBounds().pad(0.15));
      }

      // モーダルが開いた直後はサイズが確定していない場合がある
      setTimeout(() => map.invalidateSize(), 100);
    });

    return () => {
      cancelled = true;
      if (mapInstanceRef.current) {
        mapInstanceRef.current.remove();
        mapInstanceRef.current = null;
      }
    };
  }, [places]);

  return (
    <div className="p-6">
      <h2 className="text-lg font-bold text-slate-800 mb-4">
        &#128205; {t('searchResults.map', { query })}
      </h2>

      {/* Leaflet map */}
      <div
        ref={mapRef}
        style={{ height: 400 }}
        className="w-full rounded-xl overflow-hidden border border-slate-200 mb-6"
      />

      {/* Place list */}
      <div className="space-y-4">
        {places.map((p, i) => (
          <div key={`${p.lat}-${p.lon}`} className="bg-canvas border border-slate-200 rounded-xl p-4">
            <div className="text-slate-400 mb-1" style={{ fontSize: 13 }}>#{i + 1}</div>
            <h3 className="text-sm font-semibold text-slate-800 leading-snug mb-2">{p.name}</h3>

            <div className="text-xs text-slate-600 space-y-1 mb-3">
              <div>&#128205; {p.address}</div>
              <div>&#128204; {p.lat.toFixed(6)}, {p.lon.toFixed(6)}</div>
              {p.type && <div>&#127991; {p.type}</div>}
              {p.details && <div>&#128172; {p.details}</div>}
            </div>

            <a
              href={p.mapUrl}
              target="_blank"
              rel="noopener noreferrer"
              className="inline-flex items-center gap-1 px-3 py-1.5 bg-slate-100 hover:bg-slate-200 text-slate-700 text-xs font-semibold rounded-lg no-underline transition-colors"
            >
              {t('viewOn.osm')}
            </a>
          </div>
        ))}
      </div>
    </div>
  );
}
