'use client';

import mapboxgl from 'mapbox-gl';
import * as React from 'react';
import 'mapbox-gl/dist/mapbox-gl.css';
import type { ListingDetail } from '@/lib/listings-api';

function formatPrice(priceVND: string): string {
  const num = Number(priceVND);
  if (num >= 1_000_000_000) return `${(num / 1_000_000_000).toFixed(1)} tỷ`;
  if (num >= 1_000_000) return `${(num / 1_000_000).toFixed(0)} tr`;
  return num.toLocaleString('vi-VN');
}

interface ListingMapProps {
  listings: ListingDetail[];
  onMarkerClick?: (listing: ListingDetail) => void;
  selectedListingId?: string;
  className?: string;
}

interface MapMarker {
  listing: ListingDetail;
  lat: number;
  lng: number;
}

const CITY_COORDS: Record<string, [number, number]> = {
  'Hồ Chí Minh': [10.8231, 106.6297],
  'Hà Nội': [21.0285, 105.8542],
  'Đà Nẵng': [16.0544, 108.2022],
  'Nha Trang': [12.2388, 109.1967],
  'Cần Thơ': [10.0452, 105.7469],
};

const DEFAULT_CENTER: [number, number] = [106.6297, 10.8231]; // HCMC [lng, lat]
const DEFAULT_ZOOM = 12;

function getMarkerCoords(listing: ListingDetail, index: number): { lat: number; lng: number } {
  const base = CITY_COORDS[listing.property.city] || [10.8231, 106.6297];
  const seed = listing.id.charCodeAt(0) + index;
  return {
    lat: base[0] + ((seed % 100) - 50) * 0.001,
    lng: base[1] + ((seed % 73) - 36) * 0.001,
  };
}

