'use client';

import { useEffect, useMemo } from 'react';
import { MapContainer as LeafletMapContainer, TileLayer, Marker, Popup, Polyline, useMap, useMapEvents } from 'react-leaflet';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';

interface JourneyMapStop {
    id: string;
    title: string;
    locationName?: string | null;
    latitude?: number | null;
    longitude?: number | null;
    order: number;
}

interface JourneyMapProps {
    stops: JourneyMapStop[];
    onMapClick?: (lat: number, lng: number) => void;
    onStopClick?: (stopId: string) => void;
    interactive?: boolean;
    className?: string;
    height?: string;
}

// Warm-toned numbered marker
function createStopIcon(index: number) {
    return L.divIcon({
        className: 'journey-stop-marker',
        html: `<div style="
            background: #8B7355;
            color: white;
            width: 28px;
            height: 28px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 13px;
            font-weight: 600;
            font-family: 'Lora', serif;
            border: 2px solid #f0e6d2;
            box-shadow: 0 2px 6px rgba(44,24,16,0.3);
        ">${index + 1}</div>`,
        iconSize: [28, 28],
        iconAnchor: [14, 14],
        popupAnchor: [0, -16],
    });
}

// Click handler component
function MapClickHandler({ onClick }: { onClick: (lat: number, lng: number) => void }) {
    useMapEvents({
        click(e) {
            onClick(e.latlng.lat, e.latlng.lng);
        },
    });
    return null;
}

// Fit bounds component
function FitBounds({ stops }: { stops: JourneyMapStop[] }) {
    const map = useMap();

    useEffect(() => {
        const locatedStops = stops.filter(s => s.latitude != null && s.longitude != null);
        if (locatedStops.length > 0) {
            const bounds = L.latLngBounds(
                locatedStops.map(s => [s.latitude!, s.longitude!] as [number, number])
            );
            map.fitBounds(bounds, { padding: [50, 50], maxZoom: 12 });
        }
    }, [map, stops]);

    return null;
}

export default function JourneyMap({
    stops,
    onMapClick,
    onStopClick,
    interactive = false,
    className = '',
    height = '300px',
}: JourneyMapProps) {
    const locatedStops = useMemo(
        () => stops.filter(s => s.latitude != null && s.longitude != null).sort((a, b) => a.order - b.order),
        [stops]
    );

    const center = useMemo<[number, number]>(() => {
        if (locatedStops.length === 0) return [40, 0];
        const avgLat = locatedStops.reduce((sum, s) => sum + s.latitude!, 0) / locatedStops.length;
        const avgLng = locatedStops.reduce((sum, s) => sum + s.longitude!, 0) / locatedStops.length;
        return [avgLat, avgLng];
    }, [locatedStops]);

    // Route polyline coordinates
    const routeCoords = useMemo(
        () => locatedStops.map(s => [s.latitude!, s.longitude!] as [number, number]),
        [locatedStops]
    );

    return (
        <LeafletMapContainer
            center={center}
            zoom={locatedStops.length > 0 ? 6 : 3}
            scrollWheelZoom={true}
            className={`w-full rounded-xl shadow-lg ${className}`}
            style={{ height, minHeight: '200px' }}
        >
            <TileLayer
                attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
                url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
            />
            <FitBounds stops={locatedStops} />

            {interactive && onMapClick && <MapClickHandler onClick={onMapClick} />}

            {/* Route line */}
            {routeCoords.length > 1 && (
                <Polyline
                    positions={routeCoords}
                    pathOptions={{
                        color: '#8B7355',
                        weight: 2,
                        dashArray: '8, 8',
                        opacity: 0.7,
                    }}
                />
            )}

            {/* Stop markers */}
            {locatedStops.map((stop, idx) => (
                <Marker
                    key={stop.id}
                    position={[stop.latitude!, stop.longitude!]}
                    icon={createStopIcon(idx)}
                    eventHandlers={onStopClick ? {
                        click: () => onStopClick(stop.id),
                    } : {}}
                >
                    <Popup minWidth={150}>
                        <div className="font-serif">
                            <p className="font-semibold text-sm">{stop.title}</p>
                            {stop.locationName && (
                                <p className="text-xs text-zinc-500 mt-0.5">{stop.locationName}</p>
                            )}
                        </div>
                    </Popup>
                </Marker>
            ))}
        </LeafletMapContainer>
    );
}
