<!-- Fullscreen Connections Map Modal with Filters -->

<div id="connectionsModal" class="connections-modal" style="display: none;">
    <div class="connections-modal-header">
        <div class="connections-modal-title">
            <h2>Mapa Powiązań Norda Biznes</h2>
        </div>
        <div class="connections-modal-stats" id="modalStats">
            <span><strong id="modal-stat-companies">-</strong> firm</span>
            <span><strong id="modal-stat-people">-</strong> osób</span>
            <span><strong id="modal-stat-connections">-</strong> powiązań</span>
            <span class="stats-filtered" id="modal-stat-filtered" style="display: none;">
                (pokazano: <strong id="modal-stat-visible">-</strong>)
            </span>
        </div>
        <button class="connections-modal-close" onclick="closeConnectionsMap()" title="Zamknij (ESC)">
            <svg width="24" height="24" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
            </svg>
        </button>
    </div>

    <div class="connections-modal-content">
        <!-- Filter Panel -->
        <div class="connections-filter-panel">
            <div class="filter-section">
                <h4>Wyszukaj</h4>
                <div class="filter-search">
                    <input type="text" id="filterSearch" placeholder="Wpisz nazwę firmy lub osoby..."
                           oninput="handleFilterSearch(this.value)">
                    <div id="filterSearchResults" class="filter-search-results"></div>
                </div>
                <button class="filter-clear-btn" onclick="clearAllFilters()" id="clearFiltersBtn" style="display: none;">
                    Wyczyść filtry
                </button>
            </div>

            <div class="filter-section">
                <h4>Pokaż węzły</h4>
                <div class="filter-checkboxes">
                    <label class="filter-checkbox">
                        <input type="checkbox" id="filterCompanies" checked onchange="applyFilters()">
                        <span class="checkbox-mark" style="border-color: #4a90d9;"></span>
                        <span class="checkbox-dot" style="background: #4a90d9;"></span>
                        Firmy
                        <span class="filter-count" id="countCompanies">0</span>
                    </label>
                    <label class="filter-checkbox">
                        <input type="checkbox" id="filterPeople" checked onchange="applyFilters()">
                        <span class="checkbox-mark" style="border-color: #f39c12;"></span>
                        <span class="checkbox-dot" style="background: #f39c12;"></span>
                        Osoby
                        <span class="filter-count" id="countPeople">0</span>
                    </label>
                </div>
            </div>

            <div class="filter-section">
                <h4>Pokaż powiązania</h4>
                <div class="filter-checkboxes">
                    <label class="filter-checkbox">
                        <input type="checkbox" id="filterZarzad" checked onchange="applyFilters()">
                        <span class="checkbox-mark" style="border-color: #e74c3c;"></span>
                        <span class="checkbox-line-indicator" style="background: #e74c3c;"></span>
                        Zarząd
                        <span class="filter-count" id="countZarzad">0</span>
                    </label>
                    <label class="filter-checkbox">
                        <input type="checkbox" id="filterWspolnik" checked onchange="applyFilters()">
                        <span class="checkbox-mark" style="border-color: #2ecc71;"></span>
                        <span class="checkbox-line-indicator" style="background: #2ecc71;"></span>
                        Wspólnicy
                        <span class="filter-count" id="countWspolnik">0</span>
                    </label>
                    <label class="filter-checkbox">
                        <input type="checkbox" id="filterProkulrent" checked onchange="applyFilters()">
                        <span class="checkbox-mark" style="border-color: #f39c12;"></span>
                        <span class="checkbox-line-indicator" style="background: #f39c12;"></span>
                        Prokurenci
                        <span class="filter-count" id="countProkulrent">0</span>
                    </label>
                    <label class="filter-checkbox">
                        <input type="checkbox" id="filterJDG" checked onchange="applyFilters()">
                        <span class="checkbox-mark" style="border-color: #9b59b6;"></span>
                        <span class="checkbox-line-indicator" style="background: #9b59b6;"></span>
                        Właściciele JDG
                        <span class="filter-count" id="countJDG">0</span>
                    </label>
                </div>
            </div>

            <div class="filter-section">
                <h4>Widok</h4>
                <div class="filter-checkboxes">
                    <label class="filter-checkbox">
                        <input type="checkbox" id="filterLabels" onchange="toggleModalLabels()">
                        <span class="checkbox-icon">Aa</span>
                        Pokaż etykiety
                    </label>
                </div>
                <div class="filter-buttons">
                    <button class="filter-action-btn" onclick="modalFitToScreen()">
                        <svg width="14" height="14" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4"/>
                        </svg>
                        Dopasuj
                    </button>
                    <button class="filter-action-btn" onclick="modalResetZoom()">
                        <svg width="14" height="14" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
                        </svg>
                        Reset
                    </button>
                </div>
            </div>

            <div class="filter-section filter-legend">
                <h4>Legenda</h4>
                <div class="legend-items">
                    <div class="legend-row">
                        <span class="legend-dot" style="background: #4a90d9;"></span>
                        <span>Firma</span>
                    </div>
                    <div class="legend-row">
                        <span class="legend-dot" style="background: #f39c12;"></span>
                        <span>Osoba</span>
                    </div>
                </div>
            </div>

            <div class="filter-source">
                Źródło: <a href="https://ekrs.ms.gov.pl" target="_blank">ekrs.ms.gov.pl</a>,
                <a href="https://dane.biznes.gov.pl" target="_blank">dane.biznes.gov.pl</a>
            </div>
        </div>

        <!-- Graph Area -->
        <div class="connections-modal-body">
            <svg id="connections-graph-modal"></svg>

            <div class="connections-modal-loading" id="modalLoading">
                <div class="loading-spinner"></div>
                <span>Ładowanie danych...</span>
            </div>
        </div>
    </div>

    <div class="connections-modal-tooltip" id="modalTooltip"></div>
