import { lineVector, Pos, vectorAngle, verticalVector } from "@/utils/math";
import { onlyId, rangMod } from "@/utils/shared";
import { MathUtils } from "three";
import { ComponentSnapInfo } from ".";

export type BaseItem = {
  id: string;
  createTime: number;
  zIndex: number;
  lock: boolean,
  opacity: number
  ref: boolean
  listening?: boolean
};

export const getBaseItem = (): BaseItem => ({
  id: onlyId(),
  createTime: Date.now(),
  lock: false,
  zIndex: 0,
  opacity: 1,
  ref: false
});

export const getRectSnapPoints = (
  w: number,
  h: number,
  x = -w / 2,
  y = -h / 2
) => {
  const r = w + x;
  const b = h + y;
  return [
    { x: x, y: y },
    { x: r, y: y },
    { x: r, y: b },
    { x: x, y: b },
    { x: x + w / 2, y: y + h / 2 },
  ];
};


export const generateSnapInfos = (
  geo: (Pos & { view?: boolean })[],
  hvAxis = true,
  link = true,
  vertical = false,
): ComponentSnapInfo[] => {
  const len = geo.length;
  return geo.map((point, ndx) => {
    const links: Pos[] = [];
    const linkDirections: Pos[] = [];
    const linkAngle: number[] = [];

    const pushLink = (p: Pos) => {
      const prevVector = lineVector([point, p]);
      links.push(p);
      linkDirections.push(prevVector);
      linkAngle.push(
        rangMod(MathUtils.radToDeg(vectorAngle(prevVector)), 180),
      );
      if (vertical) {
        const vLine = verticalVector(prevVector)
        linkDirections.push(vLine);
        linkAngle.push(
          rangMod(MathUtils.radToDeg(vectorAngle(vLine)), 180),
        );
      }

    }

    if (link && geo.length > 1) {
      if (ndx > 0) {
        const prev = geo[rangMod(ndx - 1, len)];
        pushLink(prev)
      }
      if (ndx < len - 1) {
        const next = geo[rangMod(ndx + 1, len)];
        pushLink(next)
      }
    }
    if (hvAxis) {
      linkDirections.push({ x: 1, y: 0 }, { y: 1, x: 0 });
      linkAngle.push(0, 90);
    }

    return {
      point,
      links,
      linkDirections,
      linkAngle,
    };
  });
};
