{% extends 'layouts/base.html' %}
{% load i18n %}

{% block title %}{% trans "Staff Hierarchy - D3 Visualization" %}{% endblock %}

{% block content %}
<div class="container-fluid">
    <!-- Page Title -->
    <div class="page-title-box">
        <h4>{% trans "Staff Hierarchy" %}</h4>
        <ol class="breadcrumb">
            <li class="breadcrumb-item"><a href="{% url 'organizations:hospital_list' %}">{% trans "Organizations" %}</a></li>
            <li class="breadcrumb-item"><a href="{% url 'organizations:staff_list' %}">{% trans "Staff" %}</a></li>
            <li class="breadcrumb-item active">{% trans "Hierarchy" %}</li>
        </ol>
    </div>

    <!-- Statistics Cards -->
    <div class="row mb-4">
        <div class="col-md-4">
            <div class="stat-card">
                <div class="card-body">
                    <div class="stat-icon bg-teal">
                        <i class="bi bi-people"></i>
                    </div>
                    <div class="stat-value" id="totalStaff">-</div>
                    <div class="stat-label">{% trans "Total Staff" %}</div>
                </div>
            </div>
        </div>
        <div class="col-md-4">
            <div class="stat-card">
                <div class="card-body">
                    <div class="stat-icon bg-blue">
                        <i class="bi bi-diagram-3"></i>
                    </div>
                    <div class="stat-value" id="topManagers">-</div>
                    <div class="stat-label">{% trans "Top Managers" %}</div>
                </div>
            </div>
        </div>
        <div class="col-md-4">
            <div class="stat-card">
                <div class="card-body">
                    <div class="stat-icon bg-green">
                        <i class="bi bi-layers"></i>
                    </div>
                    <div class="stat-value" id="avgDepth">-</div>
                    <div class="stat-label">{% trans "Avg. Hierarchy Depth" %}</div>
                </div>
            </div>
        </div>
    </div>

    <!-- Controls -->
    <div class="card mb-4">
        <div class="card-body">
            <div class="row g-3">
                <div class="col-md-4">
                    <label class="form-label">{% trans "Search Staff" %}</label>
                    <div class="input-group">
                        <span class="input-group-text"><i class="bi bi-search"></i></span>
                        <input type="text" class="form-control" id="searchInput" placeholder="{% trans 'Search by name or ID' %}">
                    </div>
                </div>
                <div class="col-md-3">
                    <label class="form-label">{% trans "Layout" %}</label>
                    <select class="form-select" id="layoutSelect">
                        <option value="horizontal">{% trans "Horizontal" %}</option>
                        <option value="vertical">{% trans "Vertical" %}</option>
                        <option value="radial">{% trans "Radial" %}</option>
                    </select>
                </div>
                <div class="col-md-3">
                    <label class="form-label">{% trans "Node Size By" %}</label>
                    <select class="form-select" id="nodeSizeSelect">
                        <option value="fixed">{% trans "Fixed Size" %}</option>
                        <option value="team">{% trans "Team Size" %}</option>
                        <option value="level">{% trans "Hierarchy Level" %}</option>
                    </select>
                </div>
                <div class="col-md-2 d-flex align-items-end">
                    <button class="btn btn-primary w-100" id="resetZoom">
                        <i class="bi bi-zoom-in"></i> {% trans "Reset View" %}
                    </button>
                </div>
            </div>
        </div>
    </div>

    <!-- D3 Visualization Container -->
    <div class="card">
        <div class="card-header d-flex justify-content-between align-items-center">
            <h5 class="mb-0">
                <i class="bi bi-diagram-3"></i> {% trans "Organizational Chart" %}
            </h5>
            <div class="btn-group">
                <button class="btn btn-sm btn-outline-primary" id="expandAllBtn">
                    <i class="bi bi-plus-square"></i> {% trans "Expand All" %}
                </button>
                <button class="btn btn-sm btn-outline-primary" id="collapseAllBtn">
                    <i class="bi bi-dash-square"></i> {% trans "Collapse All" %}
                </button>
            </div>
        </div>
        <div class="card-body">
            <div id="hierarchy-chart" style="width: 100%; height: 800px; overflow: hidden;"></div>
        </div>
    </div>

    <!-- Instructions -->
    <div class="card mt-4">
        <div class="card-header">
            <i class="bi bi-info-circle"></i> {% trans "Instructions" %}
        </div>
        <div class="card-body">
            <ul class="mb-0">
                <li><strong>{% trans "Zoom & Pan" %}:</strong> {% trans "Use mouse wheel to zoom, click and drag to pan the chart" %}</li>
                <li><strong>{% trans "Expand/Collapse" %}:</strong> {% trans "Click on a node to expand or collapse its children" %}</li>
                <li><strong>{% trans "View Details" %}:</strong> {% trans "Double-click on a node to view full staff details" %}</li>
                <li><strong>{% trans "Search" %}:</strong> {% trans "Type in the search box to find a staff member. The chart will automatically navigate to them" %}</li>
                <li><strong>{% trans "Layout Options" %}:</strong> {% trans "Switch between horizontal, vertical, and radial layouts" %}</li>
            </ul>
        </div>
    </div>
