import {
  MAP_POLYGON_BAN,
  MAP_POLYLINE_BAN,
  MAP_TRACKPOINTS_ID,
  ROUTE_TRIP,
} from '@/constants';
import { ENTITY_TYPE_ENUM } from '@/constants/enums';
import {
  queryAlarms,
  queryEntities,
  queryShipTrackPoints,
} from '@/services/controller/DeviceController';
import { queryBanzones } from '@/services/controller/MapController';
import { getShipIcon } from '@/services/service/MapService';
import {
  convertWKTLineStringToLatLngArray,
  convertWKTtoLatLngString,
  getBanzoneNameByType,
} from '@/utils/geomUtils';
import {
  CommentOutlined,
  InfoCircleOutlined,
  InfoOutlined,
} from '@ant-design/icons';
import { history, useModel } from '@umijs/max';
import { FloatButton, Popover } from 'antd';
import { useCallback, useEffect, useRef, useState } from 'react';
import GpsInfo from './components/GpsInfo';
import ShipInfo from './components/ShipInfo';
import SosButton from './components/SosButton';
import VietNamMap, { MapManager } from './components/VietNamMap';

// // Define missing types locally for now
// interface AlarmData {
//   level: number;
// }

// interface EntityData {
//   id: string;
//   valueString: string;
// }

// interface TrackPoint {
//   lat: number;
//   lon: number;
// }

