import { AFRICA_MAP_REGION_CODES } from '@admin/lib/africa-map-regions';
import { countryMarkerColor } from '@admin/lib/country-marker-colors';
import { countryMarkerCoords } from '@admin/lib/country-map-centroids';
import type { DashboardClientsByCountry } from '@admin/types/dashboard';
import { ensureDashboardChartScripts } from '@admin/lib/load-dashboard-chart-scripts';
import { useEffect, useMemo, useRef } from 'react';

declare global {
    interface Window {
        jsVectorMap?: new (options: Record<string, unknown>) => {
            destroy?: () => void;
            setFocus?: (options: Record<string, unknown>) => void;
        };
    }
}

type ClientsWorldMapProps = {
    clientsByCountry: DashboardClientsByCountry;
};

type MapMarker = {
    name: string;
    coords: [number, number];
    count: number;
    iso: string;
    color: string;
};

function buildMarkers(rows: DashboardClientsByCountry['rows']): MapMarker[] {
    return rows
        .filter((row) => row.iso !== null)
        .map((row) => {
            const coords = countryMarkerCoords(row.iso as string);

            if (!coords) {
                return null;
            }

            return {
                name: `${row.country} (${row.total})`,
                coords,
                count: row.total,
                iso: row.iso as string,
                color: countryMarkerColor(row.country),
            };
        })
        .filter((marker): marker is MapMarker => marker !== null);
}

function africaFocusRegions(markers: MapMarker[]): string[] {
    const withClients = markers.map((marker) => marker.iso);

    return withClients.length > 0 ? withClients : [...AFRICA_MAP_REGION_CODES];
}

export function ClientsWorldMap({ clientsByCountry }: ClientsWorldMapProps) {
    const mapRef = useRef<HTMLDivElement>(null);
    const markers = useMemo(() => buildMarkers(clientsByCountry.rows), [clientsByCountry.rows]);
    const hasMapData = markers.length > 0;

    useEffect(() => {
        const element = mapRef.current;
        if (!element || !hasMapData) {
            return;
        }

        let mapInstance: { destroy?: () => void } | null = null;
        let cancelled = false;

        ensureDashboardChartScripts()
            .then(() => {
                if (cancelled || !window.jsVectorMap) {
                    return;
                }

                element.innerHTML = '';

                const focusRegions = africaFocusRegions(markers);

                mapInstance = new window.jsVectorMap({
                    selector: element,
                    map: 'world_merc',
                    backgroundColor: 'transparent',
                    zoomButtons: true,
                    zoomOnScroll: true,
                    focusOn: {
                        regions: focusRegions,
                        animate: true,
                    },
                    regionStyle: {
                        initial: {
                            fill: '#e9edf6',
                            stroke: '#dde4ef',
                            strokeWidth: 0.6,
                        },
                        hover: {
                            fill: '#d1dae5',
                        },
                    },
                    markers: markers.map((marker) => ({
                        name: marker.name,
                        coords: marker.coords,
                        style: {
                            fill: marker.color,
                            stroke: '#fff',
                            strokeWidth: 2,
                            r: 7,
                        },
                    })),
                    markerStyle: {
                        initial: {
                            r: 7,
                            stroke: '#fff',
                            strokeWidth: 2,
                            fillOpacity: 1,
                        },
                        hover: {
                            stroke: '#fff',
                            strokeWidth: 2,
                        },
                    },
                    labels: {
                        markers: {
                            render: () => '',
                        },
                    },
                    onMarkerTooltipShow(
                        event: { tooltip: { text: (value: string) => void } },
                        index: number,
                    ) {
                        const marker = markers[index];
                        if (!marker) {
                            return;
                        }

                        event.tooltip.text(
                            `${marker.name}: ${marker.count} client${marker.count === 1 ? '' : 's'}`,
                        );
                    },
                });
            })
            .catch((error) => {
                console.error('[Dashboard client map]', error);
            });

        return () => {
            cancelled = true;
            mapInstance?.destroy?.();
            element.innerHTML = '';
        };
    }, [clientsByCountry, hasMapData, markers]);

    if (!hasMapData) {
        return (
            <p className="text-sm text-gray-500 dark:text-white/70 py-16 text-center">
                Add clients with recognizable country names (e.g. Kenya, Uganda) to show locations on the map.
            </p>
        );
    }

    return <div ref={mapRef} id="dashboard-clients-map" className="h-96 w-full min-h-[24rem]" />;
}
