import * as THREE from "three";
import { useEffect, useState } from "react";
import * as turf from "@turf/turf";
import * as Types from "../../../types/world/worldTypes";
import arrayLinesToObject from "../geomentries/lines/lineConvertions/arrayLinesToObject";
interface PolygonGeneratorProps {
  groupRef: React.MutableRefObject<THREE.Group | null>;
  lines: Types.RefLines;
}

export default function PolygonGenerator({
  groupRef,
  lines,
}: PolygonGeneratorProps) {

  useEffect(() => {
    let allLines = arrayLinesToObject(lines.current);
    const wallLines = allLines?.filter((line) => line?.type === "WallLine");
    const aisleLines = allLines?.filter((line) => line?.type === "AisleLine");

    const wallPoints = wallLines
      .map((pair) => pair?.line.map((vals) => vals.position))
      .filter((wall): wall is THREE.Vector3[] => !!wall);

    const result = aisleLines.map((pair) =>
      pair?.line.map((point) => ({
        position: [point.position.x, point.position.z],
        uuid: point.uuid,
      }))
    );

    if (!result || result.some((line) => !line)) {
      return;
    }

    const lineFeatures = result?.map((line: any) =>
      turf.lineString(line.map((p: any) => p?.position))
    );

    const polygons = turf.polygonize(turf.featureCollection(lineFeatures));
    renderWallGeometry(wallPoints);

    if (polygons.features.length > 1) {
      polygons.features.forEach((feature) => {
        if (feature.geometry.type === "Polygon") {

          const shape = new THREE.Shape();
          const coords = feature.geometry.coordinates[0];

          shape.moveTo(coords[0][0], coords[0][1]);

          for (let i = 1; i < coords.length; i++) {
            shape.lineTo(coords[i][0], coords[i][1]);
          }
          shape.lineTo(coords[0][0], coords[0][1]);

          const extrudeSettings = {
            depth: 5,
            bevelEnabled: false,
          };

          const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);

          const material = new THREE.MeshBasicMaterial({ color: "blue", transparent: true, opacity: 0.5 });
          const mesh = new THREE.Mesh(geometry, material);
          mesh.rotateX(Math.PI / 2);
          mesh.name = "agv-collider";
          mesh.position.y = 5;

          mesh.receiveShadow = true;
          groupRef.current?.add(mesh);
        }
      });
    }

  }, [lines.current]);

  const renderWallGeometry = (walls: THREE.Vector3[][]) => {
    walls.forEach((wall) => {
      if (wall.length < 2) return;

      for (let i = 0; i < wall.length - 1; i++) {
        const start = new THREE.Vector3(wall[i].x, wall[i].y, wall[i].z);
        const end = new THREE.Vector3(
          wall[i + 1].x,
          wall[i + 1].y,
          wall[i + 1].z
        );

        const wallHeight = 10;
        const direction = new THREE.Vector3().subVectors(end, start);
        const length = direction.length();
        direction.normalize();

        const wallGeometry = new THREE.BoxGeometry(length, wallHeight);
        const wallMaterial = new THREE.MeshBasicMaterial({
          color: "#aaa",
          transparent: true,
          opacity: 0.5,
        });

        const wallMesh = new THREE.Mesh(wallGeometry, wallMaterial);
        const midPoint = new THREE.Vector3()
          .addVectors(start, end)
          .multiplyScalar(0.5);
        wallMesh.position.set(midPoint.x, wallHeight / 2, midPoint.z);

        const quaternion = new THREE.Quaternion();
        quaternion.setFromUnitVectors(new THREE.Vector3(1, 0, 0), direction);
        wallMesh.quaternion.copy(quaternion);

        groupRef.current?.add(wallMesh);
      }
    });
  };

  return null;
}