</div>

<style>
.connections-modal {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    background: #0f172a;
    z-index: 10000;
    display: flex;
    flex-direction: column;
}

.connections-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 20px;
    background: #1e293b;
    border-bottom: 1px solid #334155;
    flex-shrink: 0;
}

.connections-modal-title h2 {
    margin: 0;
    font-size: 16px;
    color: #f8fafc;
    font-weight: 600;
}

.connections-modal-stats {
    display: flex;
    gap: 20px;
    font-size: 13px;
    color: #94a3b8;
}

.connections-modal-stats strong {
    color: #4ade80;
    font-weight: 600;
}

.stats-filtered {
    color: #60a5fa;
}

.connections-modal-close {
    background: transparent;
    border: none;
    color: #94a3b8;
    cursor: pointer;
    padding: 6px;
    border-radius: 6px;
    transition: all 0.2s;
}

.connections-modal-close:hover {
    background: #334155;
    color: #f8fafc;
}

.connections-modal-content {
    flex: 1;
    display: flex;
    overflow: hidden;
}

/* Filter Panel */
.connections-filter-panel {
    width: 240px;
    background: #1e293b;
    border-right: 1px solid #334155;
    padding: 16px;
    overflow-y: auto;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.filter-section h4 {
    margin: 0 0 10px 0;
    font-size: 12px;
    font-weight: 600;
    color: #94a3b8;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.filter-search {
    position: relative;
}

.filter-search input {
    width: 100%;
    padding: 8px 12px;
    background: #0f172a;
    border: 1px solid #475569;
    border-radius: 6px;
    color: #f8fafc;
    font-size: 13px;
    outline: none;
    box-sizing: border-box;
}

.filter-search input:focus {
    border-color: #60a5fa;
}

.filter-search input::placeholder {
    color: #64748b;
}

.filter-search-results {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: #1e293b;
    border: 1px solid #475569;
    border-radius: 6px;
    margin-top: 4px;
    max-height: 200px;
    overflow-y: auto;
    z-index: 100;
    display: none;
}

.filter-search-results.show {
    display: block;
}

.filter-search-item {
    padding: 8px 12px;
    cursor: pointer;
    font-size: 13px;
    color: #e2e8f0;
    display: flex;
    align-items: center;
    gap: 8px;
    border-bottom: 1px solid #334155;
}

.filter-search-item:last-child {
    border-bottom: none;
}

.filter-search-item:hover {
    background: #334155;
}

.filter-search-item .item-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}

