import { useEffect, useState } from 'react';
import { LoaderCircle, MapPin } from 'lucide-react';
import { useCurrentLocation } from '@/hooks/use-current-location';
import { fetchPlacePhotoUrl, nearbyPopularPlaces, routeMetrics, type PopularPlace, type RouteMetrics } from '@/lib/google-maps';
import type { RoutePrefill } from '@/types/booking';

export default function NearbyRoutes({ onPrefill }: { onPrefill: (value: RoutePrefill) => void }) {
    const { locate, status } = useCurrentLocation();
    const [places, setPlaces] = useState<PopularPlace[]>([]);
    const [placeMetrics, setPlaceMetrics] = useState<Record<string, RouteMetrics>>({});
    const [placePhotos, setPlacePhotos] = useState<Record<string, string>>({});
    const [locationLabel, setLocationLabel] = useState('your current location');
    const [locationCoords, setLocationCoords] = useState({ lat: 0, lng: 0 });
    const [message, setMessage] = useState('');

    const findRoutes = async () => {
        setMessage('');
        const current = await locate();
        if (!current || current.lat === null || current.lng === null) {
            setMessage('Allow location access to see airports and stations near you.');
            return;
        }
        setLocationLabel(current.address);
        setLocationCoords({ lat: current.lat, lng: current.lng });

        try {
            const popularPlaces = await nearbyPopularPlaces(current.lat, current.lng);
            const metrics = await Promise.all(popularPlaces.map(async (place) => [
                place.id,
                await routeMetrics({ lat: current.lat as number, lng: current.lng as number }, { lat: place.lat, lng: place.lng }),
            ] as const));
            setPlaces(popularPlaces);
            setPlaceMetrics(Object.fromEntries(metrics));
            const photoEntries = await Promise.all(
                popularPlaces.map(async (place) => [
                    place.id,
                    await fetchPlacePhotoUrl(place.id, place.photoName),
                ] as const),
            );
            setPlacePhotos(
                Object.fromEntries(
                    photoEntries.filter((entry): entry is [string, string] => Boolean(entry[1])),
                ),
            );
            if (popularPlaces.length === 0) setMessage('No popular places were found nearby.');
        } catch {
            setMessage('Nearby routes are temporarily unavailable. Please try again.');
        }
    };

    useEffect(() => {
        void findRoutes();
        // Location is requested once when this section mounts.
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

    return (
        <section className="border-y border-navy/10 bg-white/70 py-12 dark:border-white/10 dark:bg-white/5 lg:py-16">
            <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-10">
                {status === 'locating' && places.length === 0 ? (
                    <div className="mt-8 flex items-center gap-3 rounded-xl bg-mist p-5 text-sm text-navy/70 dark:bg-white/10 dark:text-white/70"><LoaderCircle className="size-5 animate-spin text-gold" /> Finding popular places near you…</div>
                ) : message ? (
                    <div className="mt-8 rounded-xl bg-mist p-5 text-sm text-navy/70 dark:bg-white/10 dark:text-white/70">{message} {status !== 'denied' && <button type="button" onClick={() => void findRoutes()} className="font-semibold text-gold-dark underline">Try again</button>}</div>
                ) : null}

                {places.length > 0 && (
                    <div className="mt-8">
                        <div>
                            <p className="text-xs font-bold tracking-[0.2em] text-gold-dark uppercase">Explore nearby</p>
                            <h3 className="mt-2 font-google text-2xl font-semibold text-navy sm:text-3xl dark:text-white">Popular places around you</h3>
                            <p className="mt-2 text-sm text-gray-500 dark:text-white/70">Famous attractions and local highlights discovered through Google Maps.</p>
                        </div>
                        <div className="mt-7 grid gap-5 sm:grid-cols-2 lg:grid-cols-4">
                            {places.map((place) => {
                                const metrics = placeMetrics[place.id];
                                return <article key={place.id} className="overflow-hidden rounded-xl bg-white shadow-[0_8px_30px_-12px_rgba(11,31,51,0.18)] dark:bg-ocean">
                                    <div className="aspect-[16/10] overflow-hidden bg-navy/10"><img src={placePhotos[place.id] ?? '/images/hero-bg.png'} alt={place.name} loading="lazy" className="size-full object-cover transition-transform duration-500 hover:scale-105" /></div>
                                    <div className="p-5"><p className="text-[11px] font-bold tracking-wide text-gold-dark uppercase">{place.category}</p><h4 className="mt-1 font-semibold text-navy dark:text-white">{place.name}</h4><p className="mt-2 line-clamp-2 text-xs text-navy/60 dark:text-white/60">{place.address}</p><div className="mt-3 flex items-center justify-between gap-2 text-xs"><span className="font-semibold text-amber-600">★ {place.rating?.toFixed(1) ?? 'New'}{place.ratingCount ? ` (${place.ratingCount.toLocaleString()})` : ''}</span>{metrics && <span className="text-navy/60 dark:text-white/60">{metrics.distance} · {metrics.duration}</span>}</div><button type="button" onClick={() => onPrefill({ routeId: null, origin: locationLabel, destination: place.name, originLat: locationCoords.lat, originLng: locationCoords.lng, destinationLat: place.lat, destinationLng: place.lng })} className="mt-4 text-xs font-semibold text-navy underline underline-offset-2 hover:text-gold-dark dark:text-white">Plan a ride here</button></div>
                                </article>;
                            })}
                        </div>
                    </div>
                )}
            </div>
        </section>
    );
}
