import React, { useMemo, useState, useEffect } from 'react';
import {
  Box,
  Card,
  CardBody,
  CardHeader,
  Flex,
  Heading,
  Skeleton,
  Text,
  useColorModeValue,
  VStack,
  Tooltip,
  Icon,
} from '@chakra-ui/react';
import { FaInfoCircle } from 'react-icons/fa';
import { ComposableMap, Geographies, Geography } from 'react-simple-maps';
import type { Feature } from 'geojson';
import { useClubTheme } from '../../contexts/ClubThemeContext';

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

type CountryDatum = {
  code: string;
  value: number;
  name?: string | null;
};

type VisitorCountriesMapProps = {
  title?: string;
  metrics: CountryDatum[];
  isLoading?: boolean;
  height?: number;
  onCountryClick?: (countryCode: string, countryName: string, value: number) => void;
  clearSelection?: boolean;
};

type HoverState = {
  name: string;
  value: number;
};

type ClickedState = {
  name: string;
  value: number;
  code: string;
};

const mixChannel = (start: number, end: number, factor: number) => {
  return Math.round(start + (end - start) * factor);
};

const hexToRgb = (hex: string) => {
  const normalized = hex.replace('#', '');
  const bigint = parseInt(normalized, 16);
  return {
    r: (bigint >> 16) & 255,
    g: (bigint >> 8) & 255,
    b: bigint & 255,
  };
};

const interpolateColor = (startHex: string, endHex: string, factor: number) => {
  const start = hexToRgb(startHex);
  const end = hexToRgb(endHex);
  const clamped = Math.min(Math.max(factor, 0), 1);

  const r = mixChannel(start.r, end.r, clamped);
  const g = mixChannel(start.g, end.g, clamped);
  const b = mixChannel(start.b, end.b, clamped);

  return `rgb(${r}, ${g}, ${b})`;
};

const getDisplayNames = () => {
  if (typeof Intl !== 'undefined' && typeof (Intl as any).DisplayNames === 'function') {
    try {
      return new Intl.DisplayNames(['cs', 'en'], { type: 'region' });
    } catch (error) {
      // Some browsers might throw when the locale is unsupported
      return new Intl.DisplayNames(['en'], { type: 'region' });
    }
  }
  return null;
};

