import { PolygonWithLabel } from "@/components/map/PolygonWithLabel";
import { PolylineWithLabel } from "@/components/map/PolylineWithLabel";
import { showToastError } from "@/config";
import {
  AUTO_REFRESH_INTERVAL,
  ENTITY,
  IOS_PLATFORM,
  LIGHT_THEME,
} from "@/constants";
import {
  queryAlarm,
  queryEntities,
  queryGpsData,
  queryTrackPoints,
} from "@/controller/DeviceController";
import { useColorScheme } from "@/hooks/use-color-scheme.web";
import { usePlatform } from "@/hooks/use-platform";
import { getShipIcon } from "@/services/map_service";
import { useBanzones } from "@/state/use-banzones";
import {
  convertWKTLineStringToLatLngArray,
  convertWKTtoLatLngString,
} from "@/utils/geom";
import { Image as ExpoImage } from "expo-image";
import { useEffect, useRef, useState } from "react";
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";

import MapView, { Circle, Marker } from "react-native-maps";
import { SafeAreaProvider } from "react-native-safe-area-context";

const testPolyline =
  "MULTIPOLYGON(((108.7976074 17.5392966,110.390625 14.2217886,109.4677734 10.8548863,112.9227161 10.6933337,116.4383411 12.565622,116.8997669 17.0466095,109.8685169 17.8013229,108.7973446 17.5393669,108.7976074 17.5392966)))";

