/**
 * This program has been developed by students from the bachelor Computer Science at
 * Utrecht University within the Software Project course.
 * © Copyright Utrecht University (Department of Information and Computing Sciences)
 */

/* istanbul ignore file */
/* The comment above was added so the code coverage wouldn't count this file towards code coverage.
 * We do not test components/renderfunctions/styling files.
 * See testing plan for more details.*/
import React, { useEffect } from 'react';
import { getCenter } from '@graphpolaris/shared/lib/schema/schema-utils';
import { EdgeProps } from 'reactflow';

/**
 * SelfEdge is used for edges that loop back to a node. This means the node is connected to itself.
 * It has a path that is altered depending on the algorithm in the SchemaViewModelImpl.
 * @param EdgeProps All the data that is stored inside of the React Flow edge.
 */
export function SelfEdge({
  id,
  source,
  target,
  sourceX,
  sourceY,
  targetX,
  targetY,
  style,
  data,
  markerEnd,
  sourcePosition,
  targetPosition,
}: EdgeProps) {
  const offset = 0;
  const setRelationNodePosition = data.setRelationNodePosition;

  const [centerX, centerY] = getCenter({
    sourceX,
    sourceY,
    targetX,
    targetY,
    offset,
    sourcePosition,
    targetPosition,
  });

  /**
   * Function called after every render. For the first render the relation node is created here, because it needs the centerX and centerY.
   * This function is created in the viewmodel and given to the data of the edge when it is created.
   */
  useEffect(() => {
    if (!data.created) {
      setRelationNodePosition(centerX, centerY, id, source, target, data.attributes);
      data.created = true;
    }
  });

  return (
    <g strokeWidth={0.5} style={{ pointerEvents: 'none' }}>
      <path
        type="smoothstep"
        id={id}
        fill="none"
        strokeWidth={0.5}
        style={style}
        // The d is used to create the path for the edge.
        d={`M${sourceX},${sourceY}h ${-data.d} v ${data.d} L ${targetX + data.d},${targetY + data.d} v ${-data.d} h ${-data.d}`}
        markerEnd={markerEnd}
      />
    </g>
  );
}