.filter-search-item .item-type {
    font-size: 10px;
    color: #64748b;
    margin-left: auto;
}

.filter-clear-btn {
    width: 100%;
    padding: 8px;
    margin-top: 8px;
    background: #dc2626;
    border: none;
    border-radius: 6px;
    color: white;
    font-size: 12px;
    cursor: pointer;
    transition: background 0.2s;
}

.filter-clear-btn:hover {
    background: #ef4444;
}

.filter-checkboxes {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.filter-checkbox {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    font-size: 13px;
    color: #e2e8f0;
}

.filter-checkbox input {
    display: none;
}

.checkbox-mark {
    width: 16px;
    height: 16px;
    border: 2px solid;
    border-radius: 4px;
    position: relative;
    transition: all 0.2s;
}

.filter-checkbox input:checked + .checkbox-mark {
    background: currentColor;
}

.filter-checkbox input:checked + .checkbox-mark::after {
    content: '✓';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    color: #0f172a;
    font-size: 11px;
    font-weight: bold;
}

.checkbox-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    margin-left: -4px;
}

.checkbox-line {
    width: 16px;
    height: 3px;
    border-radius: 2px;
}

.checkbox-line-indicator {
    width: 12px;
    height: 3px;
    border-radius: 2px;
    margin-left: -4px;
}

.filter-count {
    margin-left: auto;
    background: #334155;
    color: #94a3b8;
    font-size: 11px;
    padding: 2px 6px;
    border-radius: 10px;
    min-width: 20px;
    text-align: center;
    font-weight: 500;
}

.checkbox-icon {
    width: 16px;
    height: 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    font-weight: bold;
    color: #64748b;
    background: #334155;
    border-radius: 3px;
}

.filter-checkbox input:checked ~ .checkbox-icon {
    background: #60a5fa;
    color: #0f172a;
}

.filter-buttons {
    display: flex;
    gap: 8px;
    margin-top: 8px;
}

.filter-action-btn {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding: 8px;
    background: #334155;
    border: none;
    border-radius: 6px;
    color: #e2e8f0;
    font-size: 12px;
    cursor: pointer;
    transition: background 0.2s;
}

.filter-action-btn:hover {
    background: #475569;
}

.filter-legend {
    margin-top: auto;
    padding-top: 16px;
    border-top: 1px solid #334155;
}

.legend-items {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.legend-row {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    color: #94a3b8;
}

.legend-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
}

.filter-source {
    font-size: 10px;
    color: #64748b;
    padding-top: 12px;
    border-top: 1px solid #334155;
}

.filter-source a {
    color: #60a5fa;
    text-decoration: none;
}

/* Graph Area */
.connections-modal-body {
    flex: 1;
    position: relative;
    overflow: hidden;
    background: #0f172a;
}

#connections-graph-modal {
    width: 100%;
    height: 100%;
    display: block;
}

.connections-modal-loading {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    align-items: center;
    gap: 12px;
    color: #94a3b8;
    font-size: 14px;
}

