import GPSInfoPanel from "@/components/map/GPSInfoPanel";
import type { PolygonWithLabelProps } from "@/components/map/PolygonWithLabel";
import { PolygonWithLabel } from "@/components/map/PolygonWithLabel";
import type { PolylineWithLabelProps } from "@/components/map/PolylineWithLabel";
import { PolylineWithLabel } from "@/components/map/PolylineWithLabel";
import SosButton from "@/components/map/SosButton";
import {
  ENTITY,
  EVENT_ALARM_DATA,
  EVENT_BANZONE_DATA,
  EVENT_ENTITY_DATA,
  EVENT_GPS_DATA,
  EVENT_TRACK_POINTS_DATA,
  IOS_PLATFORM,
  LIGHT_THEME,
} from "@/constants";
import { useColorScheme } from "@/hooks/use-color-scheme.web";
import { usePlatform } from "@/hooks/use-platform";
import { useThemeContext } from "@/hooks/use-theme-context";
import {
  getAlarmEventBus,
  getBanzonesEventBus,
  getEntitiesEventBus,
  getGpsEventBus,
  getTrackPointsEventBus,
} from "@/services/device_events";
import { getShipIcon } from "@/services/map_service";
import eventBus from "@/utils/eventBus";
import {
  convertWKTLineStringToLatLngArray,
  convertWKTtoLatLngString,
} from "@/utils/geom";
import { useEffect, useRef, useState } from "react";
import { Animated, Image as RNImage, StyleSheet, View } from "react-native";
import MapView, { Circle, Marker } from "react-native-maps";