</div>

<!-- D3 Hierarchy Visualization Script -->
<script>
document.addEventListener('DOMContentLoaded', function() {
    // Chart dimensions
    const margin = { top: 40, right: 120, bottom: 40, left: 120 };
    let width = document.getElementById('hierarchy-chart').offsetWidth - margin.left - margin.right;
    let height = 800 - margin.top - margin.bottom;
    
    // Create SVG
    const svg = d3.select("#hierarchy-chart")
        .append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", `translate(${margin.left},${margin.top})`);
    
    // Zoom behavior
    const zoom = d3.zoom()
        .scaleExtent([0.1, 3])
        .on("zoom", (event) => {
            svg.attr("transform", event.transform);
        });
    
    d3.select("svg").call(zoom);
    
    // Global variables
    let root = null;
    let treeLayout = null;
    let currentLayout = 'horizontal';
    let nodeSizeBy = 'fixed';
    let i = 0;
    
    // Fetch hierarchy data
    fetchHierarchyData();
    
    function fetchHierarchyData() {
        fetch('/organizations/api/staff/hierarchy/')
            .then(response => response.json())
            .then(data => {
                console.log('Hierarchy data received:', data);
                
                // Check if hierarchy is empty
                if (!data.hierarchy || data.hierarchy.length === 0) {
                    document.getElementById('totalStaff').textContent = '0';
                    document.getElementById('topManagers').textContent = '0';
                    document.getElementById('avgDepth').textContent = '0';
                    
                    // Show empty state message
                    const chartContainer = document.getElementById('hierarchy-chart');
                    chartContainer.innerHTML = `
                        <div style="display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; text-align: center; padding: 40px;">
                            <i class="bi bi-people" style="font-size: 64px; color: #ccc; margin-bottom: 20px;"></i>
                            <h4 style="color: #666; margin-bottom: 10px;">No Staff Data Available</h4>
                            <p style="color: #888; max-width: 400px; margin-bottom: 20px;">
                                The staff hierarchy is empty. Please import staff data using the CSV import command.
                            </p>
                            <div style="background: #f5f5f5; padding: 15px; border-radius: 8px; text-align: left; max-width: 500px;">
                                <strong>Import Staff Data:</strong>
                                <code style="display: block; margin-top: 8px; padding: 8px; background: #fff; border-radius: 4px; overflow-x: auto;">
                                    python manage.py import_staff_csv your_staff_data.csv
                                </code>
                            </div>
                        </div>
                    `;
                    return;
                }
                
                // Update statistics
                document.getElementById('totalStaff').textContent = data.statistics.total_staff.toLocaleString();
                document.getElementById('topManagers').textContent = data.statistics.top_managers.toLocaleString();
                document.getElementById('avgDepth').textContent = calculateAverageDepth(data.hierarchy).toFixed(1);
                
                // Create hierarchy
                const hierarchyData = {
                    name: "Organization",
                    children: data.hierarchy
                };
                
                root = d3.hierarchy(hierarchyData);
                root.x0 = height / 2;
                root.y0 = 0;
                
                // Only collapse nodes that actually have children and are at depth > 1
                root.descendants().forEach((d, i) => {
                    d.id = i;
                    // Only collapse if node has children and is deeper than first level
                    if (d.depth > 1 && d.children && d.children.length > 0) {
                        d._children = d.children;
                        d.children = null;
                    }
                });
                
                console.log('Root hierarchy:', root);
                console.log('Total nodes:', root.descendants().length);
                
                // Initial render
                update(root);
                
                // Center the view
                centerView();
            })
            .catch(error => {
                console.error('Error fetching hierarchy data:', error);
                
                // Show error message
                const chartContainer = document.getElementById('hierarchy-chart');
                chartContainer.innerHTML = `
                    <div style="display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; text-align: center; padding: 40px;">
                        <i class="bi bi-exclamation-triangle" style="font-size: 64px; color: #dc3545; margin-bottom: 20px;"></i>
                        <h4 style="color: #dc3545; margin-bottom: 10px;">Error Loading Hierarchy</h4>
                        <p style="color: #666; max-width: 400px;">
                            Failed to load hierarchy data. Please check your connection and try again.
                        </p>
                        <p style="color: #888; font-size: 14px;">
                            Error: ${error.message}
                        </p>
                    </div>
                `;
            });
    }
    
    function update(source) {
        // Get tree layout based on current orientation
        const duration = 500;
        
        // Assigns the x, y position for the nodes
        const treeData = treeLayout(root);
        
        // Compute the new tree layout
        const nodes = treeData.descendants();
        const links = treeData.links();
        
        // Normalize for fixed-depth
        nodes.forEach(d => {
            d.y = d.depth * 200;
        });
        
        // ****************** Nodes section ******************
        
        // Update the nodes
        const node = svg.selectAll('g.node')
            .data(nodes, d => d.id || (d.id = ++i));
        
        // Enter any new modes at the parent's previous position
        const nodeEnter = node.enter().append('g')
            .attr('class', 'node')
            .attr("transform", d => `translate(${source.y0},${source.x0})`)
            .on('click', click)
            .on('dblclick', d => {
                // Only navigate if node has a real ID (not virtual root)
                if (d.data && d.data.id && !d.data.is_virtual_root) {
                    window.location.href = `/organizations/staff/${d.data.id}/`;
                }
            });
        
        // Add circle for the nodes
        nodeEnter.append('circle')
            .attr('class', 'node')
            .attr('r', d => d.data.is_virtual_root ? 20 : 10)  // Larger for virtual root
            .style("fill", d => d.data.is_virtual_root ? "#666" : (d._children ? "var(--hh-primary)" : "var(--hh-success)"))
            .style("stroke", d => d.data.is_virtual_root ? "#999" : "var(--hh-primary)")
            .style("stroke-width", "2px")
            .style("cursor", d => d.data.is_virtual_root ? "default" : "pointer");
        
        // Add labels for the nodes
        nodeEnter.append('text')
            .attr("dy", ".35em")
            .attr("x", d => d.children || d._children ? -15 : 15)
            .attr("text-anchor", d => d.children || d._children ? "end" : "start")
            .text(d => {
                if (d.data.name === "Organization") return d.data.name;
                return d.data.name.length > 20 ? d.data.name.substring(0, 20) + '...' : d.data.name;
            })
            .style("fill-opacity", 0);
        
        // Add tooltip
        nodeEnter.append('title')
            .text(d => {
                if (!d.data || !d.data.name) return "Staff";
                if (d.data.name === "Organization") return d.data.name;
                return `${d.data.name}\n${d.data.job_title || ''}\nTeam: ${d.data.team_size || 0}`;
            });
        
        // UPDATE
        const nodeUpdate = nodeEnter.merge(node);
        
        // Transition to the proper position for the node
        nodeUpdate.transition()
            .duration(duration)
            .attr("transform", d => {
                if (currentLayout === 'horizontal') {
                    return `translate(${d.y},${d.x})`;
                } else if (currentLayout === 'vertical') {
                    return `translate(${d.x},${d.y})`;
                } else {
                    // Radial
                    const angle = (d.x - 90) * Math.PI / 180;
                    const radius = d.y;
                    return `translate(${radius * Math.cos(angle)},${radius * Math.sin(angle)})`;
                }
            });
        
        // Update the node attributes and style
        nodeUpdate.select('circle.node')
            .attr('r', d => getNodeRadius(d))
            .style("fill", d => {
                if (d.data.is_virtual_root) return "#666";
                return d._children ? "var(--hh-primary)" : "var(--hh-success)";
            })
            .style("stroke", d => d.data.is_virtual_root ? "#999" : "var(--hh-primary)")
            .attr('cursor', d => d.data.is_virtual_root ? "default" : "pointer");
        
        // Update the text
        nodeUpdate.select('text')
            .style("fill-opacity", 1)
            .attr("x", d => {
                if (currentLayout === 'horizontal') {
                    return d.children || d._children ? -15 : 15;
                } else if (currentLayout === 'vertical') {
                    return 0;
                } else {
                    // Radial
                    const angle = (d.x - 90) * Math.PI / 180;
                    return (d.children || d._children ? -1 : 1) * 15;
                }
            })
            .attr("dy", ".35em")
            .attr("text-anchor", d => {
                if (currentLayout === 'horizontal') {
                    return d.children || d._children ? "end" : "start";
                } else if (currentLayout === 'vertical') {
                    return "middle";
                } else {
                    // Radial
                    return d.children || d._children ? "end" : "start";
                }
            });
        
        // Remove any exiting nodes
        const nodeExit = node.exit().transition()
            .duration(duration)
            .attr("transform", d => `translate(${source.y},${source.x})`)
            .remove();
        
        nodeExit.select('circle')
            .attr('r', 1e-6);
        
        nodeExit.select('text')
            .style("fill-opacity", 1e-6);
        
        // ****************** Links section ******************
        
        // Update the links
        const link = svg.selectAll('path.link')
            .data(links, d => d.target.id);
        
        // Enter any new links at the parent's previous position
        const linkEnter = link.enter().insert('path', "g")
            .attr("class", "link")
            .attr('d', d => {
                const o = {x: source.x0, y: source.y0};
                return diagonal(o, o);
            })
            .style("fill", "none")
            .style("stroke", "#ccc")
            .style("stroke-width", "2px");
        
        // UPDATE
        const linkUpdate = linkEnter.merge(link);
        
        // Transition back to the parent element position
        linkUpdate.transition()
            .duration(duration)
            .attr('d', d => diagonal(d.source, d.target));
        
        // Remove any exiting links
        link.exit().transition()
            .duration(duration)
            .attr('d', d => {
                const o = {x: source.x, y: source.y};
                return diagonal(o, o);
            })
            .remove();
        
        // Store the old positions for transition
        nodes.forEach(d => {
            d.x0 = d.x;
            d.y0 = d.y;
        });
    }
    
    // Creates a curved (diagonal) path from parent to the child nodes
    function diagonal(s, d) {
        if (currentLayout === 'horizontal') {
            return `M ${s.y} ${s.x}
                    C ${(s.y + d.y) / 2} ${s.x},
                      ${(s.y + d.y) / 2} ${d.x},
                      ${d.y} ${d.x}`;
        } else if (currentLayout === 'vertical') {
            return `M ${s.x} ${s.y}
                    C ${s.x} ${(s.y + d.y) / 2},
                      ${d.x} ${(s.y + d.y) / 2},
                      ${d.x} ${d.y}`;
        } else {
            // Radial
            const sAngle = (s.x - 90) * Math.PI / 180;
            const dAngle = (d.x - 90) * Math.PI / 180;
            const sRadius = s.y;
            const dRadius = d.y;
            
            return `M ${sRadius * Math.cos(sAngle)} ${sRadius * Math.sin(sAngle)}
                    C ${sRadius * Math.cos(sAngle)} ${(sRadius + dRadius) / 2 * Math.sin(sAngle)},
                      ${dRadius * Math.cos(dAngle)} ${(sRadius + dRadius) / 2 * Math.sin(dAngle)},
                      ${dRadius * Math.cos(dAngle)} ${dRadius * Math.sin(dAngle)}`;
        }
    }
    
    // Toggle children on click
    function click(event, d) {
        if (d.children) {
            d._children = d.children;
            d.children = null;
        } else {
            d.children = d._children;
            d._children = null;
        }
        update(d);
    }
    
    // Get node radius based on nodeSizeBy setting
    function getNodeRadius(d) {
        // Virtual root always gets larger size
        if (d.data.is_virtual_root) {
            return 20;
        }
        
        if (nodeSizeBy === 'fixed') {
            return 10;
        } else if (nodeSizeBy === 'team') {
            const teamSize = d.data.team_size || 0;
            return Math.min(8 + Math.sqrt(teamSize) * 2, 25);
        } else if (nodeSizeBy === 'level') {
            return Math.max(10, 30 - d.depth * 3);
        }
        return 10;
    }
    
    // Calculate average depth
    function calculateAverageDepth(hierarchy) {
        let totalDepth = 0;
        let count = 0;
        
        function traverse(node, depth) {
            if (node.name !== "Organization") {
                totalDepth += depth;
                count++;
            }
            if (node.children) {
                node.children.forEach(child => traverse(child, depth + 1));
            }
        }
        
        hierarchy.forEach(root => traverse(root, 1));
        return count > 0 ? totalDepth / count : 0;
    }
    
    // Center the view
    function centerView() {
        const chart = d3.select("#hierarchy-chart svg");
        const zoomIdentity = d3.zoomIdentity.translate(width/2, height/2).scale(1);
        chart.transition().duration(750).call(zoom.transform, zoomIdentity);
    }
    
    // Search functionality
    document.getElementById('searchInput').addEventListener('keyup', function(e) {
        if (e.key === 'Enter') {
            const searchTerm = e.target.value.toLowerCase();
            if (!searchTerm || !root) return;
            
            // Find matching node
            let foundNode = null;
            root.descendants().forEach(d => {
                if (d.data.name && d.data.name.toLowerCase().includes(searchTerm) ||
                    d.data.employee_id && d.data.employee_id.toString().includes(searchTerm)) {
                    foundNode = d;
                }
            });
            
            if (foundNode) {
                // Expand all nodes leading to the found node
                let current = foundNode;
                while (current.parent) {
                    if (current.parent._children) {
                        current.parent.children = current.parent._children;
                        current.parent._children = null;
                    }
                    current = current.parent;
                }
                
                update(root);
                
                // Zoom to the found node
                const transform = d3.zoomIdentity
                    .translate(width / 2, height / 2)
                    .scale(1.5)
                    .translate(-foundNode.y, -foundNode.x);
                
                d3.select("svg").transition().duration(750).call(zoom.transform, transform);
                
                // Highlight the found node
                setTimeout(() => {
                    svg.selectAll('circle.node')
                        .style("stroke", d => d === foundNode ? "var(--hh-accent)" : "var(--hh-primary)")
                        .style("stroke-width", d => d === foundNode ? "4px" : "2px");
                }, 750);
                
                alert(`Found: ${foundNode.data.name}`);
            } else {
                alert('Staff member not found');
            }
        }
    });
    
    // Layout change
    document.getElementById('layoutSelect').addEventListener('change', function(e) {
        currentLayout = e.target.value;
        
        // Update tree layout based on orientation
        if (currentLayout === 'horizontal') {
            treeLayout = d3.tree().nodeSize([50, 200]);
        } else if (currentLayout === 'vertical') {
            treeLayout = d3.tree().nodeSize([200, 50]);
        } else {
            treeLayout = d3.tree().nodeSize([50, 200]);
        }
        
        update(root);
        centerView();
    });
    
    // Node size change
    document.getElementById('nodeSizeSelect').addEventListener('change', function(e) {
        nodeSizeBy = e.target.value;
        update(root);
    });
    
    // Expand all
    document.getElementById('expandAllBtn').addEventListener('click', function() {
        if (!root) return;
        
        root.descendants().forEach(d => {
            if (d._children) {
                d.children = d._children;
                d._children = null;
            }
        });
        update(root);
    });
    
    // Collapse all
    document.getElementById('collapseAllBtn').addEventListener('click', function() {
        if (!root) return;
        
        root.descendants().forEach(d => {
            if (d.children && d.depth > 0) {
                d._children = d.children;
                d.children = null;
            }
        });
        update(root);
    });
    
    // Reset zoom
    document.getElementById('resetZoom').addEventListener('click', function() {
        centerView();
    });
    
    // Initialize tree layout
    treeLayout = d3.tree().nodeSize([50, 200]);
    
    // Resize handler
    window.addEventListener('resize', function() {
        width = document.getElementById('hierarchy-chart').offsetWidth - margin.left - margin.right;
        d3.select("svg")
            .attr("width", width + margin.left + margin.right);
        if (root) update(root);
    });
});
</script>
{% endblock %}
