'use client';

import React, { memo } from 'react';
import {
  ComposableMap,
  Geographies,
  Geography,
  ZoomableGroup,
} from 'react-simple-maps';
import { scaleLinear } from 'd3-scale';

// TopoJSON world map
const geoUrl = 'https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json';

// ISO Alpha-2 to country name mapping for common countries
const countryNameToCode: Record<string, string> = {
  'United States': 'US',
  'USA': 'US',
  'US': 'US',
  'Germany': 'DE',
  'DE': 'DE',
  'United Kingdom': 'GB',
  'UK': 'GB',
  'GB': 'GB',
  'France': 'FR',
  'FR': 'FR',
  'Canada': 'CA',
  'CA': 'CA',
  'Australia': 'AU',
  'AU': 'AU',
  'Japan': 'JP',
  'JP': 'JP',
  'China': 'CN',
  'CN': 'CN',
  'India': 'IN',
  'IN': 'IN',
  'Brazil': 'BR',
  'BR': 'BR',
  'Spain': 'ES',
  'ES': 'ES',
  'Italy': 'IT',
  'IT': 'IT',
  'Netherlands': 'NL',
  'NL': 'NL',
  'Switzerland': 'CH',
  'CH': 'CH',
  'Austria': 'AT',
  'AT': 'AT',
  'Poland': 'PL',
  'PL': 'PL',
  'Sweden': 'SE',
  'SE': 'SE',
  'Norway': 'NO',
  'NO': 'NO',
  'Denmark': 'DK',
  'DK': 'DK',
  'Finland': 'FI',
  'FI': 'FI',
  'Belgium': 'BE',
  'BE': 'BE',
  'Portugal': 'PT',
  'PT': 'PT',
  'Ireland': 'IE',
  'IE': 'IE',
  'Mexico': 'MX',
  'MX': 'MX',
  'Argentina': 'AR',
  'AR': 'AR',
  'South Korea': 'KR',
  'KR': 'KR',
  'Singapore': 'SG',
  'SG': 'SG',
  'New Zealand': 'NZ',
  'NZ': 'NZ',
  'Russia': 'RU',
  'RU': 'RU',
  'South Africa': 'ZA',
  'ZA': 'ZA',
  'Unknown Location': 'UNKNOWN',
  'unknown': 'UNKNOWN',
};

// ISO Alpha-2 to ISO Alpha-3 mapping (for matching with TopoJSON)
const alpha2ToNumeric: Record<string, string> = {
  'US': '840',
  'DE': '276',
  'GB': '826',
  'FR': '250',
  'CA': '124',
  'AU': '036',
  'JP': '392',
  'CN': '156',
  'IN': '356',
  'BR': '076',
  'ES': '724',
  'IT': '380',
  'NL': '528',
  'CH': '756',
  'AT': '040',
  'PL': '616',
  'SE': '752',
  'NO': '578',
  'DK': '208',
  'FI': '246',
  'BE': '056',
  'PT': '620',
  'IE': '372',
  'MX': '484',
  'AR': '032',
  'KR': '410',
  'SG': '702',
  'NZ': '554',
  'RU': '643',
  'ZA': '710',
};

interface CountryStat {
  country: string;
  count: number;
  percentage: number;
}

interface GeoMapProps {
  countryStats: CountryStat[];
  totalScans: number;
}

const GeoMap: React.FC<GeoMapProps> = ({ countryStats, totalScans }) => {
  // Build a map of ISO Alpha-3 codes to scan counts
  const countryData: Record<string, number> = {};
  let maxCount = 0;

  countryStats.forEach((stat) => {
    const alpha2 = countryNameToCode[stat.country] || stat.country;
    const numericCode = alpha2ToNumeric[alpha2];
    if (numericCode) {
      countryData[numericCode] = stat.count;
      if (stat.count > maxCount) maxCount = stat.count;
    }
  });

  // Color scale: light blue to dark blue based on scan count
  const colorScale = scaleLinear<string>()
    .domain([0, maxCount || 1])
    .range(['#E0F2FE', '#1E40AF']);

  const [tooltipContent, setTooltipContent] = React.useState<{ name: string; count: number } | null>(null);
  const [tooltipPos, setTooltipPos] = React.useState({ x: 0, y: 0 });

  return (
    <div
      className="w-full h-full relative group"
      onMouseMove={(evt) => {
        setTooltipPos({ x: evt.clientX, y: evt.clientY });
      }}
    >
      <ComposableMap
        projection="geoMercator"
        projectionConfig={{
          scale: 120,
          center: [0, 30],
        }}
        style={{ width: '100%', height: '100%' }}
      >
        <ZoomableGroup center={[0, 30]} zoom={1}>
          <Geographies geography={geoUrl}>
            {({ geographies }) =>
              geographies.map((geo) => {
                // geo.id is the numeric ISO code as a string (e.g., "840" for US)
                const geoId = geo.id;
                const scanCount = countryData[geoId] || 0;
                const fillColor = scanCount > 0 ? colorScale(scanCount) : '#F1F5F9';

                return (
                  <Geography
                    key={geo.rsmKey}
                    geography={geo}
                    fill={fillColor}
                    stroke="#CBD5E1"
                    strokeWidth={0.5}
                    style={{
                      default: { outline: 'none' },
                      hover: {
                        fill: scanCount > 0 ? '#3B82F6' : '#E2E8F0',
                        outline: 'none',
                        cursor: 'pointer',
                      },
                      pressed: { outline: 'none' },
                    }}
                    onMouseEnter={() => {
                      const { name } = geo.properties;
                      setTooltipContent({ name, count: scanCount });
                    }}
                    onMouseLeave={() => {
                      setTooltipContent(null);
                    }}
                  />
                );
              })
            }
          </Geographies>
        </ZoomableGroup>
      </ComposableMap>

      {tooltipContent && (
        <div
          className="fixed z-50 px-3 py-2 text-sm font-medium text-white bg-gray-900 rounded-lg shadow-xl pointer-events-none transform -translate-x-1/2 -translate-y-full"
          style={{
            left: tooltipPos.x,
            top: tooltipPos.y - 10,
          }}
        >
          <div className="flex items-center gap-2">
            <span>{tooltipContent.name}</span>
            <span className="text-gray-400">|</span>
            <span className="font-bold text-blue-400">{tooltipContent.count} scans</span>
          </div>
          {/* Arrow */}
          <div className="absolute bottom-0 left-1/2 -translate-x-1/2 translate-y-full w-0 h-0 border-l-4 border-r-4 border-t-4 border-l-transparent border-r-transparent border-t-gray-900"></div>
        </div>
      )}
    </div>
  );
};

export default memo(GeoMap);