export default function HomeScreen() {
  const [gpsData, setGpsData] = useState<Model.GPSResponse | null>(null);
  const [alarmData, setAlarmData] = useState<Model.AlarmResponse | null>(null);
  const [entityData, setEntityData] = useState<
    Model.TransformedEntity[] | null
  >(null);
  const [banzoneData, setBanzoneData] = useState<Model.Zone[] | null>(null);
  const [trackPointsData, setTrackPointsData] = useState<
    Model.ShipTrackPoint[] | null
  >(null);
  const [circleRadius, setCircleRadius] = useState(100);
  const [zoomLevel, setZoomLevel] = useState(10);
  const [isFirstLoad, setIsFirstLoad] = useState(true);
  const [polylineCoordinates, setPolylineCoordinates] = useState<
    PolylineWithLabelProps[]
  >([]);
  const [polygonCoordinates, setPolygonCoordinates] = useState<
    PolygonWithLabelProps[]
  >([]);
  const platform = usePlatform();
  const theme = useThemeContext().colorScheme;
  const scale = useRef(new Animated.Value(0)).current;
  const opacity = useRef(new Animated.Value(1)).current;

  useEffect(() => {
    getGpsEventBus();
    getAlarmEventBus();
    getEntitiesEventBus();
    getBanzonesEventBus();
    getTrackPointsEventBus();
    const queryGpsData = (gpsData: Model.GPSResponse) => {
      if (gpsData) {
        // console.log("GPS Data: ", gpsData);
        setGpsData(gpsData);
      } else {
        setGpsData(null);
        setPolygonCoordinates([]);
        setPolylineCoordinates([]);
      }
    };
    const queryAlarmData = (alarmData: Model.AlarmResponse) => {
      // console.log("Alarm Data: ", alarmData.alarms.length);
      setAlarmData(alarmData);
    };
    const queryEntityData = (entityData: Model.TransformedEntity[]) => {
      // console.log("Entities Length Data: ", entityData.length);
      setEntityData(entityData);
    };
    const queryBanzonesData = (banzoneData: Model.Zone[]) => {
      // console.log("Banzone Data: ", banzoneData.length);

      setBanzoneData(banzoneData);
    };
    const queryTrackPointsData = (TrackPointsData: Model.ShipTrackPoint[]) => {
      // console.log("TrackPoints Data: ", TrackPointsData.length);
      if (TrackPointsData && TrackPointsData.length > 0) {
        setTrackPointsData(TrackPointsData);
      } else {
        setTrackPointsData([]);
      }
    };

    eventBus.on(EVENT_GPS_DATA, queryGpsData);
    // console.log("Registering event handlers in HomeScreen");
    eventBus.on(EVENT_GPS_DATA, queryGpsData);
    // console.log("Subscribed to EVENT_GPS_DATA");
    eventBus.on(EVENT_ALARM_DATA, queryAlarmData);
    // console.log("Subscribed to EVENT_ALARM_DATA");
    eventBus.on(EVENT_ENTITY_DATA, queryEntityData);
    // console.log("Subscribed to EVENT_ENTITY_DATA");
    eventBus.on(EVENT_TRACK_POINTS_DATA, queryTrackPointsData);
    // console.log("Subscribed to EVENT_TRACK_POINTS_DATA");
    eventBus.once(EVENT_BANZONE_DATA, queryBanzonesData);
    // console.log("Subscribed once to EVENT_BANZONE_DATA");

    return () => {
      // console.log("Unregistering event handlers in HomeScreen");
      eventBus.off(EVENT_GPS_DATA, queryGpsData);
      // console.log("Unsubscribed EVENT_GPS_DATA");
      eventBus.off(EVENT_ALARM_DATA, queryAlarmData);
      // console.log("Unsubscribed EVENT_ALARM_DATA");
      eventBus.off(EVENT_ENTITY_DATA, queryEntityData);
      // console.log("Unsubscribed EVENT_ENTITY_DATA");
      eventBus.off(EVENT_TRACK_POINTS_DATA, queryTrackPointsData);
      // console.log("Unsubscribed EVENT_TRACK_POINTS_DATA");
    };
  }, []);

  useEffect(() => {
    setPolylineCoordinates([]);
    setPolygonCoordinates([]);
    if (!entityData) return;
    if (!banzoneData) return;
    for (const entity of entityData) {
      if (entity.id !== ENTITY.ZONE_ALARM_LIST) {
        continue;
      }

      let zones: any[] = [];
      try {
        zones = entity.valueString ? JSON.parse(entity.valueString) : [];
      } catch (parseError) {
        console.error("Error parsing zone list:", parseError);
        continue;
      }
      // Nếu danh sách zone rỗng, clear tất cả
      if (zones.length === 0) {
        setPolylineCoordinates([]);
        setPolygonCoordinates([]);
        return;
      }

      let polylines: PolylineWithLabelProps[] = [];
      let polygons: PolygonWithLabelProps[] = [];

      for (const zone of zones) {
        // console.log("Zone Data: ", zone);
        const geom = banzoneData.find((b) => b.id === zone.zone_id);
        if (!geom) {
          continue;
        }
        const { geom_type, geom_lines, geom_poly } = geom.geom || {};
        if (typeof geom_type !== "number") {
          continue;
        }
        if (geom_type === 2) {
          // if(oldEntityData.find(e => e.id === ))
          // foundPolyline = true;
          const coordinates = convertWKTLineStringToLatLngArray(
            geom_lines || ""
          );
          if (coordinates.length > 0) {
            polylines.push({
              coordinates: coordinates.map((coord) => ({
                latitude: coord[0],
                longitude: coord[1],
              })),
              label: zone?.zone_name ?? "",
              content: zone?.message ?? "",
            });
          } else {
            console.log("Không tìm thấy polyline trong alarm");
          }
        } else if (geom_type === 1) {
          // foundPolygon = true;
          const coordinates = convertWKTtoLatLngString(geom_poly || "");
          if (coordinates.length > 0) {
            // console.log("Polygon Coordinate: ", coordinates);
            const zonePolygons = coordinates.map((polygon) => ({
              coordinates: polygon.map((coord) => ({
                latitude: coord[0],
                longitude: coord[1],
              })),
              label: zone?.zone_name ?? "",
              content: zone?.message ?? "",
            }));
            polygons.push(...zonePolygons);
          } else {
            console.log("Không tìm thấy polygon trong alarm");
          }
        }
      }

      setPolylineCoordinates(polylines);
      setPolygonCoordinates(polygons);
    }
  }, [banzoneData, entityData]);

  // Hàm tính radius cố định khi zoom change
  const calculateRadiusFromZoom = (zoom: number) => {
    const baseZoom = 10;
    const baseRadius = 100;
    const zoomDifference = baseZoom - zoom;
    const calculatedRadius = baseRadius * Math.pow(2, zoomDifference);
    // console.log("Caculate Radius: ", calculatedRadius);

    return Math.max(calculatedRadius, 50);
  };

  // Xử lý khi region (zoom) thay đổi
  const handleRegionChangeComplete = (newRegion: any) => {
    // Tính zoom level từ latitudeDelta
    // zoom = log2(360 / (latitudeDelta * 2)) + 8
    const zoom = Math.round(Math.log2(360 / (newRegion.latitudeDelta * 2)) + 8);
    const newRadius = calculateRadiusFromZoom(zoom);
    setCircleRadius(newRadius);
    setZoomLevel(zoom);
    // console.log("Zoom level:", zoom, "Circle radius:", newRadius);
  };

  // Tính toán region để focus vào marker của tàu (chỉ lần đầu tiên)
  const getMapRegion = () => {
    if (!isFirstLoad) {
      // Sau lần đầu, return undefined để không force region
      return undefined;
    }
    if (!gpsData) {
      return {
        latitude: 15.70581,
        longitude: 116.152685,
        latitudeDelta: 0.05,
        longitudeDelta: 0.05,
      };
    }

    return {
      latitude: gpsData.lat,
      longitude: gpsData.lon,
      latitudeDelta: 0.05,
      longitudeDelta: 0.05,
    };
  };

  const handleMapReady = () => {
    setTimeout(() => {
      setIsFirstLoad(false);
    }, 2000);
  };

  useEffect(() => {
    if (alarmData?.level === 3) {
      const loop = Animated.loop(
        Animated.sequence([
          Animated.parallel([
            Animated.timing(scale, {
              toValue: 3, // nở to 3 lần
              duration: 1500,
              useNativeDriver: true,
            }),
            Animated.timing(opacity, {
              toValue: 0, // mờ dần
              duration: 1500,
              useNativeDriver: true,
            }),
          ]),
          Animated.parallel([
            Animated.timing(scale, {
              toValue: 0,
              duration: 0,
              useNativeDriver: true,
            }),
            Animated.timing(opacity, {
              toValue: 1,
              duration: 0,
              useNativeDriver: true,
            }),
          ]),
        ])
      );
      loop.start();
      return () => loop.stop();
    }
  }, [alarmData?.level, scale, opacity]);

  return (
    <View
      // edges={["top"]}
      style={styles.container}
    >
      <MapView
        onMapReady={handleMapReady}
        onRegionChangeComplete={handleRegionChangeComplete}
        style={styles.map}
        // initialRegion={getMapRegion()}
        region={getMapRegion()}
        userInterfaceStyle={theme === LIGHT_THEME ? "light" : "dark"}
        showsBuildings={false}
        showsIndoors={false}
        loadingEnabled={true}
        mapType={platform === IOS_PLATFORM ? "mutedStandard" : "standard"}
        rotateEnabled={false}
      >
        {trackPointsData &&
          trackPointsData.length > 0 &&
          trackPointsData.map((point, index) => {
            // console.log(`Rendering circle ${index}:`, point);
            return (
              <Circle
                key={`circle-${index}`}
                center={{
                  latitude: point.lat,
                  longitude: point.lon,
                }}
                // zIndex={50}
                // radius={platform === IOS_PLATFORM ? 200 : 50}
                radius={circleRadius}
                strokeColor="rgba(16, 85, 201, 0.7)"
                fillColor="rgba(16, 85, 201, 0.7)"
                strokeWidth={2}
              />
            );
          })}
        {polylineCoordinates.length > 0 && (
          <>
            {polylineCoordinates.map((polyline, index) => (
              <PolylineWithLabel
                key={`polyline-${index}-${gpsData?.lat || 0}-${
                  gpsData?.lon || 0
                }`}
                coordinates={polyline.coordinates}
                label={polyline.label}
                content={polyline.content}
                strokeColor="#FF5733"
                strokeWidth={4}
                showDistance={false}
                // zIndex={50}
              />
            ))}
          </>
        )}
        {polygonCoordinates.length > 0 && (
          <>
            {polygonCoordinates.map((polygon, index) => {
              return (
                <PolygonWithLabel
                  key={`polygon-${index}-${gpsData?.lat || 0}-${
                    gpsData?.lon || 0
                  }`}
                  coordinates={polygon.coordinates}
                  label={polygon.label}
                  content={polygon.content}
                  fillColor="rgba(16, 85, 201, 0.6)"
                  strokeColor="rgba(16, 85, 201, 0.8)"
                  strokeWidth={2}
                  // zIndex={50}
                  zoomLevel={zoomLevel}
                />
              );
            })}
          </>
        )}
        {gpsData !== null && (
          <Marker
            key={
              platform === IOS_PLATFORM
                ? `${gpsData.lat}-${gpsData.lon}`
                : "gps-data"
            }
            coordinate={{
              latitude: gpsData.lat,
              longitude: gpsData.lon,
            }}
            zIndex={20}
            anchor={
              platform === IOS_PLATFORM
                ? { x: 0.5, y: 0.5 }
                : { x: 0.6, y: 0.4 }
            }
            tracksViewChanges={platform === IOS_PLATFORM ? true : undefined}
          >
            <View className="w-8 h-8 items-center justify-center">
              <View style={styles.pingContainer}>
                {alarmData?.level === 3 && (
                  <Animated.View
                    style={[
                      styles.pingCircle,
                      {
                        transform: [{ scale }],
                        opacity,
                      },
                    ]}
                  />
                )}
                <RNImage
                  source={(() => {
                    const icon = getShipIcon(
                      alarmData?.level || 0,
                      gpsData.fishing
                    );
                    // console.log("Ship icon:", icon, "for level:", alarmData?.level, "fishing:", gpsData.fishing);
                    return typeof icon === "string" ? { uri: icon } : icon;
                  })()}
                  style={{
                    width: 32,
                    height: 32,
                    transform: [
                      {
                        rotate: `${
                          typeof gpsData.h === "number" && !isNaN(gpsData.h)
                            ? gpsData.h
                            : 0
                        }deg`,
                      },
                    ],
                  }}
                />
              </View>
            </View>
          </Marker>
        )}
      </MapView>

      <View className="absolute top-14 right-2 shadow-md">
        <SosButton />
      </View>
      <GPSInfoPanel gpsData={gpsData!} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  map: {
    flex: 1,
  },
  button: {
    // display: "none",
    position: "absolute",
    top: 50,
    right: 20,
    backgroundColor: "#007AFF",
    paddingHorizontal: 16,
    paddingVertical: 12,
    borderRadius: 8,
    elevation: 5,
    shadowColor: "#000",
    shadowOffset: {
      width: 0,
      height: 2,
    },
    shadowOpacity: 0.25,
    shadowRadius: 3.84,
  },
  buttonText: {
    color: "#fff",
    fontSize: 16,
    fontWeight: "600",
  },

  pingContainer: {
    width: 32,
    height: 32,
    alignItems: "center",
    justifyContent: "center",
    overflow: "visible",
  },
  pingCircle: {
    position: "absolute",
    width: 40,
    height: 40,
    borderRadius: 20,
    backgroundColor: "#ED3F27",
  },
  centerDot: {
    width: 20,
    height: 20,
    borderRadius: 10,
    backgroundColor: "#0096FF",
  },
});
