// ── Cards (selected tables) ─────────────────────────────────────────
function renderSelectedCards() {
    const container = document.getElementById('selectedTablesContainer');
    container.querySelectorAll('.table-card').forEach(card => card.remove());

    let emptyMsg = document.getElementById('emptySelection');
    if (!emptyMsg) {
        emptyMsg = document.createElement('div');
        emptyMsg.id = 'emptySelection';
        emptyMsg.className = 'text-center py-5 text-muted';
        container.appendChild(emptyMsg);
    }

    if (window.selectedTablesSet.size === 0) {
        // Distinguish a genuinely EMPTY database (no tables yet) from one that just
        // has none selected — so a brand-new project shows a clear "create your
        // first table" call to action instead of "select from the (empty) panel".
        const dbHasTables = Array.isArray(window.allTables) ? window.allTables.length > 0 : true;
        emptyMsg.innerHTML = dbHasTables
            ? `<i class="bi bi-hand-index display-1 d-block mb-3"></i>
               <h5>Select tables from the left panel</h5>
               <p>Check the tables you want to work with.</p>`
            : `<i class="bi bi-database-add display-1 d-block mb-3" style="color:var(--pp-accent,#4f46e5)"></i>
               <h5>Create your first table</h5>
               <p class="mb-3">This database is empty. Add a table to start modelling your data —
               it appears in Data&nbsp;Studio too.</p>
               <button type="button" class="btn btn-primary"
                   onclick="(document.getElementById('btnCreateTable')||document.getElementById('btnCreateTable2'))?.click()">
                   <i class="bi bi-plus-lg me-1"></i> Create your first table</button>`;
        emptyMsg.style.display = 'block';
        return;
    }
    emptyMsg.style.display = 'none';

    // Build position map from savedPositions (global)
    const posArray = Array.isArray(savedPositions) ? savedPositions : [];
    const posMap = {};
    posArray.forEach(p => { if (p && p.table) posMap[p.table] = { left: p.left, top: p.top }; });

    const tables = Array.from(window.selectedTablesSet);
    let defaultLeft = 10, defaultTop = 10;
    const cardWidth = 260, cardHeight = 40;
    const containerWidth = container.clientWidth || 800;
    let column = 0, row = 0;

    tables.forEach(tableName => {
        const savedPos = posMap[tableName];
        let left, top;
        if (savedPos) {
            left = savedPos.left;
            top = savedPos.top;
        } else {
            left = defaultLeft + column * cardWidth;
            top = defaultTop + row * cardHeight;
            column++;
            if (left + cardWidth > containerWidth) {
                column = 0;
                row++;
                left = defaultLeft;
                top = defaultTop + row * cardHeight;
            }
        }
        left = Math.min(left, containerWidth - 250);
        top = Math.max(top, 0);
        const card = createTableCard(tableName, { left, top });
        container.appendChild(card);
    });

    attachDragEvents();
    setTimeout(() => {
        document.querySelectorAll('.table-card').forEach(card => resolveOverlaps(card));
    }, 50);

    const svg = document.getElementById('relationsSvg');
    if (svg) svg.parentNode.appendChild(svg);

    if (typeof loadAndDrawRelations === 'function') loadAndDrawRelations();
}

