// 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)
import {NodeToolbar, useReactFlow} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import {type JSX, useState} from "react";
import {createPortal} from "react-dom";
import styles from "../../VisProg.module.css";
import {NodeTooltips} from "../NodeRegistry.ts";
import useFlowStore from "../VisProgStores.tsx";


/**
 * Props for the Toolbar component.
 *
 * @property nodeId - The ID of the node this toolbar is attached to.
 * @property allowDelete - If `true`, the delete button is enabled; otherwise disabled.
 */
type ToolbarProps = {
  nodeId: string;
  allowDelete: boolean;
};

/**
 * Node Toolbar definition:
 * Handles: node deleting functionality
 * Can be integrated to any custom node component as a React component
 *
 * @param {string} nodeId - The ID of the node for which the toolbar is rendered.
 * @param {boolean} allowDelete - Enables or disables the delete functionality.
 * @returns {React.JSX.Element} A JSX element representing the toolbar.
 * @constructor
 */
export function Toolbar({nodeId, allowDelete}: ToolbarProps) {
  const {nodes, deleteNode} = useFlowStore();
  const { deleteElements } = useReactFlow();

  const deleteParentNode = () => {

    deleteNode(nodeId, deleteElements);
  };

  const nodeType = nodes.find((node) => node.id === nodeId)?.type as keyof typeof NodeTooltips;
  return (
    <NodeToolbar className={"flex-row align-center"}>
      <button className="Node-toolbar__deletebutton" onClick={deleteParentNode} disabled={!allowDelete}>delete</button>
      <Tooltip nodeType={nodeType}>
        <div className={styles.nodeToolbarTooltip}>i</div>
      </Tooltip>
    </NodeToolbar>);
}


type TooltipProps = {
  nodeType?: keyof typeof NodeTooltips;
  children: JSX.Element;
};


/**
 * A general tooltip component, that can be used as a wrapper for any component
 * that has a nodeType and a corresponding nodeTooltip.
 *
 * currently used to show tooltips for draggable-nodes and nodes inside the editor
 *
 * @param {"start" | "end" | "phase" | "norm" | "goal" | "trigger" | "basic_belief" | undefined} nodeType
 * @param {React.JSX.Element} children
 * @returns {React.JSX.Element}
 * @constructor
 */
export function Tooltip({ nodeType, children }: TooltipProps) {
  const [showTooltip, setShowTooltip] = useState(false);
  const [disabled , setDisabled] = useState(false);
  const [coords, setCoords] = useState({ top: 0, left: 0 });

  const updateTooltipPos = () => {
    const rect = document.getElementById("draggable-sidebar")!.getBoundingClientRect();
    setCoords({
      // Position exactly below the bottom edge of the draggable sidebar (plus a small gap)
      top: rect.bottom + 10,
      left: rect.left + rect.width / 2, // Keep it horizontally centered
    });
  };

  return nodeType ?
    (<div>
      <div
        onMouseDown={() => {
          updateTooltipPos();
          setShowTooltip(false);
          setDisabled(true);
        }}
        onMouseUp={() => {
          setDisabled(false);
        }}
        onMouseOver={() => {
          if (!disabled) {
            updateTooltipPos();
            setShowTooltip(true);
          }
        }}
        onMouseLeave={ () => setShowTooltip(false)}
      >
        {children}
      </div>
      {showTooltip && createPortal(
        <div
          className={"flex-row"}
          style={{
            pointerEvents: 'none',
            position: 'fixed',
            top: `${coords.top}px`,
            left: `${coords.left}px`,
            transform: 'translateX(-50%)', // Center based on the midpoint
          }}
        >
          <span className={styles.customTooltipHeader}>{nodeType}</span>
          <span className={styles.customTooltip}>
            {NodeTooltips[nodeType] || "Available for drag"}
          </span>
        </div>,
        document.body
      )}
    </div>
  ) : children
}