export function ListingMap({ listings, onMarkerClick, selectedListingId, className }: ListingMapProps) {
  const mapContainerRef = React.useRef<HTMLDivElement>(null);
  const mapRef = React.useRef<mapboxgl.Map | null>(null);
  const markersRef = React.useRef<mapboxgl.Marker[]>([]);
  const popupRef = React.useRef<mapboxgl.Popup | null>(null);

  const markers: MapMarker[] = React.useMemo(
    () => listings.map((listing, index) => ({ listing, ...getMarkerCoords(listing, index) })),
    [listings],
  );

  // Initialize map
  React.useEffect(() => {
    if (!mapContainerRef.current) return;

    const token = process.env['NEXT_PUBLIC_MAPBOX_TOKEN'];
    if (!token) {
      console.warn('NEXT_PUBLIC_MAPBOX_TOKEN is not set. Map will not render.');
      return;
    }

    mapboxgl.accessToken = token;

    const map = new mapboxgl.Map({
      container: mapContainerRef.current,
      style: 'mapbox://styles/mapbox/streets-v12',
      center: DEFAULT_CENTER,
      zoom: DEFAULT_ZOOM,
      attributionControl: false,
    });

    map.addControl(new mapboxgl.NavigationControl(), 'top-right');
    map.addControl(new mapboxgl.AttributionControl({ compact: true }), 'bottom-right');

    mapRef.current = map;

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

  // Update markers when listings change
  React.useEffect(() => {
    const map = mapRef.current;
    if (!map) return;

    // Clear existing markers
    markersRef.current.forEach((m) => m.remove());
    markersRef.current = [];

    if (markers.length === 0) return;

    const bounds = new mapboxgl.LngLatBounds();

    markers.forEach((marker) => {
      const el = document.createElement('button');
      el.className = 'mapbox-price-marker';
      const isSelected = selectedListingId === marker.listing.id;
      el.innerHTML = `<span class="${isSelected ? 'selected' : ''}">${formatPrice(marker.listing.priceVND)}</span>`;
      el.style.cssText = 'border:none;cursor:pointer;background:none;padding:0;';

      el.addEventListener('click', (e) => {
        e.stopPropagation();
        onMarkerClick?.(marker.listing);
        showPopup(map, marker);
      });

      const mbMarker = new mapboxgl.Marker({ element: el, anchor: 'bottom' })
        .setLngLat([marker.lng, marker.lat])
        .addTo(map);

      markersRef.current.push(mbMarker);
      bounds.extend([marker.lng, marker.lat]);
    });

    // Fit bounds with padding
    if (markers.length > 1) {
      map.fitBounds(bounds, { padding: 60, maxZoom: 15 });
    } else {
      map.flyTo({ center: [markers[0]!.lng, markers[0]!.lat], zoom: 14 });
    }
  }, [markers, selectedListingId, onMarkerClick]);

  function showPopup(map: mapboxgl.Map, marker: MapMarker) {
    popupRef.current?.remove();

    const { listing } = marker;
    const imgHtml = listing.property.media.length > 0
      ? `<img src="${listing.property.media[0]!.url}" alt="${listing.property.title}" style="width:100%;height:96px;object-fit:cover;border-radius:6px;margin-bottom:8px;" />`
      : '';

    const popup = new mapboxgl.Popup({ offset: 25, maxWidth: '260px', closeButton: true })
      .setLngLat([marker.lng, marker.lat])
      .setHTML(`
        <div style="font-family:system-ui,sans-serif;">
          ${imgHtml}
          <p style="font-weight:700;color:hsl(142.1,76.2%,36.3%);font-size:14px;margin:0 0 4px;">
            ${formatPrice(listing.priceVND)} VND
          </p>
          <p style="font-size:13px;font-weight:500;margin:0 0 2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">
            ${listing.property.title}
          </p>
          <p style="font-size:12px;color:#666;margin:0 0 8px;">
            ${listing.property.district}, ${listing.property.city}
          </p>
          <div style="display:flex;gap:4px;font-size:11px;margin-bottom:8px;">
            <span style="background:#f1f5f9;padding:2px 6px;border-radius:4px;">${listing.property.areaM2} m\u00B2</span>
            ${listing.property.bedrooms != null ? `<span style="background:#f1f5f9;padding:2px 6px;border-radius:4px;">${listing.property.bedrooms} PN</span>` : ''}
            ${listing.property.bathrooms != null ? `<span style="background:#f1f5f9;padding:2px 6px;border-radius:4px;">${listing.property.bathrooms} WC</span>` : ''}
          </div>
          <a href="/listings/${listing.id}" style="display:block;text-align:center;font-size:12px;font-weight:500;color:hsl(142.1,76.2%,36.3%);text-decoration:none;">
            Xem chi tiet &rarr;
          </a>
        </div>
      `)
      .addTo(map);

    popupRef.current = popup;
  }

  const hasToken = typeof process !== 'undefined' && process.env['NEXT_PUBLIC_MAPBOX_TOKEN'];

  return (
    <div className={`relative overflow-hidden rounded-lg border ${className || 'h-[500px]'}`}>
      <div ref={mapContainerRef} className="h-full w-full" />

      {/* Fallback when no Mapbox token */}
      {!hasToken && (
        <div className="absolute inset-0 flex items-center justify-center bg-gradient-to-b from-blue-50 to-green-50">
          <div className="text-center">
            <svg className="mx-auto mb-2 h-10 w-10 text-muted-foreground" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M9 20l-5.447-2.724A1 1 0 013 16.382V5.618a1 1 0 011.447-.894L9 7m0 13l6-3m-6 3V7m6 10l4.553 2.276A1 1 0 0021 18.382V7.618a1 1 0 00-.553-.894L15 4m0 13V4m0 0L9 7" />
            </svg>
            <p className="text-sm text-muted-foreground">
              Thiết lập NEXT_PUBLIC_MAPBOX_TOKEN để hiển thị bản đồ
            </p>
          </div>
        </div>
      )}

      {/* Listing count overlay */}
      <div className="absolute bottom-3 left-3 rounded bg-white/90 px-2 py-1 text-xs text-muted-foreground shadow">
        {markers.length} bất động sản trên bản đồ
      </div>

      {/* Empty state */}
      {markers.length === 0 && hasToken && (
        <div className="absolute inset-0 flex items-center justify-center bg-white/60">
          <p className="text-muted-foreground">Không có bất động sản để hiển thị trên bản đồ</p>
        </div>
      )}

      <style jsx global>{`
        .mapbox-price-marker span {
          display: block;
          background: white;
          border-radius: 9999px;
          padding: 4px 8px;
          font-size: 12px;
          font-weight: 700;
          box-shadow: 0 1px 4px rgba(0,0,0,0.15);
          white-space: nowrap;
          transition: all 0.15s;
        }
        .mapbox-price-marker:hover span,
        .mapbox-price-marker span.selected {
          background: hsl(142.1, 76.2%, 36.3%);
          color: white;
          transform: scale(1.1);
        }
        .mapboxgl-popup-content {
          border-radius: 8px !important;
          padding: 12px !important;
          box-shadow: 0 4px 12px rgba(0,0,0,0.15) !important;
        }
      `}</style>
    </div>
  );
}