export default function HomeScreen() {
  const [gpsData, setGpsData] = useState<Model.GPSResonse | null>(null);
  const [alarmData, setAlarmData] = useState<Model.AlarmResponse | null>(null);
  const [trackPoints, setTrackPoints] = useState<Model.ShipTrackPoint[] | null>(
    null
  );
  const [circleRadius, setCircleRadius] = useState(100);
  const [zoomLevel, setZoomLevel] = useState(10);
  const [isFirstLoad, setIsFirstLoad] = useState(true);
  const [polylineCoordinates, setPolylineCoordinates] = useState<
    number[][] | null
  >(null);
  const [polygonCoordinates, setPolygonCoordinates] = useState<
    number[][][] | null
  >(null);
  const [, setZoneGeometries] = useState<Map<string, any>>(new Map());
  const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const platform = usePlatform();
  const theme = useColorScheme();
  const { banzones, getBanzone } = useBanzones();
  const banzonesRef = useRef(banzones);
  // console.log("Platform: ", platform);
  // console.log("Theme: ", theme);

  const getGpsData = async () => {
    try {
      const response = await queryGpsData();
      // console.log("GpsData: ", response.data);
      // console.log(
      //   "Heading value:",
      //   response.data?.h,
      //   "Type:",
      //   typeof response.data?.h
      // );
      setGpsData(response.data);
    } catch (error) {
      console.error("Error fetching GPS data:", error);
      showToastError("Lỗi", "Không thể lấy dữ liệu GPS");
    }
  };

  const drawPolyline = () => {
    const data = convertWKTtoLatLngString(testPolyline);
    console.log("Data: ", data);
    // setPolygonCoordinates(data[0]);
    // ;
    // console.log("Banzones: ", banzones.length);
  };

  useEffect(() => {
    banzonesRef.current = banzones;
  }, [banzones]);

  const areGeometriesEqual = (
    left?: {
      geom_type: number;
      geom_lines?: string | null;
      geom_poly?: string | null;
    },
    right?: {
      geom_type: number;
      geom_lines?: string | null;
      geom_poly?: string | null;
    }
  ) => {
    if (!left && !right) {
      return true;
    }

    if (!left || !right) {
      return false;
    }

    return (
      left.geom_type === right.geom_type &&
      (left.geom_lines || "") === (right.geom_lines || "") &&
      (left.geom_poly || "") === (right.geom_poly || "")
    );
  };

  const areCoordinatesEqual = (
    current: number[][] | null,
    next: number[][] | null
  ) => {
    if (!current || !next || current.length !== next.length) {
      return false;
    }

    return current.every(
      (coord, index) =>
        coord[0] === next[index][0] && coord[1] === next[index][1]
    );
  };

  const areMultiPolygonCoordinatesEqual = (
    current: number[][][] | null,
    next: number[][][] | null
  ) => {
    if (!current || !next || current.length !== next.length) {
      return false;
    }

    return current.every((polygon, polyIndex) => {
      const nextPolygon = next[polyIndex];
      if (!nextPolygon || polygon.length !== nextPolygon.length) {
        return false;
      }
      return polygon.every(
        (coord, coordIndex) =>
          coord[0] === nextPolygon[coordIndex][0] &&
          coord[1] === nextPolygon[coordIndex][1]
      );
    });
  };

  const getAlarmData = async () => {
    try {
      const response = await queryAlarm();
      // console.log("AlarmData: ", response.data);
      setAlarmData(response.data);
    } catch (error) {
      console.error("Error fetching Alarm Data: ", error);
      showToastError("Lỗi", "Không thể lấy dữ liệu báo động");
    }
  };

  const getEntities = async () => {
    try {
      const entities = await queryEntities();
      if (!entities) {
        // Clear tất cả khu vực khi không có dữ liệu
        setPolylineCoordinates(null);
        setPolygonCoordinates(null);
        setZoneGeometries(new Map());
        return;
      }

      const currentBanzones = banzonesRef.current || [];
      let nextPolyline: number[][] | null = null;
      let nextMultiPolygon: number[][][] | null = null;
      let foundPolyline = false;
      let foundPolygon = false;

      // Process zones để tìm geometries
      for (const entity of entities) {
        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(null);
          setPolygonCoordinates(null);
          setZoneGeometries(new Map());
          return;
        }

        for (const zone of zones) {
          const geom = currentBanzones.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) {
            foundPolyline = true;
            const coordinates = convertWKTLineStringToLatLngArray(
              geom_lines || ""
            );
            if (coordinates.length > 0) {
              nextPolyline = coordinates;
            }
          } else if (geom_type === 1) {
            foundPolygon = true;
            const coordinates = convertWKTtoLatLngString(geom_poly || "");
            if (coordinates.length > 0) {
              console.log("Polygon Coordinate: ", coordinates);
              nextMultiPolygon = coordinates;
            }
          }
        }
      }

      // Update state sau khi đã process xong
      setZoneGeometries((prevGeometries) => {
        const updated = new Map(prevGeometries);
        let hasChanges = false;

        for (const entity of entities) {
          if (entity.id !== ENTITY.ZONE_ALARM_LIST) {
            continue;
          }

          let zones: any[] = [];
          try {
            zones = entity.valueString ? JSON.parse(entity.valueString) : [];
          } catch {
            continue;
          }

          if (zones.length === 0) {
            if (updated.size > 0) {
              hasChanges = true;
              updated.clear();
            }
            break;
          }

          for (const zone of zones) {
            const geom = currentBanzones.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;
            }

            const key = `${zone.zone_id}_${geom_type}`;
            const newGeomData = { geom_type, geom_lines, geom_poly };
            const oldGeom = updated.get(key);

            if (!areGeometriesEqual(oldGeom, newGeomData)) {
              hasChanges = true;
              updated.set(key, newGeomData);
              console.log("Geometry changed", { key, oldGeom, newGeomData });
            }
          }
        }

        return hasChanges ? updated : prevGeometries;
      });

      // Cập nhật hoặc clear polyline
      if (foundPolyline && nextPolyline) {
        setPolylineCoordinates((prev) =>
          areCoordinatesEqual(prev, nextPolyline) ? prev : nextPolyline
        );
      } else if (!foundPolyline) {
        console.log("Hết cảnh báo qua polyline");
        setPolylineCoordinates(null);
      }

      // Cập nhật hoặc clear polygon
      if (foundPolygon && nextMultiPolygon) {
        setPolygonCoordinates((prev) =>
          areMultiPolygonCoordinatesEqual(prev, nextMultiPolygon)
            ? prev
            : nextMultiPolygon
        );
      } else if (!foundPolygon) {
        console.log("Hết cảnh báo qua polygon");
        setPolygonCoordinates(null);
      }
    } catch (error) {
      console.error("Error fetching Entities: ", error);
      // Clear tất cả khi có lỗi
      setPolylineCoordinates(null);
      setPolygonCoordinates(null);
      setZoneGeometries(new Map());
    }
  };

  const getShipTrackPoints = async () => {
    try {
      const response = await queryTrackPoints();
      // console.log("TrackPoints Data Length: ", response.data.length);
      setTrackPoints(response.data);
    } catch (error) {
      console.error("Error fetching TrackPoints Data: ", error);
      showToastError("Lỗi", "Không thể lấy lịch sử di chuyển");
    }
  };

  const fetchAllData = async () => {
    await Promise.all([
      getGpsData(),
      getAlarmData(),
      getShipTrackPoints(),
      getEntities(),
    ]);
  };

  const setupAutoRefresh = () => {
    // Clear existing interval if any
    if (intervalRef.current) {
      clearInterval(intervalRef.current);
    }

    // Set new interval to refresh data every 5 seconds
    // Không fetch banzones vì dữ liệu không thay đổi
    intervalRef.current = setInterval(async () => {
      // console.log("Auto-refreshing data...");
      await fetchAllData();
    }, AUTO_REFRESH_INTERVAL);
  };

  const handleMapReady = () => {
    // console.log("Map loaded successfully!");
    // Gọi fetchAllData ngay lập tức (không cần đợi banzones)
    fetchAllData();
    setupAutoRefresh();
    // Set isFirstLoad to false sau khi map ready để chỉ zoom lần đầu tiên
    setTimeout(() => {
      setIsFirstLoad(false);
    }, 2000);
  };

  // Cleanup interval on component unmount
  useEffect(() => {
    return () => {
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
      }
    };
  }, []);

  useEffect(() => {
    getBanzone();
  }, [getBanzone]);

  // 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,
    };
  };

  return (
    <SafeAreaProvider style={styles.container}>
      {banzones.length > 0 && (
        <Text className="hidden">Banzones loaded: {banzones.length}</Text>
      )}
      <MapView
        onMapReady={handleMapReady}
        onPoiClick={(point) => {
          console.log("Poi clicked: ", point.nativeEvent);
        }}
        onRegionChangeComplete={handleRegionChangeComplete}
        style={styles.map}
        // initialRegion={getMapRegion()}
        region={getMapRegion()}
        userInterfaceStyle={theme === LIGHT_THEME ? "light" : "dark"}
        showsBuildings={false}
        showsIndoors={false}
        loadingEnabled={true}
        mapType="standard"
      >
        {trackPoints &&
          trackPoints.length > 0 &&
          trackPoints.map((point, index) => {
            // console.log(`Rendering circle ${index}:`, point);
            return (
              <Circle
                key={index}
                center={{
                  latitude: point.lat,
                  longitude: point.lon,
                }}
                zIndex={50}
                radius={circleRadius}
                fillColor="rgba(16, 85, 201, 0.6)"
                strokeColor="rgba(16, 85, 201, 0.8)"
                strokeWidth={2}
              />
            );
          })}
        {polylineCoordinates && (
          <PolylineWithLabel
            coordinates={polylineCoordinates.map((coord) => ({
              latitude: coord[0],
              longitude: coord[1],
            }))}
            label="Tuyến bờ"
            strokeColor="#FF5733"
            strokeWidth={4}
            showDistance={false}
            zIndex={50}
          />
        )}
        {polygonCoordinates && polygonCoordinates.length > 0 && (
          <>
            {polygonCoordinates.map((polygon, index) => {
              // Tạo key ổn định từ tọa độ đầu tiên của polygon
              const polygonKey =
                polygon.length > 0
                  ? `polygon-${polygon[0][0]}-${polygon[0][1]}-${index}`
                  : `polygon-${index}`;

              return (
                <PolygonWithLabel
                  key={polygonKey}
                  coordinates={polygon.map((coords) => ({
                    latitude: coords[0],
                    longitude: coords[1],
                  }))}
                  label="Test khu đánh bắt"
                  content="Thời gian cấm (từ tháng 1 đến tháng 12)"
                  fillColor="rgba(16, 85, 201, 0.6)"
                  strokeColor="rgba(16, 85, 201, 0.8)"
                  strokeWidth={2}
                  zIndex={50}
                  zoomLevel={zoomLevel}
                />
              );
            })}
          </>
        )}
        {gpsData && (
          <Marker
            coordinate={{
              latitude: gpsData.lat,
              longitude: gpsData.lon,
            }}
            title={
              platform === IOS_PLATFORM
                ? "Tàu của mình - iOS"
                : "Tàu của mình - Android"
            }
            zIndex={100}
            anchor={{ x: 0.5, y: 0.5 }}
          >
            <View className="w-8 h-8 items-center justify-center">
              <ExpoImage
                source={getShipIcon(alarmData?.level || 0, gpsData.fishing)}
                style={{
                  width: 32,
                  height: 32,
                  transform: [
                    {
                      rotate: `${
                        typeof gpsData.h === "number" && !isNaN(gpsData.h)
                          ? gpsData.h
                          : 0
                      }deg`,
                    },
                  ],
                }}
              />
            </View>
          </Marker>
        )}
      </MapView>
      <TouchableOpacity style={styles.button} onPress={drawPolyline}>
        <Text style={styles.buttonText}>Get GPS Data</Text>
      </TouchableOpacity>
    </SafeAreaProvider>
  );
}

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",
  },
  titleContainer: {
    flexDirection: "row",
    alignItems: "center",
    gap: 8,
  },
  stepContainer: {
    gap: 8,
    marginBottom: 8,
  },
  reactLogo: {
    height: 178,
    width: 290,
    bottom: 0,
    left: 0,
    position: "absolute",
  },
});