function createTableCard(tableName, position) {
    const card = document.createElement('div');
    card.className = 'table-card';
    card.draggable = true;
    card.dataset.table = tableName;
    card.style.position = 'absolute';
    card.style.left = (position.left || 10) + 'px';
    card.style.top = (position.top || 10) + 'px';

    const itemType = window.tableTypeMap[tableName] || 'TABLE';
    const isSystemTable = typeof window.isSystemGeneratedTable === 'function' && window.isSystemGeneratedTable(tableName);
    const isView = itemType === 'VIEW';
    const editLocked = isSystemTable || isView;
    if (isSystemTable) card.classList.add('system-table-card');
    const cardIcon = itemType === 'VIEW' ? 'bi-eye' : 'bi-table';
    const editTitle = isSystemTable
        ? 'System-generated table structure is protected'
        : (isView ? 'Views are based on SQL; recreate the view to change its definition' : 'Edit Structure');
    const header = document.createElement('div');
    header.className = 'card-header';
    header.innerHTML = `
        <span class="card-title"><i class="bi ${cardIcon} me-1"></i> ${tableName}${isSystemTable ? ' <span class="badge text-bg-light ms-1">system</span>' : ''}</span>
        <div class="btn-group">
            <button class="btn btn-sm btn-outline-secondary toggle-card" data-bs-toggle="tooltip" title="Expand or collapse this table card to inspect fields."><i class="bi ${window.expandedTablesSet?.has(tableName) ? 'bi-chevron-up' : 'bi-chevron-down'}"></i></button>
            <button class="btn btn-sm btn-outline-primary edit-card" data-bs-toggle="tooltip" title="${editTitle}" ${editLocked ? 'disabled' : ''}><i class="bi bi-pencil"></i></button>
        </div>
    `;

    const body = document.createElement('div');
    const shouldExpand = window.expandedTablesSet?.has(tableName);
    body.className = `card-body${shouldExpand ? '' : ' collapsed'}`;
    body.innerHTML = '<div class="text-center py-2 text-muted small">Click to load fields</div>';

    card.appendChild(header);
    card.appendChild(body);

    header.querySelector('.toggle-card').addEventListener('click', (e) => {
        e.stopPropagation();
        const icon = header.querySelector('.toggle-card i');
        body.classList.toggle('collapsed');
        icon.className = body.classList.contains('collapsed') ? 'bi bi-chevron-down' : 'bi bi-chevron-up';
        if (body.classList.contains('collapsed')) {
            window.expandedTablesSet?.delete(tableName);
        } else {
            window.expandedTablesSet?.add(tableName);
        }
        if (!body.classList.contains('collapsed') && body.querySelector('.text-muted')) {
            loadTableDetailsIntoCard(tableName, body);
        }
        if (typeof window.autoSaveTablesState === 'function') window.autoSaveTablesState();
    });

    header.querySelector('.edit-card').addEventListener('click', (e) => {
        e.stopPropagation();
        if (editLocked) {
            const message = isView
                ? 'Views are SQL definitions, not physical table structures. Recreate the custom or SQL view to change it.'
                : 'System-generated tables are grouped separately and protected from structural edits.';
            Swal.fire(isView ? 'View structure' : 'Protected table', message, 'info');
            return;
        }
        if (typeof openEditModal === 'function') openEditModal(tableName);
    });

    if (shouldExpand) {
        loadTableDetailsIntoCard(tableName, body);
    }

    return card;
}

async function loadTableDetailsIntoCard(tableName, bodyElement) {
    if (window.tableDetailsCache[tableName]) {
        populateCardBody(tableName, bodyElement, window.tableDetailsCache[tableName]);
        return;
    }
    bodyElement.innerHTML = '<div class="text-center py-2"><div class="spinner-border spinner-border-sm"></div></div>';
    try {
        const res = await fetch(`${baseUrl}/project/${projectSlug}/tables/details/${tableName}`);
        const data = await res.json();
        if (data.success) {
            window.tableDetailsCache[tableName] = { columns: data.columns, indexes: data.indexes };
            populateCardBody(tableName, bodyElement, window.tableDetailsCache[tableName]);
        } else {
            bodyElement.innerHTML = '<div class="alert alert-danger small">Failed</div>';
        }
    } catch (err) {
        bodyElement.innerHTML = '<div class="alert alert-danger small">Error</div>';
    }
}

function populateCardBody(tableName, body, details) {
    const { columns, indexes } = details;
    const pkColumns = columns.filter(c => c.COLUMN_KEY === 'PRI').map(c => c.COLUMN_NAME);
    const uniqueColumns = indexes.filter(i => i.NON_UNIQUE == 0 && !pkColumns.includes(i.COLUMN_NAME)).map(i => i.COLUMN_NAME);

    let html = `<div class="small mb-1 fw-bold">${columns.length} fields</div>`;
    columns.forEach(col => {
        const isPK = pkColumns.includes(col.COLUMN_NAME);
        const isUnique = uniqueColumns.includes(col.COLUMN_NAME);
        const isAuto = col.EXTRA === 'auto_increment';
        let icon = '<i class="bi bi-box fi"></i>';
        if (isPK) icon = '<i class="bi bi-key-fill fi text-warning"></i>';
        else if (isUnique) icon = '<i class="bi bi-shield-check fi text-info"></i>';
        else if (isAuto) icon = '<i class="bi bi-arrow-repeat fi text-success"></i>';
        html += `<div class="field-list-item" data-table="${tableName}" data-field="${col.COLUMN_NAME}" data-type="${col.DATA_TYPE}" style="cursor:pointer;">
            ${icon}
            <span class="fw-bold">${col.COLUMN_NAME}</span>
            <span class="text-muted">${col.COLUMN_TYPE}</span>
            ${isPK ? '<span class="badge bg-warning text-dark ms-auto">PK</span>' : ''}
        </div>`;
    });
    body.innerHTML = html;
}

