import { useEffect, useState } from "react";
import { getLines } from "../../../../../services/factoryBuilder/lines/getLinesApi";
import * as THREE from "three";
import {
  useActiveLayer,
  useDeletedLines,
  useNewLines,
  useToggleView,
} from "../../../../../store/store";
import objectLinesToArray from "../lineConvertions/objectLinesToArray";
import { Html } from "@react-three/drei";
import * as Types from "../../../../../types/world/worldTypes";

const DistanceText = () => {
  const [lines, setLines] = useState<
    {
      distance: string;
      position: THREE.Vector3;
      userData: Types.Line;
      layer: string;
    }[]
  >([]);
  const { activeLayer } = useActiveLayer();
  const { toggleView } = useToggleView();
  const { newLines, setNewLines } = useNewLines();
  const { deletedLines, setDeletedLines } = useDeletedLines();

  useEffect(() => {
    const email = localStorage.getItem("email");
    if (!email) return;
    const organization = email.split("@")[1].split(".")[0];

    getLines(organization).then((data) => {
      data = objectLinesToArray(data);

      const lines = data
        .filter((line: Types.Line) => line[0][2] === activeLayer)
        .map((line: Types.Line) => {
          const point1 = new THREE.Vector3(
            line[0][0].x,
            line[0][0].y,
            line[0][0].z
          );
          const point2 = new THREE.Vector3(
            line[1][0].x,
            line[1][0].y,
            line[1][0].z
          );
          const distance = point1.distanceTo(point2);
          const midpoint = new THREE.Vector3()
            .addVectors(point1, point2)
            .divideScalar(2);
          return {
            distance: distance.toFixed(1),
            position: midpoint,
            userData: line,
            layer: activeLayer,
          };
        });
      setLines(lines);
    });
  }, [activeLayer]);

  useEffect(() => {
    if (newLines.length > 0) {
      if (newLines[0][0][2] !== activeLayer) return;
      const newLinesData = newLines.map((line: Types.Line) => {
        const point1 = new THREE.Vector3(
          line[0][0].x,
          line[0][0].y,
          line[0][0].z
        );
        const point2 = new THREE.Vector3(
          line[1][0].x,
          line[1][0].y,
          line[1][0].z
        );
        const distance = point1.distanceTo(point2);
        const midpoint = new THREE.Vector3()
          .addVectors(point1, point2)
          .divideScalar(2);

        return {
          distance: distance.toFixed(1),
          position: midpoint,
          userData: line,
          layer: activeLayer,
        };
      });
      setLines((prevLines) => [...prevLines, ...newLinesData]);
      setNewLines([]);
    }
  }, [newLines, activeLayer]);

  useEffect(() => {
    if ((deletedLines as Types.Lines).length > 0) {
      setLines((prevLines) =>
        prevLines.filter(
          (line) =>
            !deletedLines.some(
              (deletedLine: any) =>
                deletedLine[0][1] === line.userData[0][1] &&
                deletedLine[1][1] === line.userData[1][1]
            )
        )
      );
      setDeletedLines([]);
    }
  }, [deletedLines]);

  return (
    <>
      {toggleView && (
        <group name="Distance_Text">
          {lines.map((text) => (
            <Html
              // data
              key={`${text.userData[0][1]}_${text.userData[1][1]}`}
              userData={text.userData}
              position={[text.position.x, 1, text.position.z]}
              // class
              wrapperClass="distance-text-wrapper"
              className="distance-text"
              // other
              zIndexRange={[1, 0]}
              prepend
              sprite
            >
              <div
                key={`${text.userData[0][1]}_${text.userData[1][1]}`}
                className={`distance line-${text.userData[0][1]}_${text.userData[1][1]}_${text.layer}`}
              >
                {text.distance} m
              </div>
            </Html>
          ))}
        </group>
      )}
    </>
  );
};

export default DistanceText;
