(() => {
    'use strict';

    const svg = document.getElementById('dependency-graph-pro');
    const data = window.AXIOM_DEPENDENCY_GRAPH;

    if (!svg || !data || !Array.isArray(data.nodes)) {
        return;
    }

    const NS = 'http://www.w3.org/2000/svg';
    const width = 1200;
    const height = 620;
    let filter = 'ALL';

    const nodes = data.nodes.slice(0, 80);
    const nodeByKey = new Map(nodes.map(node => [String(node.key), node]));
    const edges = (data.edges || []).filter(edge =>
        nodeByKey.has(String(edge.source_key))
    );

    const selectedKey = svg.dataset.selectedKey || '';
    const centerX = width / 2;
    const centerY = height / 2;
    const radiusX = 470;
    const radiusY = 235;

    nodes.forEach((node, index) => {
        const angle = (Math.PI * 2 * index / Math.max(1, nodes.length)) - Math.PI / 2;
        node.x = centerX + Math.cos(angle) * radiusX;
        node.y = centerY + Math.sin(angle) * radiusY;
    });

    function element(name, attrs = {}) {
        const item = document.createElementNS(NS, name);
        Object.entries(attrs).forEach(([key, value]) => item.setAttribute(key, String(value)));
        return item;
    }

    function color(type) {
        if (type === 'CONFLICT') return '#dc2626';
        if (type === 'OPTIONAL') return '#d97706';
        return '#2563eb';
    }

    function nodeFill(node) {
        if (String(node.key) === selectedKey) return '#7c3aed';
        if (node.status === 'INSTALLED' || node.status === 'SYSTEM') return '#0f766e';
        if (node.status === 'UPDATE_AVAILABLE') return '#2563eb';
        return '#64748b';
    }

    function render() {
        svg.innerHTML = '';

        const defs = element('defs');
        ['REQUIRED', 'OPTIONAL', 'CONFLICT'].forEach(type => {
            const marker = element('marker', {
                id: `arrow-${type}`,
                viewBox: '0 0 10 10',
                refX: '9',
                refY: '5',
                markerWidth: '6',
                markerHeight: '6',
                orient: 'auto-start-reverse'
            });
            marker.appendChild(element('path', {
                d: 'M 0 0 L 10 5 L 0 10 z',
                fill: color(type)
            }));
            defs.appendChild(marker);
        });
        svg.appendChild(defs);

        const visibleEdges = edges.filter(edge =>
            filter === 'ALL' || String(edge.type) === filter
        );

        visibleEdges.forEach(edge => {
            const source = nodeByKey.get(String(edge.source_key));
            const target = nodeByKey.get(String(edge.target_key));

            if (!source || !target) return;

            const line = element('line', {
                x1: source.x,
                y1: source.y,
                x2: target.x,
                y2: target.y,
                stroke: color(String(edge.type)),
                'stroke-width': String(edge.type) === 'CONFLICT' ? '2.8' : '1.8',
                'stroke-dasharray': String(edge.type) === 'OPTIONAL' ? '7 5' : '0',
                opacity: '0.72',
                'marker-end': `url(#arrow-${edge.type})`
            });

            const title = element('title');
            title.textContent = `${edge.source_label} → ${edge.target_key} (${edge.type})`;
            line.appendChild(title);
            svg.appendChild(line);
        });

        nodes.forEach(node => {
            const group = element('g', {
                role: 'link',
                tabindex: '0',
                style: 'cursor:pointer'
            });

            const circle = element('circle', {
                cx: node.x,
                cy: node.y,
                r: String(node.key === selectedKey ? 27 : 22),
                fill: nodeFill(node),
                stroke: '#ffffff',
                'stroke-width': '4'
            });

            const label = element('text', {
                x: node.x,
                y: node.y + 39,
                'text-anchor': 'middle',
                'font-size': '11',
                'font-weight': '700',
                fill: '#173b5a'
            });
            label.textContent = String(node.label || node.key).slice(0, 28);

            const version = element('text', {
                x: node.x,
                y: node.y + 53,
                'text-anchor': 'middle',
                'font-size': '10',
                fill: '#64748b'
            });
            version.textContent = String(node.version || '');

            const title = element('title');
            title.textContent = `${node.label} · ${node.version} · ${node.status}`;

            group.append(circle, label, version, title);

            const open = () => {
                window.location.href =
                    `/public/administration/plateforme/packages/dependances?package_id=${encodeURIComponent(node.id)}`;
            };

            group.addEventListener('click', open);
            group.addEventListener('keydown', event => {
                if (event.key === 'Enter' || event.key === ' ') {
                    event.preventDefault();
                    open();
                }
            });

            svg.appendChild(group);
        });
    }

    document.querySelectorAll('[data-edge-filter]').forEach(button => {
        button.addEventListener('click', () => {
            filter = button.dataset.edgeFilter || 'ALL';
            document.querySelectorAll('[data-edge-filter]').forEach(item =>
                item.classList.toggle('active', item === button)
            );
            render();
        });
    });

    document.querySelector('[data-graph-reset]')?.addEventListener('click', () => {
        filter = 'ALL';
        document.querySelectorAll('[data-edge-filter]').forEach(item =>
            item.classList.toggle('active', item.dataset.edgeFilter === 'ALL')
        );
        render();
    });

    render();
})();
