<!DOCTYPE html>
<html lang="en">
<head>
  <style>
    body { margin: 0; }
    #3d-graph { width: 100vw; height: 100vh; }
    .tooltip {
      position: absolute;
      background-color: rgba(255, 255, 255, 0.8);
      padding: 10px;
      border-radius: 5px;
      pointer-events: none;
      z-index: 10;
      display: none;
    }
    #node-details {
      position: fixed;
      top: 20px;
      left: 20px;
      background-color: white;
      padding: 20px;
      border-radius: 8px;
      box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
      display: none;
    }
    #close-tooltip {
      position: absolute;
      top: -5px;
      right: -5px;
      background-color: red;
      color: white;
      padding: 2px 6px;
      border-radius: 50%;
      cursor: pointer;
    }
  </style>
  <!-- Load the ForceGraph library -->
  <script src="https://cdn.jsdelivr.net/npm/3d-force-graph@latest/dist/3d-force-graph.min.js"></script>
</head>
<body>
  <div id="3d-graph"></div>
  <div class="tooltip" id="node-tooltip">
    <span id="close-tooltip">&times;</span>
  </div>
  <div id="node-details">
    <h3>Node Details</h3>
    <pre id="node-details-content"></pre>
  </div>
  <script>
    async function fetchData() {
      try {
        const response = await fetch('/data/policymap.json');
        const textData = await response.text();
        const jsonData = textData.trim().split('\n').map(line => JSON.parse(line));
        const nodes = [];
        const links = [];
        jsonData.forEach(item => {
          if (item.labels) {
            const id = item.id || item.properties.id;
            let name = '';
            let title = '';
            if (item.properties.name) {
              name = item.properties.name;
            } else if (item.properties.title) {
              title = item.properties.title;
            }
            nodes.push({
              id: id,
              name: name,
              title: title,
              type: item.labels[0],
              properties: item.properties
            });
          } else if (item.start.id && item.end.id) {
            links.push({
              source: item.start.id,
              target: item.end.id,
              value: item?.weight || 1,
              label: item.label
            });
          }
        });
        return {
          nodes: nodes,
          links: links
        };
      } catch (error) {
        console.error('Error fetching or transforming JSON:', error);
      }
    }

    async function initGraph() {
      const data = await fetchData();
      if (!data || !data.nodes || !data.links) {
        console.error('Data is incomplete:', data);
        return;
      }
      const elem = document.getElementById('3d-graph');
      const tooltip = document.getElementById('node-tooltip');
      const nodeDetailsContent = document.getElementById('node-details-content');
      const closeTooltipButton = document.getElementById('close-tooltip');

      closeTooltipButton.addEventListener('click', () => {
        tooltip.style.display = 'none';
      });

      const Graph = ForceGraph3D()(elem)
        .graphData(data)
        .nodeColor(node => {
          if (node.labels === 'Bill' || node.type === 'Legislation') {
            return 'pink';
          } else if (node.labels === 'Order') {
            return 'orange';
          } else if (node.type === 'Law') {
            return 'blue';
          } else if (node.type === 'Person') {
            return 'red';
          }
        })
        .nodeLabel(node => node.labels === 'Person' ? node.properties.name : node.properties.title || 'Node')
        .linkWidth(link => link.weight || 1)
        .onNodeHover(node => {
          if (node) {
            const properties = Object.entries(node.properties).map(([key, value]) => `${key}: ${value}`).join('<br>');
            tooltip.innerHTML = properties;
            tooltip.style.display = 'block';
          } else {
            tooltip.style.display = 'none';
          }
        })
        .onNodeDragEnd(() => tooltip.style.display = 'none')
        .onNodeClick(node => {
          const nodeDetailsDiv = document.getElementById('node-details');
          if (node) {
            nodeDetailsContent.innerHTML = JSON.stringify(node.properties, null, 2);
            nodeDetailsDiv.style.display = 'block';
          } else {
            nodeDetailsDiv.style.display = 'none';
          }
        });

      elem.addEventListener('mousemove', event => {
        const rect = elem.getBoundingClientRect();
        const x = event.clientX - rect.left;
        const y = event.clientY - rect.top;
        tooltip.style.transform = `translate(${x}px, ${y}px)`;
      });
    }

    initGraph();
  </script>
</body>
</html>
