import { getTheme } from '@/components/Theme/ThemeSwitcher';
import { useToken } from '@ant-design/pro-components';
import { useIntl } from '@umijs/max';
import { Checkbox, Flex } from 'antd';
import BaseLayer from 'ol/layer/Base';
import React, {
  forwardRef,
  useEffect,
  useImperativeHandle,
  useRef,
  useState,
} from 'react';
import {
  INITIAL_VIEW_CONFIG,
  LAYERS,
  wmsBoundaryLineLayer,
  wmsEntryBanzoneLayer,
  wmsFishingBanzoneLayer,
  wmsPortsLayer,
  wmsTinhLayer,
} from '../config/MapConfig';
import { BaseMap } from './BaseMap';

export interface VietNamMapProps {
  style?: React.CSSProperties;
  onFeatureClick?: (feature: any) => void;
  onFeaturesClick?: (features: any[]) => void;
  onError?: (error: Error) => void;
  onMapReady?: (baseMap: BaseMap) => void;
}

export interface VietNamMapRef {
  baseMap: BaseMap | null;
  getBaseMap: () => BaseMap | null;
}

interface LayerInfo {
  name: string;
  layer: BaseLayer;
  visible: boolean;
  mandatory: boolean;
}

const VietNamMap = forwardRef<VietNamMapRef, VietNamMapProps>(
  (
    { style = {}, onFeatureClick, onFeaturesClick, onError, onMapReady },
    ref,
  ) => {
    const token = useToken();
    const mapRef = useRef<HTMLDivElement>(null);
    const baseMapRef = useRef<BaseMap | null>(null);
    const [layers, setLayers] = useState<LayerInfo[]>([]);
    const intl = useIntl();
    const [isDark, setIsDark] = useState(getTheme() === 'dark');
    const [isMapReady, setIsMapReady] = useState(false);

    // Expose the BaseMap instance through ref
    useImperativeHandle(ref, () => ({
      baseMap: baseMapRef.current,
      getBaseMap: () => baseMapRef.current,
    }));

    // Listen for theme change
    useEffect(() => {
      const handleThemeChange = (e: CustomEvent) => {
        setIsDark(e.detail.theme === 'dark');
      };

      window.addEventListener(
        'theme-change',
        handleThemeChange as EventListener,
      );
      return () => {
        window.removeEventListener(
          'theme-change',
          handleThemeChange as EventListener,
        );
      };
    }, []);

    // Update base layer based on theme
    useEffect(() => {
      const baseMap = baseMapRef.current;

      if (!baseMap || !isMapReady) {
        return;
      }

      const baseLayerType = isDark ? 'dark' : 'osm';

      baseMap.setBaseLayer(baseLayerType);
    }, [isDark, isMapReady]);

    const getLayerDisplayName = (layerKey: string) => {
      switch (layerKey) {
        case LAYERS.FISHING_BANZONE.name:
          return intl.formatMessage({
            id: 'map.layer.fishing_ban_zone',
            defaultMessage: 'Vùng cấm đánh bắt cá',
          });
        case LAYERS.ENTRY_BANZONE.name:
          return intl.formatMessage({
            id: 'map.layer.entry_ban_zone',
            defaultMessage: 'Vùng cấm nhập cảnh',
          });
        case LAYERS.BOUNDARY_LINES.name:
          return intl.formatMessage({
            id: 'map.layer.boundary_lines',
            defaultMessage: 'Đường biên giới',
          });
        case LAYERS.EXIT_BANZONE.name:
          return intl.formatMessage({
            id: 'map.layer.exit_ban_zone',
            defaultMessage: 'Vùng cấm xuất cảnh',
          });
        case LAYERS.PORTS.name:
          return intl.formatMessage({
            id: 'map.layer.ports',
            defaultMessage: 'Cảng cá',
          });
        case LAYERS.TINH.name:
          return intl.formatMessage({
            id: 'map.layer.tinh',
            defaultMessage: 'Tỉnh',
          });
        default:
          return layerKey;
      }
    };

    useEffect(() => {
      console.log('Rerender');

      // Initialize BaseMap instance
      if (!baseMapRef.current && mapRef.current) {
        const baseMap = new BaseMap();
        baseMapRef.current = baseMap;

        try {
          // Initialize the map
          baseMap.initMap(mapRef.current);

          // Set initial view to Vietnam
          baseMap.setView(
            INITIAL_VIEW_CONFIG.center as [number, number],
            INITIAL_VIEW_CONFIG.zoom,
          );

          // Add WMS layers
          const layerInfos: LayerInfo[] = [];

          // Tỉnh layer (mandatory)
          wmsTinhLayer.setProperties({
            id: LAYERS.TINH.name,
            name: LAYERS.TINH.name,
          });
          wmsTinhLayer.setVisible(true);
          baseMap.addLayer(wmsTinhLayer);
          layerInfos.push({
            name: LAYERS.TINH.name,
            layer: wmsTinhLayer,
            visible: true,
            mandatory: true,
          });
          // console.log('Added Tỉnh layer with ID:', LAYERS.TINH.name);

          // Optional layers
          const optionalLayers = [
            { layer: wmsEntryBanzoneLayer, config: LAYERS.ENTRY_BANZONE },
            { layer: wmsBoundaryLineLayer, config: LAYERS.BOUNDARY_LINES },
            { layer: wmsFishingBanzoneLayer, config: LAYERS.FISHING_BANZONE },
            { layer: wmsPortsLayer, config: LAYERS.PORTS },
          ];

          optionalLayers.forEach(({ layer, config }) => {
            layer.setProperties({
              id: config.name,
              name: config.name,
            });
            layer.setVisible(true);
            baseMap.addLayer(layer);
            layerInfos.push({
              name: config.name,
              layer: layer,
              visible: true,
              mandatory: false,
            });
            // console.log(`Added layer with ID: ${config.name}`);
          });

          setLayers(layerInfos);

          // Register click handler
          baseMap.onClick((feature) => {
            if (feature) {
              if (onFeatureClick) {
                onFeatureClick(feature);
              }
            }
          });
          baseMap.onClickMultiple((features) => {
            if (features && features.length > 0) {
              if (onFeaturesClick) {
                onFeaturesClick(features);
              }
            }
          });

          // // Register pointer move handler for hover effects
          // baseMap.onPointerMove((feature) => {
          //   if (feature && onFeatureSelect) {
          //     onFeatureSelect(feature);
          //   }
          // });

          // Call onMapReady with the BaseMap instance
          if (onMapReady) {
            onMapReady(baseMap);
          }

          // Map is now ready
          setIsMapReady(true);
        } catch (error) {
          console.error('Failed to initialize map:', error);
          if (onError) {
            onError(error as Error);
          }
        }
      }

      // Cleanup
      return () => {
        if (baseMapRef.current) {
          baseMapRef.current.destroyMap();
          baseMapRef.current = null;
        }
      };
    }, []);

    // Handle layer visibility toggle
    const handleToggleLayer = (layerName: string, visible: boolean) => {
      const baseMap = baseMapRef.current;

      if (!baseMap) return;

      baseMap.toggleLayer(layerName, visible);
      setLayers((prevLayers) =>
        prevLayers.map((layer) =>
          layer.name === layerName ? { ...layer, visible } : layer,
        ),
      );
    };

    return (
      <div style={{ position: 'relative' }}>
        {/* Layer control panel */}
        <div
          style={{
            position: 'absolute',
            top: 0,
            right: 0,
            zIndex: 10,
            background: token.token.colorBgContainer,
            padding: '8px 12px',
            borderRadius: 4,
            boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)',
          }}
        >
          <h3 className="mb-3 font-semibold text-center">
            {intl.formatMessage({
              id: 'map.layer.list',
              defaultMessage: 'Danh sách khu vực',
            })}
          </h3>
          <Flex vertical gap="small">
            {layers.map(
              (layer) =>
                !layer.mandatory && (
                  <Checkbox
                    key={layer.name}
                    checked={layer.visible}
                    onChange={(e) =>
                      handleToggleLayer(layer.name, e.target.checked)
                    }
                  >
                    {getLayerDisplayName(layer.name)}
                  </Checkbox>
                ),
            )}
          </Flex>
        </div>

        {/* Map container */}
        <div
          ref={mapRef}
          style={{
            ...style,
            height: '100vh', // Default height
            width: '100vw',
          }}
        />
      </div>
    );
  },
);

VietNamMap.displayName = 'VietNamMap';

export default VietNamMap;
