import { useEffect, useState, useRef } from 'react';
import { MapContainer, TileLayer, Marker, Popup, useMap } from 'react-leaflet';
import MarkerClusterGroup from 'react-leaflet-cluster';
import { DivIcon } from 'leaflet';
import { type ExploreItem, type MapBounds } from '@/types/explore';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { MapPin, Heart, MessageCircle, Loader2, ExternalLink, Eye, Star } from 'lucide-react';
import { cn } from '@/lib/utils';
import { useLaravelReactI18n } from 'laravel-react-i18n';
import 'leaflet/dist/leaflet.css';

// Inject custom CSS to remove Leaflet popup default margins
if (typeof document !== 'undefined') {
    const style = document.createElement('style');
    style.textContent = `
        .leaflet-popup-content-wrapper {
            padding: 0 !important;
            border-radius: 1rem !important;
            overflow: hidden !important;
        }
        .leaflet-popup-content {
            margin: 0 !important;
            padding: 0 !important;
            width: 340px !important;
        }
        .leaflet-popup-tip-container {
            display: none !important;
        }
    `;
    if (!document.querySelector('#leaflet-popup-custom-styles')) {
        style.id = 'leaflet-popup-custom-styles';
        document.head.appendChild(style);
    }
}

interface ExploreMapProps {
    items: ExploreItem[];
    selectedItemId: number | null;
    hoveredItemId: number | null;
    isVisible: boolean;
    onBoundsChange: (bounds: MapBounds) => void;
    onMarkerClick: (id: number) => void;
    onMarkerHover: (id: number | null) => void;
}

// Create circular image marker icon
const createImageIcon = (imageUrl: string | null, type: 'experience' | 'poi', isHovered: boolean = false): DivIcon => {
    const borderColor = type === 'experience' ? '#16a34a' : '#9333ea';
    const fallbackBg = type === 'experience' ? 'bg-green-600' : 'bg-purple-600';

    // Add pulsing animation and glowing border when hovered
    const hoverStyles = isHovered
        ? `
            border: 4px solid #3b82f6 !important;
            box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.3), 0 4px 12px rgba(0,0,0,0.4) !important;
            transform: scale(1.15);
            z-index: 10000 !important;
          `
        : '';

    const html = imageUrl
        ? `<div style="
            width: 48px;
            height: 48px;
            border-radius: 50%;
            border: 3px solid ${borderColor};
            box-shadow: 0 4px 12px rgba(0,0,0,0.3);
            background: white;
            overflow: hidden;
            background-image: url('${imageUrl}');
            background-size: cover;
            background-position: center;
            cursor: pointer;
            transition: all 0.2s ease;
            ${hoverStyles}
          "></div>`
        : `<div style="
            width: 48px;
            height: 48px;
            border-radius: 50%;
            border: 3px solid ${borderColor};
            box-shadow: 0 4px 12px rgba(0,0,0,0.3);
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 24px;
            transition: all 0.2s ease;
            ${hoverStyles}
          " class="${fallbackBg}">📍</div>`;

    return new DivIcon({
        html,
        className: 'custom-marker-icon',
        iconSize: [48, 48],
        iconAnchor: [24, 24],
        popupAnchor: [0, -24],
    });
};

// Component to handle map bounds changes
function BoundsHandler({ onBoundsChange }: { onBoundsChange: (bounds: MapBounds) => void }) {
    const map = useMap();
    const onBoundsChangeRef = useRef(onBoundsChange);

    // Update ref when callback changes to avoid stale closures
    useEffect(() => {
        onBoundsChangeRef.current = onBoundsChange;
    }, [onBoundsChange]);

    useEffect(() => {
        const handleMoveEnd = () => {
            const bounds = map.getBounds();
            onBoundsChangeRef.current({
                south: bounds.getSouth(),
                west: bounds.getWest(),
                north: bounds.getNorth(),
                east: bounds.getEast(),
            });
        };

        map.on('moveend', handleMoveEnd);

        return () => {
            map.off('moveend', handleMoveEnd);
        };
    }, [map]);

    return null;
}

