import { BanzoneWithAlarm } from "@/app/(tabs)";
import {
  convertWKTLineStringToLatLngArray,
  convertWKTPointToLatLng,
  convertWKTtoLatLngString,
} from "@/utils/geom";
import React, { useEffect, useMemo } from "react";
import { CircleWithLabel } from "./CircleWithLabel";
import { MarkerCustom } from "./MarkerCustom";
import { PolygonWithLabel } from "./PolygonWithLabel";
import { PolylineWithLabel } from "./PolylineWithLabel";

import MapView from "react-native-maps";

interface ZoneInMapProps {
  banzones: BanzoneWithAlarm[];
  mapRef?: React.RefObject<MapView | null>;
}

// Helper function to parse zone geometry
const parseZoneGeometry = (geometryString: string | undefined) => {
  if (!geometryString) {
    return null;
  }

  try {
    const geometry: Model.Geom = JSON.parse(geometryString);
    return geometry;
  } catch (error) {
    console.warn("Failed to parse geometry:", error);
    return null;
  }
};

const ZoneInMap = (data: ZoneInMapProps) => {
  const { banzones, mapRef } = data;

  // Auto-focus camera to first alarm location when banzones change
  useEffect(() => {
    if (mapRef?.current && banzones.length > 0) {
      const firstAlarm = banzones[0].alarms;
      if (
        firstAlarm.zone.lat !== undefined &&
        firstAlarm.zone.lon !== undefined
      ) {
        setTimeout(() => {
          mapRef.current?.animateToRegion(
            {
              latitude: firstAlarm.zone.lat as number,
              longitude: firstAlarm.zone.lon as number,
              latitudeDelta: 0.05,
              longitudeDelta: 0.05,
            },
            1000
          );
        }, 500);
      }
    }
  }, [banzones, mapRef]);

  // Parse and render all banzones with their ship markers
  const allElements = useMemo(() => {
    const elements: React.ReactNode[] = [];

    console.log("ZoneInMap - banzones received:", banzones);

    banzones.forEach((banzone, banzoneIndex) => {
      const { zone, alarms } = banzone;

      console.log(`Processing banzone ${banzoneIndex}:`, {
        zone: zone,
        alarms: alarms,
        geometry: zone?.geometry,
      });

      // Parse geometry with error handling
      const geometry = parseZoneGeometry(zone?.geometry);
      if (!geometry) {
        console.warn(`No geometry for zone ${banzoneIndex}`);
        return;
      }

      const { geom_type, geom_lines, geom_poly, geom_point, geom_radius } =
        geometry;

      console.log(`Parsed geometry for zone ${banzoneIndex}:`, {
        geom_type,
        geom_lines: geom_lines?.substring(0, 100) + "...",
        geom_poly: geom_poly?.substring(0, 100) + "...",
        geom_point,
        geom_radius,
      });

      try {
        if (geom_type === 2) {
          // LINESTRING - use PolylineWithLabel
          // console.log(`Processing LINESTRING for zone ${banzoneIndex}`);
          const coordinates = convertWKTLineStringToLatLngArray(
            geom_lines || ""
          );
          // console.log(`Converted coordinates:`, coordinates);
          if (coordinates.length > 0) {
            elements.push(
              <PolylineWithLabel
                key={`line-${zone?.id || banzoneIndex}`}
                coordinates={coordinates.map((coord) => ({
                  latitude: coord[0],
                  longitude: coord[1],
                }))}
                label={zone?.name || alarms.zone.zone_name || ""}
                content={alarms.zone.message || ""}
              />
            );
            // console.log(`Added PolylineWithLabel for zone ${banzoneIndex}`);
          }
        } else if (geom_type === 1) {
          // MULTIPOLYGON - check both geom_poly and geom_lines
          // console.log(`Processing MULTIPOLYGON for zone ${banzoneIndex}`);
          ``;
          // First check if we have actual polygon data
          if (geom_poly && geom_poly.trim() !== "") {
            const polygons = convertWKTtoLatLngString(geom_poly);
            // console.log(`Converted polygons from geom_poly:`, polygons);
            polygons.forEach((polygon, polygonIndex) => {
              if (polygon.length > 0) {
                elements.push(
                  <PolygonWithLabel
                    key={`polygon-${zone?.id || banzoneIndex}-${polygonIndex}`}
                    coordinates={polygon.map((coord) => ({
                      latitude: coord[0],
                      longitude: coord[1],
                    }))}
                    label={zone?.name || alarms.zone.zone_name || ""}
                    content={alarms.zone.message || ""}
                  />
                );
                // console.log(
                // `Added PolygonWithLabel for zone ${banzoneIndex}-${polygonIndex}`
                // );
              }
            });
          } else if (geom_lines && geom_lines.trim() !== "") {
            // If no polygon data, treat geom_lines as a line (data inconsistency fix)
            // console.log(
            // `No polygon data, processing as LINESTRING from geom_lines`
            // );
            const coordinates = convertWKTLineStringToLatLngArray(geom_lines);
            console.log(`Converted coordinates from geom_lines:`, coordinates);
            if (coordinates.length > 0) {
              elements.push(
                <PolylineWithLabel
                  key={`line-${zone?.id || banzoneIndex}`}
                  coordinates={coordinates.map((coord) => ({
                    latitude: coord[0],
                    longitude: coord[1],
                  }))}
                  label={zone?.name || alarms.zone.zone_name || ""}
                  content={alarms.zone.message || ""}
                />
              );
              // console.log(
              // `Added PolylineWithLabel for zone ${banzoneIndex} (from geom_lines)`
              // );
            }
          } else {
            // console.warn(`No valid geometry data for zone ${banzoneIndex}`);
          }
        } else if (geom_type === 3) {
          // POINT/CIRCLE - use Circle
          // console.log(`Processing POINT/CIRCLE for zone ${banzoneIndex}`);
          const point = convertWKTPointToLatLng(geom_point || "");
          // console.log(`Converted point:`, point, `radius:`, geom_radius);
          if (point && geom_radius) {
            elements.push(
              <CircleWithLabel
                key={`circle-${zone?.id || banzoneIndex}`}
                center={{
                  latitude: point[1], // Note: convertWKTPointToLatLng returns [lng, lat]
                  longitude: point[0],
                }}
                radius={geom_radius}
                label={zone?.name || alarms.zone.zone_name || ""}
                content={alarms.zone.message || ""}
              />
            );
            // console.log(`Added Circle for zone ${banzoneIndex}`);
          }
        } else {
          console.warn(
            `Unknown geom_type ${geom_type} for zone ${banzoneIndex}`
          );
        }
      } catch (error) {
        console.warn(
          "Error processing zone geometry for zone",
          zone?.id,
          ":",
          error
        );
      }

      // Ship marker for the alarm location
      if (alarms.zone.lat && alarms.zone.lon) {
        elements.push(
          <MarkerCustom
            key={`ship-${alarms.thing_id || banzoneIndex}`}
            id={`ship-${alarms.thing_id || banzoneIndex}`}
            latitude={alarms.zone.lat}
            longitude={alarms.zone.lon}
            shipName={alarms.ship_name || "Tàu không xác định"}
            description={
              alarms.zone.gps_time
                ? new Date(alarms.zone.gps_time * 1000).toLocaleString()
                : ""
            }
            heading={alarms.zone.h}
            zIndex={100}
          />
        );
      }
    });

    // console.log(`Total elements rendered: ${elements.length}`);
    return elements;
  }, [banzones]);

  return <>{allElements}</>;
};

export default ZoneInMap;