export const VisitorCountriesMap: React.FC<VisitorCountriesMapProps> = ({
  title = 'Mapa návštěvníků podle země',
  metrics = [],
  isLoading = false,
  height = 400,
  onCountryClick,
  clearSelection = false,
}) => {
  const [hovered, setHovered] = useState<HoverState | null>(null);
  const [clicked, setClicked] = useState<ClickedState | null>(null);
  const displayNames = useMemo(getDisplayNames, []);
  const numberFormatter = useMemo(() => new Intl.NumberFormat('cs-CZ'), []);
  const clubTheme = useClubTheme();

  // Clear selection when clearSelection prop changes
  useEffect(() => {
    if (clearSelection) {
      setClicked(null);
    }
  }, [clearSelection]);

  const dataMap = useMemo(() => {
    const map = new Map<string, { value: number; name: string }>();

    metrics.forEach((item) => {
      if (!item?.code || typeof item.value !== 'number') return;
      const normalizedCode = item.code.toUpperCase();
      const fallbackName = item.name ||
        (normalizedCode.length === 2 ? displayNames?.of(normalizedCode) ?? normalizedCode : normalizedCode);

      map.set(normalizedCode, {
        value: item.value,
        name: fallbackName || normalizedCode,
      });
    });

    return map;
  }, [metrics, displayNames]);

  const maxValue = useMemo(() => {
    let max = 0;
    dataMap.forEach(({ value }) => {
      if (value > max) max = value;
    });
    return max;
  }, [dataMap]);

  const borderColor = useColorModeValue('gray.200', 'gray.700');
  const defaultFill = useColorModeValue('#EDF2F7', '#2D3748');
  
  // Use club colors for the map gradient
  const startFill = useColorModeValue(
    hexToRgb(clubTheme.primary).r > 200 ? clubTheme.secondary : clubTheme.primary,
    clubTheme.primary
  );
  const endFill = useColorModeValue(
    clubTheme.accent || clubTheme.primary,
    clubTheme.secondary || clubTheme.primary
  );
  
  const tooltipBg = useColorModeValue('white', 'gray.800');
  const tooltipBorder = useColorModeValue('gray.200', 'gray.600');
  // Enhanced border color for better visibility
  const countryBorderColor = useColorModeValue('#CBD5E0', '#4A5568');
  const hoveredBorderColor = clubTheme.secondary || '#F6AD55';

  const getDatumForGeo = (geo: Feature) => {
    const properties = (geo.properties || {}) as Record<string, any>;
    const iso2 = (properties.ISO_A2 || properties.iso_a2 || '').toUpperCase();
    const iso3 = (properties.ISO_A3 || properties.iso_a3 || '').toUpperCase();
    return (iso2 && dataMap.get(iso2)) || (iso3 && dataMap.get(iso3)) || null;
  };

  const getFillForDatum = (datum: { value: number } | null, isHovered: boolean = false, isClicked: boolean = false) => {
    if (!datum || maxValue <= 0) return defaultFill;
    const ratio = datum.value / maxValue;
    const baseColor = interpolateColor(startFill, endFill, ratio);
    
    // Enhanced visual feedback
    if (isClicked) {
      // Make clicked country more prominent
      const rgb = hexToRgb(baseColor.startsWith('#') ? baseColor : '#000000');
      return `rgb(${Math.min(rgb.r + 50, 255)}, ${Math.min(rgb.g + 50, 255)}, ${Math.min(rgb.b + 50, 255)})`;
    } else if (isHovered) {
      // Brighten on hover
      const rgb = hexToRgb(baseColor.startsWith('#') ? baseColor : '#000000');
      return `rgb(${Math.min(rgb.r + 30, 255)}, ${Math.min(rgb.g + 30, 255)}, ${Math.min(rgb.b + 30, 255)})`;
    }
    
    return baseColor;
  };

  const hasData = metrics?.some((item) => item.value > 0);

  return (
    <Card borderColor={borderColor} overflow="hidden">
      <CardHeader>
        <Flex align="center" justify="space-between">
          <Heading size="md">{title}</Heading>
          <Tooltip 
            label="Klikněte na zemi pro zobrazení detailních analytických dat"
            placement="top"
            hasArrow
          >
            <Icon as={FaInfoCircle} color="gray.400" cursor="help" />
          </Tooltip>
        </Flex>
      </CardHeader>
      <CardBody>
        {isLoading ? (
          <Skeleton height={`${height}px`} borderRadius="md" />
        ) : !hasData ? (
          <Box textAlign="center" py={12} color="gray.500">
            <Text>Pro vybraný rozsah nejsou k dispozici data o zemích návštěvníků.</Text>
          </Box>
        ) : (
          <Box 
            position="relative" 
            width="100%" 
            overflow="hidden"
            borderRadius="md"
            boxShadow="sm"
            transition="all 0.3s ease-in-out"
            _hover={{
              boxShadow: 'md',
            }}
          >
            <ComposableMap
              projectionConfig={{
                scale: 150,
                center: [0, 20],
              }}
              height={height}
              width={800}
              style={{
                width: '100%',
                height: 'auto',
                filter: 'drop-shadow(0 2px 4px rgba(0,0,0,0.1))',
              }}
            >
              <Geographies geography={GEO_URL}>
                {({ geographies }: { geographies: Feature[] }) =>
                  geographies.map((geo: Feature) => {
                    const datum = getDatumForGeo(geo);
                    const properties = (geo.properties || {}) as Record<string, any>;
                    const countryCode = (properties.ISO_A2 || properties.iso_a2 || '').toUpperCase();
                    const isHovered = hovered?.name === datum?.name;
                    const isClicked = clicked?.code === countryCode;
                    const hasData = datum !== null;
                    
                    return (
                      <Geography
                        key={geo.rsmKey}
                        geography={geo}
                        stroke={isClicked ? clubTheme.primary : (isHovered ? hoveredBorderColor : countryBorderColor)}
                        strokeWidth={isClicked ? 2.5 : (isHovered ? 1.5 : 0.7)}
                        fill={getFillForDatum(datum, isHovered, isClicked)}
                        style={{
                          default: {
                            outline: 'none',
                            cursor: hasData ? 'pointer' : 'default',
                            transition: 'all 0.2s ease-in-out',
                          },
                          hover: {
                            outline: 'none',
                            cursor: hasData ? 'pointer' : 'default',
                            transition: 'all 0.2s ease-in-out',
                          },
                          pressed: {
                            outline: 'none',
                            cursor: hasData ? 'pointer' : 'default',
                            transition: 'all 0.2s ease-in-out',
                          },
                        }}
                        onMouseEnter={() => {
                          if (!datum) {
                            setHovered(null);
                            return;
                          }
                          setHovered({
                            name: datum.name,
                            value: datum.value,
                          });
                        }}
                        onMouseLeave={() => setHovered(null)}
                        onClick={() => {
                          if (datum && onCountryClick) {
                            setClicked({
                              name: datum.name,
                              value: datum.value,
                              code: countryCode,
                            });
                            onCountryClick(countryCode, datum.name, datum.value);
                          }
                        }}
                      />
                    );
                  })
                }
              </Geographies>
            </ComposableMap>

            {hovered && (
              <Box
                position="absolute"
                bottom={4}
                left={4}
                bg={tooltipBg}
                border="1px solid"
                borderColor={tooltipBorder}
                borderRadius="md"
                px={3}
                py={2}
                boxShadow="lg"
                zIndex={10}
              >
                <VStack spacing={1} align="start">
                  <Text fontWeight="semibold">{hovered.name}</Text>
                  <Text fontSize="sm" color="gray.500">
                    {numberFormatter.format(hovered.value)} návštěv
                  </Text>
                  <Text fontSize="xs" color="blue.500" fontWeight="medium">
                    Klikněte pro detaily
                  </Text>
                </VStack>
              </Box>
            )}

            {clicked && (
              <Box
                position="absolute"
                top={4}
                right={4}
                bg={clubTheme.primary}
                color="white"
                borderRadius="md"
                px={3}
                py={2}
                boxShadow="lg"
                zIndex={10}
              >
                <VStack spacing={1} align="start">
                  <Text fontWeight="semibold" fontSize="sm">
                    Vybraná země
                  </Text>
                  <Text fontSize="sm">{clicked.name}</Text>
                  <Text fontSize="xs" opacity={0.9}>
                    {numberFormatter.format(clicked.value)} návštěv
                  </Text>
                </VStack>
              </Box>
            )}
          </Box>
        )}

        {hasData && !isLoading && (
          <VStack spacing={3} mt={4} align="stretch">
            <Flex justify="space-between" align="center">
              <Text fontSize="sm" color="gray.500" fontWeight="medium">
                Méně návštěv
              </Text>
              <Text fontSize="xs" color="gray.400" textAlign="center">
                Intenzita návštěvnosti
              </Text>
              <Text fontSize="sm" color="gray.500" fontWeight="medium">
                Více návštěv
              </Text>
            </Flex>
            <Box
              height="12px"
              borderRadius="full"
              bgGradient={`linear(to-r, ${defaultFill}, ${startFill}, ${endFill})`}
              boxShadow="inset 0 1px 2px rgba(0,0,0,0.1)"
              position="relative"
              overflow="hidden"
            >
              <Box
                position="absolute"
                top={0}
                left={0}
                right={0}
                bottom={0}
                bgGradient="linear(to-r, transparent, rgba(255,255,255,0.2), transparent)"
                borderRadius="full"
              />
            </Box>
            {clicked && (
              <Text fontSize="xs" color="blue.500" textAlign="center" fontWeight="medium">
                💡 Klikněte na jinou zemi pro porovnání dat
              </Text>
            )}
          </VStack>
        )}
      </CardBody>
    </Card>
  );
};

export default VisitorCountriesMap;