// Component to highlight selected marker and zoom to it when hovering card
function MarkerHighlighter({ hoveredItemId, items }: { hoveredItemId: number | null; items: ExploreItem[] }) {
    const map = useMap();
    const previousHoveredIdRef = useRef<number | null>(null);

    useEffect(() => {
        // Only pan if the hovered item actually changed
        if (hoveredItemId && hoveredItemId !== previousHoveredIdRef.current) {
            const item = items.find((i) => i.id === hoveredItemId);
            if (item && item.latitude && item.longitude) {
                // Just pan to the marker without changing zoom to avoid refetching data
                map.panTo([item.latitude, item.longitude], { animate: true, duration: 0.5 });
            }
        }
        previousHoveredIdRef.current = hoveredItemId;
    }, [hoveredItemId, items, map]);

    return null;
}

// Loading overlay component
function MapLoadingOverlay({ isLoading }: { isLoading: boolean }) {
    if (!isLoading) return null;

    return (
        <div className="absolute inset-0 bg-background/50 backdrop-blur-sm z-[1000] flex items-center justify-center">
            <div className="bg-white dark:bg-gray-900 rounded-lg shadow-xl p-6 flex flex-col items-center gap-3">
                <Loader2 className="h-8 w-8 animate-spin text-blue-600" />
                <p className="text-sm font-medium text-muted-foreground">Loading map data...</p>
            </div>
        </div>
    );
}

// Component to fix map size when toggling visibility
function MapSizeInvalidator({ isVisible }: { isVisible: boolean }) {
    const map = useMap();
    const prevVisibleRef = useRef(isVisible);

    useEffect(() => {
        // Run on mount or when visibility changes to true
        if (isVisible && (!prevVisibleRef.current || prevVisibleRef.current !== isVisible)) {
            // Force recalculate map size
            map.invalidateSize(true);
        }
        prevVisibleRef.current = isVisible;
    }, [isVisible, map]);

    // Also run on mount to handle initial render
    useEffect(() => {
        map.invalidateSize(true);
    }, [map]);

    return null;
}

// Popup content component
function PopupContent({ item }: { item: ExploreItem }) {
    const { t } = useLaravelReactI18n();

    const handleViewDetails = () => {
        const url = item.type === 'experience'
            ? `/experiences/${item.id}`
            : `/points-of-interest/${item.id}`;
        window.location.href = url;
    };

    const typeColor = item.type === 'experience' ? 'text-green-600' : 'text-purple-600';
    const typeBg = item.type === 'experience' ? 'bg-green-50 dark:bg-green-950' : 'bg-purple-50 dark:bg-purple-950';
    const typeLabel = item.type === 'experience' ? t('Experience') : t('Place');

    return (
        <div className="w-full m-0">
            {/* Image */}
            {item.image_url && (
                <div className="relative aspect-[4/3] overflow-hidden bg-muted">
                    <img
                        src={item.image_url}
                        alt={item.title}
                        className="h-full w-full object-cover"
                    />

                    {/* Type Badge */}
                    <div className="absolute top-3 right-3">
                        <Badge className={cn("border-0", typeBg, typeColor)}>
                            {typeLabel}
                        </Badge>
                    </div>

                    {/* Featured Badge */}
                    {item.is_featured && (
                        <div className="absolute top-3 left-3">
                            <Badge className="bg-gradient-to-r from-blue-600 to-purple-600 text-white border-0">
                                <Star className="h-3 w-3 mr-1" />
                                {t('Featured')}
                            </Badge>
                        </div>
                    )}
                </div>
            )}

            {/* Content */}
            <div className="p-4">
                {/* Category/User */}
                {item.type === 'poi' && item.category && (
                    <Badge variant="secondary" className="mb-2 text-xs">
                        {item.category.name}
                    </Badge>
                )}
                {item.type === 'experience' && item.user && (
                    <p className="text-xs text-muted-foreground mb-2">
                        {t('by')} {item.user.full_name}
                    </p>
                )}

                {/* Title */}
                <h3 className="font-semibold text-lg mb-2 line-clamp-2">
                    {item.title}
                </h3>

                {/* Description */}
                <p className="text-sm text-muted-foreground mb-3 line-clamp-2">
                    {item.description}
                </p>

                {/* Location */}
                {item.location && (
                    <div className="flex items-center text-sm text-muted-foreground mb-3">
                        <MapPin className="h-4 w-4 mr-1 flex-shrink-0" />
                        <span className="truncate">{item.location}</span>
                    </div>
                )}

                {/* Stats */}
                <div className="flex items-center gap-4 text-xs text-muted-foreground mb-4">
                    <div className="flex items-center gap-1">
                        <Heart className="h-3 w-3" />
                        <span>{item.likes_count}</span>
                    </div>
                    <div className="flex items-center gap-1">
                        <MessageCircle className="h-3 w-3" />
                        <span>{item.comments_count}</span>
                    </div>
                    <div className="flex items-center gap-1">
                        <Eye className="h-3 w-3" />
                        <span>{item.views_count}</span>
                    </div>
                    <span className="ml-auto">{item.time_ago}</span>
                </div>

                {/* View Details Button */}
                <Button
                    onClick={handleViewDetails}
                    className="w-full bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-700 hover:to-purple-700 text-white shadow-lg"
                    size="sm"
                >
                    <ExternalLink className="h-4 w-4 mr-2" />
                    {t('View Details')}
                </Button>
            </div>
        </div>
    );
}