.loading-spinner {
    width: 24px;
    height: 24px;
    border: 3px solid #475569;
    border-top-color: #4ade80;
    border-radius: 50%;
    animation: spin 1s linear infinite;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

/* Tooltip */
.connections-modal-tooltip {
    position: fixed;
    padding: 12px 16px;
    background: rgba(15, 23, 42, 0.95);
    border: 1px solid #4a90d9;
    border-radius: 8px;
    color: #f8fafc;
    font-size: 13px;
    pointer-events: none;
    z-index: 10001;
    max-width: 300px;
    box-shadow: 0 4px 20px rgba(0,0,0,0.4);
    display: none;
}

.connections-modal-tooltip h4 {
    margin: 0 0 8px 0;
    color: #60a5fa;
    font-size: 14px;
}

.connections-modal-tooltip p {
    margin: 4px 0;
    color: #cbd5e1;
}

.connections-modal-tooltip .role-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 4px;
    font-size: 11px;
    margin: 2px 4px 2px 0;
    color: white;
}

.connections-modal-tooltip .role-badge.zarzad { background: #e74c3c; }
.connections-modal-tooltip .role-badge.wspolnik { background: #2ecc71; }
.connections-modal-tooltip .role-badge.prokurent { background: #f39c12; }
.connections-modal-tooltip .role-badge.wlasciciel_jdg { background: #9b59b6; }

/* Graph styles */
.modal-node-company, .modal-node-person { cursor: pointer; }
.modal-link { stroke-opacity: 0.6; }
.modal-link.zarzad { stroke: #e74c3c; }
.modal-link.wspolnik { stroke: #2ecc71; }
.modal-link.prokurent { stroke: #f39c12; }
.modal-link.wlasciciel_jdg { stroke: #9b59b6; }

.modal-node-label {
    font-size: 9px;
    fill: #94a3b8;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.2s;
}

.modal-node-label.show-labels {
    opacity: 1;
}

.modal-node-label.hover-visible {
    opacity: 1;
    fill: #f8fafc;
    font-weight: 500;
}

/* Responsive */
@media (max-width: 768px) {
    .connections-filter-panel {
        width: 200px;
    }
}
</style>

<script>
// Connections Map Modal with Filters
let modalSimulation, modalSvg, modalG, modalZoom;
let modalGraphData = { nodes: [], links: [] };
let modalFilteredData = { nodes: [], links: [] };
let modalInitialized = false;
let modalShowLabels = false;
let selectedNodeId = null;

function openConnectionsMap() {
    const modal = document.getElementById('connectionsModal');
    modal.style.display = 'flex';
    document.body.style.overflow = 'hidden';

    if (!modalInitialized) {
        loadModalData();
    } else {
        setTimeout(modalFitToScreen, 100);
    }

    document.addEventListener('keydown', handleModalEsc);
}

function closeConnectionsMap() {
    const modal = document.getElementById('connectionsModal');
    modal.style.display = 'none';
    document.body.style.overflow = '';
    document.removeEventListener('keydown', handleModalEsc);

    // Close search results
    document.getElementById('filterSearchResults').classList.remove('show');
}

function handleModalEsc(e) {
    if (e.key === 'Escape') closeConnectionsMap();
}

async function loadModalData() {
    try {
        const response = await fetch('/api/connections');
        const data = await response.json();

        if (!data.success) throw new Error('Failed to load data');

        modalGraphData = data;
        modalFilteredData = { nodes: [...data.nodes], links: [...data.links] };

        updateStats();

        document.getElementById('modalLoading').style.display = 'none';

        applyFilters();
        modalInitialized = true;

    } catch (error) {
        console.error('Error loading data:', error);
        document.getElementById('modalLoading').innerHTML = '<span style="color: #ef4444;">Błąd ładowania danych</span>';
    }
}

function updateStats() {
    document.getElementById('modal-stat-companies').textContent = modalGraphData.stats.companies;
    document.getElementById('modal-stat-people').textContent = modalGraphData.stats.people;
    document.getElementById('modal-stat-connections').textContent = modalGraphData.stats.connections;

    const visibleNodes = modalFilteredData.nodes.length;
    const totalNodes = modalGraphData.nodes.length;

    if (visibleNodes < totalNodes) {
        document.getElementById('modal-stat-filtered').style.display = 'inline';
        document.getElementById('modal-stat-visible').textContent = visibleNodes;
    } else {
        document.getElementById('modal-stat-filtered').style.display = 'none';
    }

    // Update filter counts
    updateFilterCounts();
}

function updateFilterCounts() {
    // Count nodes by type (from filtered data)
    const companyCount = modalFilteredData.nodes.filter(n => n.type === 'company').length;
    const personCount = modalFilteredData.nodes.filter(n => n.type === 'person').length;

    // Count links by category (from filtered data)
    const zarzadCount = modalFilteredData.links.filter(l => l.category === 'zarzad').length;
    const wspolnikCount = modalFilteredData.links.filter(l => l.category === 'wspolnik').length;
    const prokurentCount = modalFilteredData.links.filter(l => l.category === 'prokurent').length;
    const jdgCount = modalFilteredData.links.filter(l => l.category === 'wlasciciel_jdg').length;

    // Update DOM
    document.getElementById('countCompanies').textContent = companyCount;
    document.getElementById('countPeople').textContent = personCount;
    document.getElementById('countZarzad').textContent = zarzadCount;
    document.getElementById('countWspolnik').textContent = wspolnikCount;
    document.getElementById('countProkulrent').textContent = prokurentCount;
    document.getElementById('countJDG').textContent = jdgCount;
}

function handleFilterSearch(query) {
    const resultsDiv = document.getElementById('filterSearchResults');

    if (query.length < 2) {
        resultsDiv.classList.remove('show');
        return;
    }

    const q = query.toLowerCase();
    const matches = modalGraphData.nodes
        .filter(n => n.name.toLowerCase().includes(q))
        .slice(0, 10);

    if (matches.length === 0) {
        resultsDiv.innerHTML = '<div class="filter-search-item" style="color: #64748b;">Brak wyników</div>';
    } else {
        resultsDiv.innerHTML = matches.map(n => `
            <div class="filter-search-item" onclick="selectNode('${n.id}')">
                <span class="item-dot" style="background: ${n.type === 'company' ? '#4a90d9' : '#f39c12'};"></span>
                <span>${escapeHtmlModal(n.name)}</span>
                <span class="item-type">${n.type === 'company' ? 'Firma' : 'Osoba'}</span>
            </div>
        `).join('');
    }

    resultsDiv.classList.add('show');
}

function escapeHtmlModal(text) {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
}

function selectNode(nodeId) {
    selectedNodeId = nodeId;
    document.getElementById('filterSearchResults').classList.remove('show');
    document.getElementById('clearFiltersBtn').style.display = 'block';

    const node = modalGraphData.nodes.find(n => n.id === nodeId);
    if (node) {
        document.getElementById('filterSearch').value = node.name;
    }

    applyFilters();
}

function clearAllFilters() {
    selectedNodeId = null;
    document.getElementById('filterSearch').value = '';
    document.getElementById('clearFiltersBtn').style.display = 'none';

    // Reset checkboxes
    document.getElementById('filterCompanies').checked = true;
    document.getElementById('filterPeople').checked = true;
    document.getElementById('filterZarzad').checked = true;
    document.getElementById('filterWspolnik').checked = true;
    document.getElementById('filterProkulrent').checked = true;
    document.getElementById('filterJDG').checked = true;

    applyFilters();
}

function applyFilters() {
    const showCompanies = document.getElementById('filterCompanies').checked;
    const showPeople = document.getElementById('filterPeople').checked;
    const showZarzad = document.getElementById('filterZarzad').checked;
    const showWspolnik = document.getElementById('filterWspolnik').checked;
    const showProkulrent = document.getElementById('filterProkulrent').checked;
    const showJDG = document.getElementById('filterJDG').checked;

    // Filter links by category
    let filteredLinks = modalGraphData.links.filter(l => {
        if (l.category === 'zarzad' && !showZarzad) return false;
        if (l.category === 'wspolnik' && !showWspolnik) return false;
        if (l.category === 'prokurent' && !showProkulrent) return false;
        if (l.category === 'wlasciciel_jdg' && !showJDG) return false;
        return true;
    });

    // If a specific node is selected, show only its connections
    if (selectedNodeId) {
        filteredLinks = filteredLinks.filter(l =>
            l.source === selectedNodeId || l.target === selectedNodeId ||
            l.source.id === selectedNodeId || l.target.id === selectedNodeId
        );
    }

    // Get node IDs that are connected
    const connectedNodeIds = new Set();
    filteredLinks.forEach(l => {
        const sourceId = typeof l.source === 'object' ? l.source.id : l.source;
        const targetId = typeof l.target === 'object' ? l.target.id : l.target;
        connectedNodeIds.add(sourceId);
        connectedNodeIds.add(targetId);
    });

    // Filter nodes
    let filteredNodes = modalGraphData.nodes.filter(n => {
        // Must be connected (or be the selected node)
        if (!connectedNodeIds.has(n.id) && n.id !== selectedNodeId) return false;

        // Type filter
        if (n.type === 'company' && !showCompanies) return false;
        if (n.type === 'person' && !showPeople) return false;

        return true;
    });

    // Re-filter links to only include those between visible nodes
    const visibleNodeIds = new Set(filteredNodes.map(n => n.id));
    filteredLinks = filteredLinks.filter(l => {
        const sourceId = typeof l.source === 'object' ? l.source.id : l.source;
        const targetId = typeof l.target === 'object' ? l.target.id : l.target;
        return visibleNodeIds.has(sourceId) && visibleNodeIds.has(targetId);
    });

    // Deep copy nodes to avoid mutation issues
    modalFilteredData = {
        nodes: filteredNodes.map(n => ({...n})),
        links: filteredLinks.map(l => ({
            ...l,
            source: typeof l.source === 'object' ? l.source.id : l.source,
            target: typeof l.target === 'object' ? l.target.id : l.target
        }))
    };

    updateStats();
    initModalGraph(modalFilteredData.nodes, modalFilteredData.links);
}

function initModalGraph(nodes, links) {
    const container = document.querySelector('.connections-modal-body');
    const width = container.clientWidth;
    const height = container.clientHeight;

    modalSvg = d3.select('#connections-graph-modal')
        .attr('width', width)
        .attr('height', height);

    modalSvg.selectAll('*').remove();

    if (nodes.length === 0) {
        modalSvg.append('text')
            .attr('x', width / 2)
            .attr('y', height / 2)
            .attr('text-anchor', 'middle')
            .attr('fill', '#64748b')
            .text('Brak danych do wyświetlenia');
        return;
    }

    modalZoom = d3.zoom()
        .scaleExtent([0.1, 4])
        .on('zoom', (event) => {
            modalG.attr('transform', event.transform);
        });

    modalSvg.call(modalZoom);
    modalG = modalSvg.append('g');

    // Adjust simulation based on node count
    const nodeCount = nodes.length;
    const chargeStrength = nodeCount > 100 ? -80 : nodeCount > 50 ? -100 : -150;
    const linkDistance = nodeCount > 100 ? 40 : nodeCount > 50 ? 60 : 80;

    modalSimulation = d3.forceSimulation(nodes)
        .force('link', d3.forceLink(links).id(d => d.id).distance(linkDistance).strength(0.7))
        .force('charge', d3.forceManyBody().strength(chargeStrength).distanceMax(200))
        .force('center', d3.forceCenter(width / 2, height / 2))
        .force('collision', d3.forceCollide().radius(d => d.type === 'company' ? 12 : 8))
        .force('x', d3.forceX(width / 2).strength(0.02))
        .force('y', d3.forceY(height / 2).strength(0.02));

    // Links
    const link = modalG.append('g')
        .selectAll('line')
        .data(links)
        .join('line')
        .attr('class', d => `modal-link ${d.category}`)
        .attr('stroke-width', 1.5);

    // Nodes
    const node = modalG.append('g')
        .selectAll('g')
        .data(nodes)
        .join('g')
        .attr('class', d => d.type === 'company' ? 'modal-node-company' : 'modal-node-person')
        .call(modalDrag(modalSimulation));

    node.append('circle')
        .attr('r', d => {
            if (d.type === 'company') return 8;
            return 4 + Math.min((d.company_count || 1), 5);
        })
        .attr('fill', d => {
            if (d.id === selectedNodeId) return '#22c55e';
            return d.type === 'company' ? '#4a90d9' : '#f39c12';
        })
        .attr('stroke', d => d.id === selectedNodeId ? '#fff' : '#1e293b')
        .attr('stroke-width', d => d.id === selectedNodeId ? 2 : 1);

    // Labels
    node.append('text')
        .attr('class', 'modal-node-label' + (modalShowLabels ? ' show-labels' : ''))
        .attr('dx', 10)
        .attr('dy', 3)
        .text(d => d.name.length > 20 ? d.name.substring(0, 20) + '...' : d.name);

    // Tooltip & hover
    const tooltip = d3.select('#modalTooltip');

    node.on('mouseover', function(event, d) {
        // Highlight label on hover
        d3.select(this).select('.modal-node-label').classed('hover-visible', true);

        let html = `<h4>${d.name}</h4>`;

        if (d.type === 'company') {
            if (d.category) html += `<p>Kategoria: ${d.category}</p>`;
            if (d.city) html += `<p>Miasto: ${d.city}</p>`;

            const connected = links.filter(l => {
                const sId = typeof l.source === 'object' ? l.source.id : l.source;
                const tId = typeof l.target === 'object' ? l.target.id : l.target;
                return sId === d.id || tId === d.id;
            });

            if (connected.length > 0) {
                html += `<p style="margin-top: 8px; border-top: 1px solid #475569; padding-top: 8px;"><strong>Powiązania:</strong></p>`;
                connected.slice(0, 8).forEach(l => {
                    const sId = typeof l.source === 'object' ? l.source.id : l.source;
                    const person = sId === d.id ?
                        nodes.find(n => n.id === (typeof l.target === 'object' ? l.target.id : l.target)) :
                        nodes.find(n => n.id === sId);
                    if (person && person.type === 'person') {
                        html += `<span class="role-badge ${l.category}">${l.role}</span>${person.name}<br>`;
                    }
                });
                if (connected.length > 8) html += `<p style="color: #64748b;">...i ${connected.length - 8} więcej</p>`;
            }
        } else {
            // Get all connections (roles)
            const connected = links.filter(l => {
                const sId = typeof l.source === 'object' ? l.source.id : l.source;
                const tId = typeof l.target === 'object' ? l.target.id : l.target;
                return sId === d.id || tId === d.id;
            });

            // Count UNIQUE companies (not roles)
            const uniqueCompanyIds = new Set();
            connected.forEach(l => {
                const tId = typeof l.target === 'object' ? l.target.id : l.target;
                uniqueCompanyIds.add(tId);
            });
            const uniqueCompanyCount = uniqueCompanyIds.size;

            html += `<p>Powiązany z ${uniqueCompanyCount} firmami (${connected.length} ról)</p>`;

            if (connected.length > 0) {
                // Show ALL companies, no limit
                connected.forEach(l => {
                    const tId = typeof l.target === 'object' ? l.target.id : l.target;
                    const company = nodes.find(n => n.id === tId);
                    if (company && company.type === 'company') {
                        html += `<span class="role-badge ${l.category}">${l.role}</span>${company.name}<br>`;
                    }
                });
            }
            html += `<p style="margin-top: 8px; color: #60a5fa; font-size: 11px;">Kliknij, aby zobaczyć profil</p>`;
        }

        tooltip.html(html)
            .style('display', 'block')
            .style('left', (event.clientX + 15) + 'px')
            .style('top', (event.clientY - 10) + 'px');
    })
    .on('mousemove', (event) => {
        tooltip
            .style('left', (event.clientX + 15) + 'px')
            .style('top', (event.clientY - 10) + 'px');
    })
    .on('mouseout', function() {
        d3.select(this).select('.modal-node-label').classed('hover-visible', false);
        tooltip.style('display', 'none');
    })
    .on('click', (event, d) => {
        if (d.type === 'company' && d.slug) {
            closeConnectionsMap();
            window.location.href = `/company/${d.slug}`;
        } else if (d.type === 'person') {
            // Navigate to person profile
            const personId = d.id.replace('person_', '');
            closeConnectionsMap();
            window.location.href = `/osoba/${personId}`;
        }
    });

    modalSimulation.on('tick', () => {
        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('transform', d => `translate(${d.x},${d.y})`);
    });

    // Auto-fit
    setTimeout(modalFitToScreen, 1200);
}

function modalDrag(simulation) {
    function dragstarted(event) {
        if (!event.active) simulation.alphaTarget(0.3).restart();
        event.subject.fx = event.subject.x;
        event.subject.fy = event.subject.y;
    }
    function dragged(event) {
        event.subject.fx = event.x;
        event.subject.fy = event.y;
    }
    function dragended(event) {
        if (!event.active) simulation.alphaTarget(0);
        event.subject.fx = null;
        event.subject.fy = null;
    }
    return d3.drag()
        .on('start', dragstarted)
        .on('drag', dragged)
        .on('end', dragended);
}

function modalResetZoom() {
    if (!modalSvg) return;
    modalSvg.transition()
        .duration(750)
        .call(modalZoom.transform, d3.zoomIdentity);
}

function modalFitToScreen() {
    if (!modalFilteredData.nodes || modalFilteredData.nodes.length === 0 || !modalSvg) return;

    const container = document.querySelector('.connections-modal-body');
    const width = container.clientWidth;
    const height = container.clientHeight;

    let minX = Infinity, maxX = -Infinity;
    let minY = Infinity, maxY = -Infinity;

    modalFilteredData.nodes.forEach(n => {
        if (n.x !== undefined && n.y !== undefined) {
            minX = Math.min(minX, n.x);
            maxX = Math.max(maxX, n.x);
            minY = Math.min(minY, n.y);
            maxY = Math.max(maxY, n.y);
        }
    });

    if (minX === Infinity) return;

    const padding = 60;
    minX -= padding;
    maxX += padding;
    minY -= padding;
    maxY += padding;

    const graphWidth = maxX - minX;
    const graphHeight = maxY - minY;
    const scale = Math.min(width / graphWidth, height / graphHeight, 2.5);
    const centerX = (minX + maxX) / 2;
    const centerY = (minY + maxY) / 2;

    modalSvg.transition()
        .duration(750)
        .call(modalZoom.transform, d3.zoomIdentity
            .translate(width / 2, height / 2)
            .scale(scale)
            .translate(-centerX, -centerY));
}

function toggleModalLabels() {
    modalShowLabels = document.getElementById('filterLabels').checked;
    d3.selectAll('.modal-node-label').classed('show-labels', modalShowLabels);
}

// Close search results when clicking outside
document.addEventListener('click', function(e) {
    const searchDiv = document.querySelector('.filter-search');
    const resultsDiv = document.getElementById('filterSearchResults');
    if (searchDiv && resultsDiv && !searchDiv.contains(e.target)) {
        resultsDiv.classList.remove('show');
    }
});

// Handle window resize
window.addEventListener('resize', () => {
    const modal = document.getElementById('connectionsModal');
    if (modal && modal.style.display === 'flex' && modalFilteredData.nodes.length > 0) {
        initModalGraph(modalFilteredData.nodes, modalFilteredData.links);
    }
});
</script>
