// ── Diagram (tables, drag & drop, joins, arrows) ────────────────────

async function addTableToDiagram(tableName, selectAll = false, skipGridUpdate = false) {
    if (selectedTables.includes(tableName)) return;
    selectedTables.push(tableName);

    await getTableDetails(tableName);
    const columns = tableFieldCache[tableName] || [];

    const container = document.getElementById('diagramContainer');
    const card = document.createElement('div');
    card.className = 'diagram-table-card';
    card.dataset.table = tableName;

    const existing = container.querySelectorAll('.diagram-table-card');
    const cols = 2, cardW = 230, cardH = 200;
    const row = Math.floor(existing.length / cols);
    const col = existing.length % cols;
    card.style.left = (10 + col * cardW) + 'px';
    card.style.top = (10 + row * cardH) + 'px';

    const header = document.createElement('div');
    header.className = 'card-header';
    header.innerHTML = `${tableName} <span class="remove-table-btn" title="Remove">&times;</span>`;
    header.querySelector('.remove-table-btn').addEventListener('click', () => {
        card.remove();
        selectedTables = selectedTables.filter(t => t !== tableName);
        joins = joins.filter(j => j.leftTable !== tableName && j.rightTable !== tableName);
        drawJoinArrows();
        updateDesignerFromDiagram();
        updateJoinTip();
    });
    card.appendChild(header);

    const body = document.createElement('div');
    body.className = 'card-body';
    columns.forEach(col => {
        const div = document.createElement('div');
        div.className = 'form-check field-draggable';
        div.draggable = true;
        div.innerHTML = `<input class="form-check-input field-check" type="checkbox" id="chk_${tableName}_${col.COLUMN_NAME}" data-table="${tableName}" data-field="${col.COLUMN_NAME}">
                         <label class="form-check-label" for="chk_${tableName}_${col.COLUMN_NAME}">${col.COLUMN_NAME}</label>`;
        div.addEventListener('dragstart', (e) => {
            e.dataTransfer.setData('application/field', JSON.stringify({ table: tableName, field: col.COLUMN_NAME }));
            e.dataTransfer.effectAllowed = 'link';
        });
        body.appendChild(div);
    });
    card.appendChild(body);
    container.appendChild(card);

    makeDiagramCardDraggable(card, header);
    body.querySelectorAll('.field-check').forEach(cb => cb.addEventListener('change', () => updateDesignerFromDiagram()));

    card.addEventListener('dragover', (e) => e.preventDefault());
    card.addEventListener('drop', (e) => {
        e.preventDefault();
        const raw = e.dataTransfer.getData('application/field');
        if (!raw) return;
        const source = JSON.parse(raw);
        const targetField = e.target.closest('.field-draggable');
        if (!targetField) return;
        const targetTable = card.dataset.table;
        const targetFieldName = targetField.querySelector('.field-check')?.dataset.field;
        if (!targetFieldName) return;
        if (source.table === targetTable && source.field === targetFieldName) return;
        document.getElementById('joinLeftTable').value = source.table;
        document.getElementById('joinLeftField').value = source.field;
        document.getElementById('joinRightTable').value = targetTable;
        document.getElementById('joinRightField').value = targetFieldName;
        document.getElementById('joinInfoLeft').textContent = `${source.table}.${source.field}`;
        document.getElementById('joinInfoRight').textContent = `${targetTable}.${targetFieldName}`;
        // Fresh join → clear any edit state.
        const editId = document.getElementById('joinEditId'); if (editId) editId.value = '';
        document.getElementById('joinTypeSelect').value = 'INNER';
        document.getElementById('joinModalTitle').textContent = 'Create JOIN';
        document.getElementById('btnDeleteJoin')?.classList.add('d-none');
        new bootstrap.Modal(document.getElementById('joinModal')).show();
    });

    if (selectAll) body.querySelectorAll('.field-check').forEach(cb => cb.checked = true);
    if (!skipGridUpdate) updateDesignerFromDiagram();
    // Smart join: if this table has a foreign-key relationship with a table
    // already on the canvas, wire the join automatically (saves manual dragging).
    if (!skipGridUpdate && selectedTables.length > 1) autoJoinForTable(tableName);
    updateJoinTip();
}

// Auto-create INNER joins implied by foreign keys among the selected tables.
function autoJoinForTable(newTable) {
    let added = false;
    const tryAdd = (masterTable, masterField, detailTable, detailField) => {
        if (!masterTable || !detailTable || !selectedTables.includes(masterTable) || !selectedTables.includes(detailTable)) return;
        const dup = joins.some(j =>
            (j.leftTable === masterTable && j.leftField === masterField && j.rightTable === detailTable && j.rightField === detailField) ||
            (j.leftTable === detailTable && j.leftField === detailField && j.rightTable === masterTable && j.rightField === masterField));
        if (dup) return;
        joins.push({ id: 'join_' + Date.now() + '_' + Math.random().toString(36).slice(2, 6), type: 'INNER', leftTable: masterTable, leftField: masterField, rightTable: detailTable, rightField: detailField });
        added = true;
    };
    // FKs declared on the new table (it references a master already present)…
    (tableFkCache[newTable] || []).forEach(fk => tryAdd(fk.master_table, fk.master_field, fk.detail_table, fk.detail_field));
    // …and FKs on already-present tables that reference the new table.
    selectedTables.forEach(t => {
        if (t === newTable) return;
        (tableFkCache[t] || []).forEach(fk => { if (fk.master_table === newTable) tryAdd(fk.master_table, fk.master_field, fk.detail_table, fk.detail_field); });
    });
    if (added) {
        drawJoinArrows();
        if (typeof generateSql === 'function') generateSql();
        if (window.Swal) Swal.fire({ toast: true, position: 'top-end', icon: 'success', title: 'Auto-joined on foreign key', timer: 2200, showConfirmButton: false });
    }
}