export default function ExploreMap({
    items,
    selectedItemId,
    hoveredItemId,
    isVisible,
    onBoundsChange,
    onMarkerClick,
    onMarkerHover,
}: ExploreMapProps) {
    const [isLoading, setIsLoading] = useState(true);

    // Filter items with valid coordinates
    const validItems = items.filter(item => item.latitude && item.longitude);

    // Default center (Romania center as fallback)
    const defaultCenter: [number, number] = [45.9432, 24.9668];
    const center = validItems.length > 0 && validItems[0].latitude && validItems[0].longitude
        ? [validItems[0].latitude, validItems[0].longitude] as [number, number]
        : defaultCenter;

    // Handle map loading
    useEffect(() => {
        setIsLoading(true);
        const timer = setTimeout(() => {
            setIsLoading(false);
        }, 500);
        return () => clearTimeout(timer);
    }, [items]);

    return (
        <div className="h-full relative">
            <MapLoadingOverlay isLoading={isLoading} />
            <MapContainer
                center={center}
                zoom={15}
                className="h-full w-full"
                scrollWheelZoom={true}
            >
                <TileLayer
                    attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
                    url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                />

                <BoundsHandler onBoundsChange={onBoundsChange} />
                <MarkerHighlighter hoveredItemId={hoveredItemId} items={validItems} />
                <MapSizeInvalidator isVisible={isVisible} />

                <MarkerClusterGroup
                    chunkedLoading
                    iconCreateFunction={(cluster: any) => {
                        const count = cluster.getChildCount();
                        const size = count < 10 ? 'small' : count < 50 ? 'medium' : 'large';
                        const dimensions = size === 'small' ? 40 : size === 'medium' ? 50 : 60;

                        return new DivIcon({
                            html: `<div style="
                                width: ${dimensions}px;
                                height: ${dimensions}px;
                                border-radius: 50%;
                                background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
                                border: 3px solid white;
                                box-shadow: 0 4px 12px rgba(0,0,0,0.3);
                                display: flex;
                                align-items: center;
                                justify-content: center;
                                color: white;
                                font-weight: bold;
                                font-size: ${size === 'small' ? '14px' : size === 'medium' ? '16px' : '18px'};
                                cursor: pointer;
                            ">${count}</div>`,
                            className: 'custom-cluster-icon',
                            iconSize: [dimensions, dimensions],
                            iconAnchor: [dimensions / 2, dimensions / 2],
                        });
                    }}
                >
                    {validItems.map((item) => (
                        <Marker
                            key={`${item.type}-${item.id}`}
                            position={[item.latitude!, item.longitude!]}
                            icon={createImageIcon(item.image_url, item.type, hoveredItemId === item.id)}
                            eventHandlers={{
                                mouseover: () => onMarkerHover(item.id),
                                mouseout: () => onMarkerHover(null),
                                click: () => onMarkerClick(item.id),
                            }}
                        >
                            <Popup closeButton={false} minWidth={340} maxWidth={340}>
                                <PopupContent item={item} />
                            </Popup>
                        </Marker>
                    ))}
                </MarkerClusterGroup>
            </MapContainer>
        </div>
    );
}
