import { useState, useEffect, useRef } from "react";
import L from "leaflet";
import { useTranslation } from "react-i18next";
import { useMap } from "react-leaflet";
import { poiCategories } from "~/lib/poi-categories";
import type { PoiState } from "~/lib/use-pois";

interface PoiPanelProps {
  poiState: PoiState;
}

export function PoiPanel({ poiState }: PoiPanelProps) {
  const { t } = useTranslation("planner");
  const [open, setOpen] = useState(false);
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (ref.current) L.DomEvent.disableClickPropagation(ref.current);
  }, []);

  const countByCategory = new Map<string, number>();
  for (const poi of poiState.pois) {
    countByCategory.set(poi.category, (countByCategory.get(poi.category) ?? 0) + 1);
  }

  return (
    <div ref={ref} className="leaflet-top leaflet-right" style={{ marginTop: 120 }}>
      <div className="leaflet-control">
        <button
          onClick={() => setOpen((v) => !v)}
          className="flex h-8 w-8 items-center justify-center rounded bg-white text-base shadow-md hover:bg-gray-50"
          title={t("poi.toggle")}
        >
          📍
        </button>
        {open && (
          <div className="mt-1 w-48 rounded bg-white p-2 shadow-lg">
            <p className="mb-1 text-xs font-semibold text-gray-600">{t("poi.title")}</p>

            {poiState.status === "zoom_too_low" && (
              <p className="text-xs text-amber-600">{t("poi.zoomIn")}</p>
            )}
            {poiState.status === "rate_limited" && (
              <p className="text-xs text-red-600">{t("poi.rateLimited")}</p>
            )}
            {poiState.status === "error" && (
              <p className="text-xs text-red-600">{t("poi.error")}</p>
            )}
            {poiState.status === "loading" && (
              <p className="text-xs text-blue-600">{t("poi.loading")}</p>
            )}

            <div className="mt-1 space-y-0.5">
              {poiCategories.map((cat) => {
                const count = countByCategory.get(cat.id) ?? 0;
                const enabled = poiState.enabledCategories.includes(cat.id);
                return (
                  <label key={cat.id} className="flex cursor-pointer items-center gap-1.5 rounded px-1 py-0.5 hover:bg-gray-50">
                    <input
                      type="checkbox"
                      checked={enabled}
                      onChange={() => poiState.toggleCategory(cat.id)}
                      className="h-3.5 w-3.5 rounded border-gray-300"
                    />
                    <span className="text-sm">{cat.icon}</span>
                    <span className="flex-1 text-xs text-gray-700">{t(cat.name)}</span>
                    {enabled && count > 0 && (
                      <span className="text-[10px] tabular-nums text-gray-400">{count}</span>
                    )}
                  </label>
                );
              })}
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

export function PoiMarkers({ poiState }: PoiPanelProps) {
  const map = useMap();
  const layerRef = useRef<L.LayerGroup>(L.layerGroup());

  useEffect(() => {
    layerRef.current.addTo(map);
    return () => { layerRef.current.remove(); };
  }, [map]);

  useEffect(() => {
    const group = layerRef.current;
    group.clearLayers();

    const catMap = new Map(poiCategories.map((c) => [c.id, c]));

    for (const poi of poiState.pois) {
      const cat = catMap.get(poi.category);
      if (!cat) continue;

      const marker = L.marker([poi.lat, poi.lon], {
        icon: L.divIcon({
          className: "",
          html: `<div style="
            width:20px;height:20px;border-radius:50%;
            background:white;
            display:flex;align-items:center;justify-content:center;
            font-size:12px;
            border:2px solid ${cat.color};
            box-shadow:0 1px 3px rgba(0,0,0,0.2);
            transform:translate(-10px,-10px);
          ">${cat.icon}</div>`,
          iconSize: [0, 0],
        }),
        zIndexOffset: -1000,
      });

      const popupLines = [`<strong>${poi.name ?? cat.icon + " " + poi.category}</strong>`];
      popupLines.push(`<span style="font-size:11px;color:#888">${cat.icon} ${cat.id.replace(/_/g, " ")}</span>`);
      if (poi.tags.description) popupLines.push(`<span style="font-size:12px">${poi.tags.description}</span>`);
      const addr = [poi.tags["addr:street"], poi.tags["addr:housenumber"]].filter(Boolean).join(" ");
      const addrCity = [addr, poi.tags["addr:postcode"], poi.tags["addr:city"]].filter(Boolean).join(", ");
      if (addrCity) popupLines.push(`📍 ${addrCity}`);
      const phone = poi.tags.phone ?? poi.tags["contact:phone"];
      if (phone) popupLines.push(`📞 <a href="tel:${phone}">${phone}</a>`);
      if (poi.tags.opening_hours) popupLines.push(`🕐 ${poi.tags.opening_hours}`);
      if (poi.tags.website) popupLines.push(`<a href="${poi.tags.website}" target="_blank" rel="noopener">Website</a>`);
      popupLines.push(`<a href="https://www.openstreetmap.org/node/${poi.id}" target="_blank" rel="noopener" style="font-size:11px;color:#666">OSM</a>`);

      marker.bindPopup(popupLines.join("<br>"), { maxWidth: 200 });
      group.addLayer(marker);
    }
  }, [poiState.pois]);

  return null;
}