export interface GpsData {
  lat: number;
  lon: number;
  s?: number; // Speed
  h?: number; // Heading
  fishing?: boolean;
}
const HomePage: React.FC = () => {
  const mapRef = useRef<HTMLDivElement>(null);
  const [isShipInfoOpen, setIsShipInfoOpen] = useState(false);
  const { gpsData, getGPSData } = useModel('getSos');

  const onFeatureClick = useCallback((feature: any) => {
    console.log('OnClick Feature: ', feature);
    console.log(
      'Clicked ship at',
      new Date().toLocaleTimeString(),
      'Properties:',
      feature.getProperties(),
    );
  }, []);

  const onFeaturesClick = useCallback((features: any[]) => {
    console.log('Multiple features clicked:', features);
  }, []);

  const onError = useCallback((error: any) => {
    console.error(
      'Lỗi khi thêm vào map at',
      new Date().toLocaleTimeString(),
      ':',
      error,
    );
  }, []);

  const mapManagerRef = useRef(
    new MapManager(mapRef, {
      onFeatureClick,
      onFeaturesClick,
      onError,
    }),
  );

  const [isShowGPSData, setIsShowGPSData] = useState(true);

  useEffect(() => {
    getGPSData();
    const interval = setInterval(() => {
      getGPSData();
      getEntitiesData(mapManagerRef.current, gpsData!);
      fetchAndAddTrackPoints(mapManagerRef.current);
      fetchAndProcessEntities(mapManagerRef.current);
    }, 5000);
    return () => {
      clearInterval(interval);
      console.log('MapManager destroyed in HomePage cleanup');
    };
  }, []);

  useEffect(() => {
    const timer = setTimeout(() => {
      // getGPSData();
      getEntitiesData(mapManagerRef.current, gpsData!);
      fetchAndAddTrackPoints(mapManagerRef.current);
      fetchAndProcessEntities(mapManagerRef.current);
    }, 1000); // delay 1s
    return () => clearTimeout(timer);
  }, [gpsData]);

  // Helper function to add features to the map
  const addFeatureToMap = (
    mapManager: MapManager,
    gpsData: GpsData,
    alarm: API.AlarmResponse,
  ) => {
    console.log(
      'Adding feature to map with GPS data:',
      gpsData,
      'and alarm:',
      alarm,
    );
    const isSos = alarm?.alarms.find(
      (a) => a.id === ENTITY_TYPE_ENUM.SOS_WARNING,
    );
    console.log('Is SOS Alarm Present:', isSos);

    if (mapManager?.featureLayer && gpsData) {
      mapManager.featureLayer.getSource()?.clear();
      mapManager.addPoint(
        [gpsData.lon, gpsData.lat],
        { bearing: gpsData.h || 0 },
        {
          icon: getShipIcon(alarm.level || 0, gpsData?.fishing || false),
          scale: 0.1,
          animate: isSos ? true : false,
        },
      );
    }
  };

  const fetchAndProcessEntities = async (mapManager: MapManager) => {
    try {
      const entities: API.TransformedEntity[] = await queryEntities();
      console.log('Fetched entities:', entities.length);

      for (const entity of entities) {
        if (entity.id === '50:2' && entity.valueString !== '[]') {
          const banzones = await queryBanzones();
          const zones: any[] = JSON.parse(entity.valueString);

          zones.forEach((zone: any) => {
            const geom = banzones.find((b) => b.id === zone.zone_id);
            if (geom) {
              const { geom_type, geom_lines, geom_poly } = geom.geom || {};
              if (geom_type === 2) {
                const coordinates = convertWKTLineStringToLatLngArray(
                  geom_lines || '',
                );
                if (coordinates.length > 0) {
                  mapManager.addLineString(
                    coordinates,
                    {
                      id: MAP_POLYLINE_BAN,
                      text: `${geom.name} - ${zone.message}`,
                    },
                    { strokeColor: 'red', strokeWidth: 4 },
                  );
                }
              } else if (geom_type === 1) {
                const coordinates = convertWKTtoLatLngString(geom_poly || '');
                if (coordinates.length > 0) {
                  mapManager.addPolygon(
                    coordinates,
                    {
                      id: MAP_POLYGON_BAN,
                      name: geom.name,
                      type: getBanzoneNameByType(geom.type || 4),
                      description: zone.message,
                    },
                    {
                      strokeColor: '#FCC61D',
                      strokeWidth: 2,
                      fillColor: '#FCC61D',
                    },
                  );
                }
              }
            }
          });
        }
      }
    } catch (error) {
      console.error('Error fetching entities:', error);
    }
  };

  const fetchAndAddTrackPoints = async (mapManager: MapManager) => {
    try {
      const trackpoints: API.ShipTrackPoint[] = await queryShipTrackPoints();
      if (trackpoints.length > 0) {
        mapManager.addLineString(
          trackpoints.map((point) => [point.lon, point.lat]),
          { id: MAP_TRACKPOINTS_ID },
          { strokeColor: 'blue', strokeWidth: 3 },
        );
      }
    } catch (error) {
      console.error('Error fetching ship track points:', error);
    }
  };

  const getEntitiesData = async (mapManager: MapManager, gpsData: GpsData) => {
    try {
      const alarm: API.AlarmResponse = await queryAlarms();
      addFeatureToMap(mapManager, gpsData, alarm);
    } catch (error) {
      console.error('Error fetching entities:', error);
    }
  };

  return (
    <div>
      <VietNamMap
        style={{
          height: '97vh',
          width: '100vw',
        }}
        mapManager={mapManagerRef.current}
        onFeatureClick={onFeatureClick}
        onFeaturesClick={onFeaturesClick}
        onError={onError}
      />
      <Popover
        styles={{
          root: { width: '85%', maxWidth: 500, paddingLeft: 15 },
        }}
        placement="left"
        title="Trạng thái hiện tại"
        content={
          <GpsInfo gpsData={gpsData} />
          // <ShipInfo />
        }
        open={isShowGPSData}
      >
        <FloatButton.Group
          trigger="click"
          style={{ insetInlineEnd: 5, insetBlockEnd: 10 }}
          icon={<InfoCircleOutlined />}
          onOpenChange={(open) => setIsShowGPSData(!open)}
        >
          <FloatButton
            icon={<CommentOutlined />}
            onClick={() => history.push(ROUTE_TRIP)}
            tooltip="Thông tin chuyến đi"
          />
          <FloatButton
            icon={<InfoOutlined />}
            tooltip="Thông tin tàu"
            onClick={() => setIsShipInfoOpen(true)}
          />
        </FloatButton.Group>
      </Popover>
      <div className="absolute top-3 right-3 ">
        <SosButton
          onRefresh={(value) => {
            if (value) {
              // Ensure null check for gpsData in all usages
              if (gpsData) {
                getEntitiesData(mapManagerRef.current, gpsData);
              } else {
                console.warn('GPS data is null, skipping getEntitiesData call');
              }
            }
          }}
        />
      </div>
      <ShipInfo isOpen={isShipInfoOpen} setIsOpen={setIsShipInfoOpen} />
    </div>
  );
};

export default HomePage;