// ── Drag and drop (free movement with overlap resolution) ──────────
let draggedCard = null;
let dragOffsetX = 0;
let dragOffsetY = 0;

function attachDragEvents() {
    const cards = document.querySelectorAll('.table-card');
    cards.forEach(card => {
        card.removeEventListener('dragstart', handleDragStart);
        card.removeEventListener('dragend', handleDragEnd);
        card.addEventListener('dragstart', handleDragStart);
        card.addEventListener('dragend', handleDragEnd);
    });
}

function handleDragStart(e) {
    draggedCard = this;
    const rect = this.getBoundingClientRect();
    dragOffsetX = e.clientX - rect.left;
    dragOffsetY = e.clientY - rect.top;
    this.classList.add('dragging');
    e.dataTransfer.effectAllowed = 'move';
    e.dataTransfer.setData('text/plain', this.dataset.table);
}

function handleDrop(e) {
    e.preventDefault();
    if (!draggedCard) return;
    const container = document.getElementById('selectedTablesContainer');
    const containerRect = container.getBoundingClientRect();
    let newLeft = e.clientX - containerRect.left - dragOffsetX;
    let newTop = e.clientY - containerRect.top - dragOffsetY;
    newLeft = Math.max(0, Math.min(newLeft, container.clientWidth - draggedCard.offsetWidth));
    newTop = Math.max(0, Math.min(newTop, container.clientHeight - draggedCard.offsetHeight));
    draggedCard.style.left = newLeft + 'px';
    draggedCard.style.top = newTop + 'px';
    resolveOverlaps(draggedCard);
    // Note: resolveOverlaps already calls drawRelationArrows, so no extra call needed.
    if (typeof window.autoSaveTablesState === 'function') window.autoSaveTablesState();
}

function handleDragEnd(e) {
    this.classList.remove('dragging');
    draggedCard = null;
    if (typeof drawRelationArrows === 'function') drawRelationArrows();
}

function resolveOverlaps(card) {
    const container = document.getElementById('selectedTablesContainer');
    const cards = container.querySelectorAll('.table-card');
    const cardRect = {
        left: parseInt(card.style.left),
        top: parseInt(card.style.top),
        width: card.offsetWidth,
        height: card.offsetHeight
    };
    let moved = true;
    for (let iter = 0; iter < 10 && moved; iter++) {
        moved = false;
        for (const other of cards) {
            if (other === card) continue;
            const otherRect = {
                left: parseInt(other.style.left),
                top: parseInt(other.style.top),
                width: other.offsetWidth,
                height: other.offsetHeight
            };
            if (rectsOverlap(cardRect, otherRect)) {
                const overlapRight = (otherRect.left + otherRect.width) - cardRect.left;
                const overlapDown = (otherRect.top + otherRect.height) - cardRect.top;
                if (overlapRight < overlapDown) {
                    cardRect.left = otherRect.left + otherRect.width + 10;
                } else {
                    cardRect.top = otherRect.top + otherRect.height + 10;
                }
                cardRect.left = Math.max(0, Math.min(cardRect.left, container.clientWidth - cardRect.width));
                cardRect.top = Math.max(0, Math.min(cardRect.top, container.clientHeight - cardRect.height));
                moved = true;
            }
        }
    }
    card.style.left = cardRect.left + 'px';
    card.style.top = cardRect.top + 'px';
    if (typeof drawRelationArrows === 'function') drawRelationArrows();
}

function rectsOverlap(r1, r2) {
    return !(r2.left > r1.left + r1.width ||
        r2.left + r2.width < r1.left ||
        r2.top > r1.top + r1.height ||
        r2.top + r2.height < r1.top);
}

// Attach global drop listener
document.getElementById('selectedTablesContainer')?.addEventListener('dragover', (e) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = 'move';
});
document.getElementById('selectedTablesContainer')?.addEventListener('drop', handleDrop);

// Expose functions globally
window.attachDragEvents = attachDragEvents;
window.resolveOverlaps = resolveOverlaps;
window.handleDragEnd = handleDragEnd;
