<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Render Network</title>
    <!-- Include D3.js -->
    <script src="https://d3js.org/d3.v7.min.js"></script>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
        #chart {
            width: 100vw;
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .node {
            stroke: #fff;
            stroke-width: 1.5px;
            cursor: pointer; /* Change cursor to indicate interactivity */
        }
        .link {
            fill: none;
            stroke: #999;
            stroke-opacity: 0.6;
        }
        text {
            font-size: 12px;
        }
        /* Tooltip styles */
        .tooltip {
            position: absolute;
            padding: 10px;
            background-color: rgba(255, 255, 255, 0.9);
            border: 1px solid #ccc;
            pointer-events: none; /* Make sure the tooltip doesn't interfere with mouse events */
        }
    </style>
</head>
<body>
    <div id="chart"></div>

    <!-- Tooltip container -->
    <div class="tooltip" style="display: none;"></div>

    <script type="text/javascript">
        // Get container dimensions
        const chartContainer = d3.select("#chart");
        let width = parseInt(chartContainer.style("width"));
        let height = parseInt(chartContainer.style("height"));

        // Create SVG container
        const svg = chartContainer.append("svg")
            .attr("width", width)
            .attr("height", height);

        // Define simulation
        const simulation = d3.forceSimulation()
            .force("link", d3.forceLink().id(d => d.id).distance(100))
            .force("charge", d3.forceManyBody().strength(-500)) // Adjust charge strength for better distribution
            .force("center", d3.forceCenter(width / 2, height / 2));

        // Fetch network data from Flask endpoint
        d3.json('/person_network').then(function(data) {
            if (data.error) {
                console.error(data.error);
                return;
            }

            const nodesData = data.nodes;
            const linksData = data.links;

            console.log("Nodes:", nodesData);
            console.log("Links:", linksData);

            // Append links to the SVG container
            const link = svg.append("g")
                .attr("class", "links")
                .selectAll("line")
                .data(linksData)
                .enter()
                .append("line")
                .attr("class", "link");

            // Append nodes to the SVG container
            const node = svg.append("g")
                .attr("class", "nodes")
                .selectAll("circle")
                .data(nodesData)
                .enter()
                .append("circle")
                .attr("class", "node")
                .attr("r", d => d.group === 1 ? 8 : 6) // Larger circles for Person nodes
                .style("fill", d => d.group === 1 ? "green" : "lightblue") // Green for Person, light blue for others
                .call(d3.drag()
                    .on("start", dragstarted)
                    .on("drag", dragged)
                    .on("end", dragended))
                .on("click", showTooltip);

            // Append labels to the SVG container
            const label = svg.append("g")
                .attr("class", "labels")
                .selectAll("text")
                .data(nodesData)
                .enter()
                .append("text")
                .text(d => {
                    if (d.labels.includes('Person')) {
                        return d.name || 'Person';
                    } else if (['Legislation', 'Bill', 'Law'].some(label => d.labels.includes(label))) {
                        return d.title || 'Title';
                    }
                    // Fallback for other types
                    return Object.keys(d).filter(key => key !== 'labels').map(key => d[key]).join(', ') || 'Node';
                })
                .attr("dx", 10) // Offset from node
                .attr("dy", 4); // Offset from node

            // Initialize simulation with nodes and links
            simulation.nodes(nodesData)
                       .on("tick", ticked);
            simulation.force("link")
                       .links(linksData);

            function ticked() {
                link.attr("x1", d => d.source.x)
                    .attr("y1", d => d.source.y)
                    .attr("x2", d => d.target.x)
                    .attr("y2", d => d.target.y);

                node.attr("cx", d => Math.max(10, Math.min(width - 10, d.x)))
                    .attr("cy", d => Math.max(10, Math.min(height - 10, d.y)));

                label.attr("x", d => d.x)
                     .attr("y", d => d.y);
            }

            function dragstarted(event, d) {
                if (!event.active) simulation.alphaTarget(0.3).restart();
                d.fx = d.x;
                d.fy = d.y;
            }

            function dragged(event, d) {
                d.fx = event.x;
                d.fy = event.y;
            }

            function dragended(event, d) {
                if (!event.active) simulation.alphaTarget(0);
                d.fx = null;
                d.fy = null;
            }

            // Show tooltip on node click
            function showTooltip(event, d) {
                const tooltip = d3.select(".tooltip");
                tooltip.style("display", "block")
                        .html(Object.entries(d).map(([key, value]) => `<strong>${key}:</strong> ${value}`).join("<br />"))
                        .style("left", `${event.pageX}px`)
                        .style("top", `${event.pageY}px`);
            }

            // Hide tooltip on document click
            d3.select(document).on("click.tooltip", function() {
                const tooltip = d3.select(".tooltip");
                if (!d3.event.target.classList.contains("node")) {
                    tooltip.style("display", "none");
                }
            });

        }).catch(function(error) {
            console.error("Error fetching data:", error);
        });

        // Handle window resize
        window.addEventListener('resize', () => {
            width = parseInt(chartContainer.style("width"));
            height = parseInt(chartContainer.style("height"));

            svg.attr("width", width)
               .attr("height", height);

            simulation.force("center")
                       .x(width / 2)
                       .y(height / 2);
        });
    </script>
</body>
</html>
