// The Lucia project.
// Copyright 2023-2026 DSP, inc.  All rights reserved.
// Authors:
//   chiayin.kuo@dsp.im (chiayin), 2023/1/31
//   imacat.yang@dsp.im (imacat), 2023/9/23
//   cindy.chang@dsp.im (Cindy Chang), 2024/5/30
/**
 * @module cytoscapeMapTrace Cytoscape.js process map rendering for
 *   individual trace visualization.
 */

import cytoscape from "cytoscape";
import dagre from "cytoscape-dagre";
import tippy from "tippy.js";
import "tippy.js/dist/tippy.css";
import { createTooltipContent } from "@/module/tooltipContent.js";

cytoscape.use(dagre);

/**
 * Creates a Cytoscape.js instance for rendering a single trace's
 * process map with left-to-right dagre layout and tooltips.
 *
 * @param {Array<Object>} nodes - Array of node data objects with
 *   backgroundColor, bordercolor, height, id, label, shape, and width.
 * @param {Array<Object>} edges - Array of edge data objects.
 * @param {HTMLElement} graphId - The DOM container element for Cytoscape.
 */
export default function cytoscapeMapTrace(nodes, edges, graphId) {
  // create Cytoscape
  let cy = cytoscape({
    container: graphId,
    elements: {
      nodes: nodes, // Node data
      edges: edges, // Edge data
    },
    layout: {
      name: "dagre",
      rankDir: "LR", // Vertical TB | Horizontal LR, variable from 'cytoscape-dagre' plugin
    },
    style: [
      // Node styling
      {
        selector: "node",
        style: {
          label: function (node) {
            // Text to display on the node
            let text = "";

            // node.data('label') accesses the original array value at node.data.label
            text =
              node.data("label").length > 18
                ? `${node.data("label").substr(0, 15)}...`
                : `${node.data("label")}`;

            return text;
          },
          "text-opacity": 0.7,
          "background-color": "data(backgroundColor)",
          "border-color": "data(bordercolor)",
          "border-width": "1",
          shape: "data(shape)",
          "text-wrap": "wrap",
          "text-max-width": 75,
          "text-halign": "center",
          "text-valign": "center",
          height: "data(height)",
          width: "data(width)",
          color: "#001933",
          "font-size": 14,
        },
      },
      // Edge styling
      {
        selector: "edge",
        style: {
          "curve-style": "taxi", // unbundled-bezier | taxi
          "target-arrow-shape": "triangle", // Arrow shape pointing to target: triangle
          color: "gray", //#0066cc
          width: "data(lineWidth)",
          "line-style": "data(style)",
        },
      },
      // Style changes when a node is selected
      {
        selector: "node:selected",
        style: {
          "border-color": "red",
          "border-width": "3",
        },
      },
    ],
  });

  // creat tippy.js
  let tip;
  cy.on("mouseover", "node", function (event) {
    tip?.destroy();
    const node = event.target;
    let ref = node.popperRef();
    let dummyDomEle = document.createElement("div");
    let content = createTooltipContent(node.data("label"));
    tip = new tippy(dummyDomEle, {
      // tippy props:
      getReferenceClientRect: ref.getBoundingClientRect,
      trigger: "manual",
      content: content,
    });
    tip.show();
  });
  cy.on("mouseout", "node", function (event) {
    tip?.destroy();
    tip = null;
  });
  return cy;
}