// Single, shared drag state for all diagram cards. The document-level
// mousemove/mouseup listeners are installed ONCE (not per card), so removing
// and recreating cards — which happens on every SQL→Designer sync — never
// leaks listeners.
let _dragCard = null, _dragOffsetX = 0, _dragOffsetY = 0;
function _installCardDragListenersOnce() {
    if (window._ppCardDragWired) return;
    window._ppCardDragWired = true;
    document.addEventListener('mousemove', (e) => {
        if (!_dragCard) return;
        e.preventDefault();
        const container = document.getElementById('diagramContainer');
        if (!container) return;
        const cr = container.getBoundingClientRect();
        let left = e.clientX - cr.left - _dragOffsetX;
        let top = e.clientY - cr.top - _dragOffsetY;
        left = Math.max(0, Math.min(left, container.clientWidth - _dragCard.offsetWidth));
        top = Math.max(0, Math.min(top, container.clientHeight - _dragCard.offsetHeight));
        _dragCard.style.left = left + 'px';
        _dragCard.style.top = top + 'px';
        drawJoinArrows();
    });
    document.addEventListener('mouseup', () => {
        if (!_dragCard) return;
        _dragCard.style.cursor = '';
        _dragCard = null;
        document.body.style.userSelect = '';
    });
}

function makeDiagramCardDraggable(card, header) {
    _installCardDragListenersOnce();
    header.addEventListener('mousedown', (e) => {
        if (e.button !== 0) return;
        e.preventDefault();
        const rect = card.getBoundingClientRect();
        _dragCard = card;
        _dragOffsetX = e.clientX - rect.left;
        _dragOffsetY = e.clientY - rect.top;
        card.style.cursor = 'grabbing';
        document.body.style.userSelect = 'none';
    });
}

function drawJoinArrows() {
    const svg = document.getElementById('joinArrowsSvg');
    svg.innerHTML = '';
    const container = document.getElementById('diagramContainer');

    if (!document.getElementById('joinArrowhead')) {
        const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
        const marker = document.createElementNS('http://www.w3.org/2000/svg', 'marker');
        marker.id = 'joinArrowhead';
        marker.setAttribute('viewBox', '0 0 10 10');
        marker.setAttribute('refX', '9');
        marker.setAttribute('refY', '5');
        marker.setAttribute('markerWidth', '6');
        marker.setAttribute('markerHeight', '6');
        marker.setAttribute('orient', 'auto');
        const arrow = document.createElementNS('http://www.w3.org/2000/svg', 'path');
        arrow.setAttribute('d', 'M 0 0 L 10 5 L 0 10 z');
        arrow.setAttribute('fill', 'currentColor');
        marker.appendChild(arrow);
        defs.appendChild(marker);
        svg.appendChild(defs);
    }

    joins.forEach(join => {
        const leftCard = container.querySelector(`.diagram-table-card[data-table="${join.leftTable}"]`);
        const rightCard = container.querySelector(`.diagram-table-card[data-table="${join.rightTable}"]`);
        if (!leftCard || !rightCard) return;
        const lRect = leftCard.getBoundingClientRect();
        const rRect = rightCard.getBoundingClientRect();
        const cRect = container.getBoundingClientRect();
        const x1 = lRect.right - cRect.left;
        const y1 = lRect.top + lRect.height / 2 - cRect.top;
        const x2 = rRect.left - cRect.left;
        const y2 = rRect.top + rRect.height / 2 - cRect.top;
        const dx = Math.abs(x2 - x1) * 0.5;
        const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
        path.setAttribute('d', `M${x1},${y1} C${x1 + dx},${y1} ${x2 - dx},${y2} ${x2},${y2}`);
        path.setAttribute('stroke', 'currentColor');
        path.setAttribute('stroke-width', '2');
        path.setAttribute('fill', 'none');
        path.setAttribute('marker-end', 'url(#joinArrowhead)');
        path.setAttribute('data-join-id', join.id);
        path.style.pointerEvents = 'stroke';
        path.style.cursor = 'pointer';
        svg.appendChild(path);
        const label = document.createElementNS('http://www.w3.org/2000/svg', 'text');
        label.setAttribute('x', (x1 + x2) / 2);
        label.setAttribute('y', (y1 + y2) / 2 - 6);
        label.setAttribute('text-anchor', 'middle');
        label.setAttribute('class', 'join-arrow-label');
        label.textContent = join.type;
        svg.appendChild(label);
    });
    updateJoinTip();
}


window.addTableToDiagram = addTableToDiagram;
window.drawJoinArrows = drawJoinArrows;
window.makeDiagramCardDraggable = makeDiagramCardDraggable;