/**
 * Cast Conductor Proprietary License v5
 * SPDX-License-Identifier: LicenseRef-CastConductor-Proprietary-v5
 * (Full proprietary header same as other modules.)
 * 
 * Macro Canvas Interactions extraction (Phase 2.7 Step 8 part 2)
 */
import { getActiveSnap as guidesGetActiveSnap, snapValue as guidesSnapValue, applyGuideSnapping as guidesApplySnap, ensureBaselineGuides as guidesEnsureBaseline, beginSnapSession as guidesBeginSession, endSnapSession as guidesEndSession } from './guides-snapping.js';

export function bindCanvasInteractions(editor){
    if (editor._canvasBound) return; editor._canvasBound = true;
    const canvas = document.getElementById('canvas-containers'); if (!canvas) return;

    editor.applyGeometryMutation = (containerId, next) => {
        const el = document.querySelector(`.canvas-container[data-container-id="${containerId}"]`);
        if (!el || !next) return;
        const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
        const w = clamp(Math.round(next.w), 40, editor.canvasBounds.w);
        const h = clamp(Math.round(next.h), 40, editor.canvasBounds.h);
        const x = clamp(Math.round(next.x), 0, editor.canvasBounds.w - w);
        const y = clamp(Math.round(next.y), 0, editor.canvasBounds.h - h);
        const changed = (parseInt(el.style.left,10)!==x || parseInt(el.style.top,10)!==y || parseInt(el.style.width,10)!==w || parseInt(el.style.height,10)!==h);
        if (!changed) return;
        el.style.left = `${x}px`; el.style.top = `${y}px`; el.style.width = `${w}px`; el.style.height = `${h}px`;
        editor._updateContainerGeometrySnapshots(containerId, { x, y, w, h });
        if (!editor._snapPulseQueued) { editor._snapPulseQueued = true; requestAnimationFrame(()=>{ editor._snapPulseQueued = false; el.classList.add('snap-pulse'); clearTimeout(el._snapTimer); el._snapTimer = setTimeout(()=>el.classList.remove('snap-pulse'),160); }); }
    };

    const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
    const getActiveSnap = (evt, containerEl) => guidesGetActiveSnap(editor, evt, containerEl);
    const snap = (v, step) => guidesSnapValue(editor, v, step);

    const onMouseMove = (e) => {
        if (!editor._dragState) return; e.preventDefault();
        const { id, type, dir, startX, startY, orig } = editor._dragState;
        const el = document.querySelector(`.canvas-container[data-container-id="${id}"]`);
        if (!el) return;
    const scaleX = (editor._canvasScale && editor._canvasScale.x) ? editor._canvasScale.x : (document.getElementById('canvas-containers')?.getBoundingClientRect().width || 1200) / (editor.canvasBounds.w || 1280);
        const scaleY = (editor._canvasScale && editor._canvasScale.y) ? editor._canvasScale.y : scaleX;
        const dx = (e.clientX - startX) / scaleX; const dy = (e.clientY - startY) / scaleY;
        let x = orig.x, y = orig.y, w = orig.w, h = orig.h;
        if (type === 'move') {
            const s = getActiveSnap(e, el); x = snap(clamp(orig.x + dx, 0, editor.canvasBounds.w - w), s); y = snap(clamp(orig.y + dy, 0, editor.canvasBounds.h - h), s);
        } else if (type === 'resize') {
            const s = getActiveSnap(e, el);
            if (dir.includes('r')) w = snap(clamp(orig.w + dx, 40, editor.canvasBounds.w - orig.x), s);
            if (dir.includes('l')) { const newX = snap(clamp(orig.x + dx, 0, orig.x + orig.w - 40), s); w = snap(orig.w + (orig.x - newX), s); x = newX; }
            if (dir.includes('b')) h = snap(clamp(orig.h + dy, 40, editor.canvasBounds.h - orig.y), s);
            if (dir.includes('t')) { const newY = snap(clamp(orig.y + dy, 0, orig.y + orig.h - 40), s); h = snap(orig.h + (orig.y - newY), s); y = newY; }
        }
        const snapped = editor._smartSnappingEnabled ? guidesApplySnap(editor, { x, y, w, h }) : { x, y, w, h };
        editor.applyGeometryMutation(id, snapped);
        try {
            const cx = editor._centerSnap && editor._centerSnap.x; const cy = editor._centerSnap && editor._centerSnap.y;
            const both = Number.isFinite(cx) && Number.isFinite(cy);
            const hyster = Number.isFinite(editor._centerHysteresis) ? editor._centerHysteresis : (editor._snapHysteresis || 6);
            let showCross = both; let crossPt = both ? { x: cx, y: cy } : null;
            if (!both && editor._centerSnapLast && Number.isFinite(hyster)) {
                const dx = Math.abs((snapped.x + Math.round(snapped.w/2)) - editor._centerSnapLast.x);
                const dy = Math.abs((snapped.y + Math.round(snapped.h/2)) - editor._centerSnapLast.y);
                if (dx <= hyster && dy <= hyster) { showCross = true; crossPt = { ...editor._centerSnapLast }; }
            }
            if (showCross) {
                if (typeof editor._updateCenterCrosshair === 'function') editor._updateCenterCrosshair(crossPt);
                if (both) editor._centerSnapLast = { x: cx, y: cy };
                if (typeof editor._updateActiveGuideHighlight === 'function') editor._updateActiveGuideHighlight(null);
            } else {
                if (typeof editor._updateCenterCrosshair === 'function') editor._updateCenterCrosshair(null);
                if (typeof editor._updateActiveGuideHighlight === 'function') editor._updateActiveGuideHighlight(editor._activeGuide);
            }
        } catch(_) {}
    };

    const persist = (id, rect) => {
        fetch(`${castconductorCanvasAjax.rest_url}castconductor/v5/containers/${id}`, {
            method: 'PUT', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': castconductorCanvasAjax.nonce },
            body: JSON.stringify({ x_position: rect.x, y_position: rect.y, width: rect.w, height: rect.h })
        }).catch(()=>{});
    };

    const onMouseUp = () => {
        if (!editor._dragState) return; const s = editor._dragState;
        const el = document.querySelector(`.canvas-container[data-container-id="${s.id}"]`);
        if (el) {
            const rect = { x: parseInt(el.style.left, 10) || 0, y: parseInt(el.style.top, 10) || 0, w: parseInt(el.style.width, 10) || el.offsetWidth, h: parseInt(el.style.height, 10) || el.offsetHeight };
            persist(s.id, rect);
        }
    try { guidesEndSession(editor); if (typeof editor._updateActiveGuideHighlight === 'function') editor._updateActiveGuideHighlight(null); if (typeof editor._clearCenterCrosshair === 'function') editor._clearCenterCrosshair(); delete editor._centerSnapLast; } catch(_){ }
        editor._dragState = null; document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp);
    };

    canvas.addEventListener('mousedown', (e) => {
        try { guidesEnsureBaseline(editor); } catch(_) {}
        const container = e.target.closest('.canvas-container'); if (!container) return; if (container.classList.contains('ccve-locked')) return;
        const handle = e.target.closest('.resize-handle');
        const moveTarget = e.target.closest('.container-label, .container-border, .canvas-container');
        const inPreview = !!e.target.closest('.container-content-preview'); const inZones = !!e.target.closest('.zones-overlay');
        const id = container.getAttribute('data-container-id');
        const rect = { x: parseInt(container.style.left, 10) || container.offsetLeft, y: parseInt(container.style.top, 10) || container.offsetTop, w: parseInt(container.style.width, 10) || container.offsetWidth, h: parseInt(container.style.height, 10) || container.offsetHeight };
        if (handle) { editor._dragState = { id, type: 'resize', dir: handle.dataset.dir || 'br', startX: e.clientX, startY: e.clientY, orig: rect }; editor.setSelectedContainer(id); }
        else if (moveTarget && !inPreview && !inZones) { editor._dragState = { id, type: 'move', dir: '', startX: e.clientX, startY: e.clientY, orig: rect }; editor.setSelectedContainer(id); }
        else { return; }
        try { if (editor._smartSnappingEnabled) guidesBeginSession(editor, id); } catch(_){ }
        e.preventDefault(); document.addEventListener('mousemove', onMouseMove); document.addEventListener('mouseup', onMouseUp);
    });
}

export function bindContainerSelection(editor){
    const canvas = document.getElementById('canvas-containers'); if (!canvas) return;
    canvas.addEventListener('click', (e) => {
        const gear = e.target.closest('.zone-gear'); if (gear) { e.preventDefault(); e.stopPropagation(); const cid = gear.getAttribute('data-container-id'); const zid = gear.getAttribute('data-zone-id'); if (cid && zid) editor.openZoneGridSettings(cid, zid); return; }
        const container = e.target.closest('.canvas-container'); if (!container) return; if (container.classList.contains('ccve-locked')) return; const id = container.getAttribute('data-container-id'); editor.setSelectedContainer(id);
    });
    document.addEventListener('keydown', (e) => {
        const tag = (e.target && (e.target.tagName || '')).toLowerCase();
        if (tag === 'input' || tag === 'textarea' || e.metaKey || e.ctrlKey || e.altKey) return;
        if (e.key === 'Escape') { editor.setSelectedContainer(null); return; }
        if (!editor.selectedContainerId) return; const id = editor.selectedContainerId; const el = document.querySelector(`.canvas-container[data-container-id="${id}"]`); if (!el) return; if (el.classList.contains('ccve-locked')) return;
        const step = (e.shiftKey ? editor.canvasSnap * 3 : editor.canvasSnap) || 8;
        let x = parseInt(el.style.left, 10) || el.offsetLeft || 0; let y = parseInt(el.style.top, 10) || el.offsetTop || 0;
        const w = parseInt(el.style.width, 10) || el.offsetWidth || 0; const h = parseInt(el.style.height, 10) || el.offsetHeight || 0;
    let handled = true; switch (e.key) { case 'ArrowLeft': x = Math.max(0, x - step); break; case 'ArrowRight': x = Math.min(editor.canvasBounds.w - w, x + step); break; case 'ArrowUp': y = Math.max(0, y - step); break; case 'ArrowDown': y = Math.min(editor.canvasBounds.h - h, y + step); break; default: handled = false; }
    if (!handled) return; e.preventDefault();
    let rect = { x, y, w, h };
    if (editor._smartSnappingEnabled) { try { guidesBeginSession(editor, id); rect = guidesApplySnap(editor, rect); } catch(_){ } }
    el.style.left = `${rect.x}px`; el.style.top = `${rect.y}px`;
    try { if (typeof editor._updateActiveGuideHighlight === 'function') editor._updateActiveGuideHighlight(editor._activeGuide); } catch(_){ }
    editor._persistRectDebounced(id);
    });
    document.addEventListener('keydown', (e) => {
        const tag = (e.target && (e.target.tagName || '')).toLowerCase(); if (tag === 'input' || tag === 'textarea' || e.metaKey || e.ctrlKey) return;
        if (editor.selectedContainerId) { const el = document.querySelector(`.canvas-container[data-container-id="${editor.selectedContainerId}"]`); if (el && el.classList.contains('ccve-locked')) return; }
        if (!e.altKey && !e.shiftKey) {
            if (e.key === 'g' || e.key === 'G') { const toggle = document.getElementById('toggle-grid'); if (toggle) { toggle.checked = !toggle.checked; editor.toggleCanvasGrid(toggle.checked); e.preventDefault(); return; } }
            if (e.key === '+' || e.key === '=') { const next = Math.min(128, (editor.canvasSnap || 8) + 1); editor.canvasSnap = next; const root = document.getElementById('container-canvas'); root?.style?.setProperty('--grid-size', `${next}px`); const snapInput = document.getElementById('snap-size'); if (snapInput) snapInput.value = String(next); const toggle = document.getElementById('toggle-grid'); if (toggle && toggle.checked) editor.toggleCanvasGrid(true); e.preventDefault(); return; }
            if (e.key === '-' || e.key === '_') { const next = Math.max(1, (editor.canvasSnap || 8) - 1); editor.canvasSnap = next; const root = document.getElementById('container-canvas'); root?.style?.setProperty('--grid-size', `${next}px`); const snapInput = document.getElementById('snap-size'); if (snapInput) snapInput.value = String(next); const toggle = document.getElementById('toggle-grid'); if (toggle && toggle.checked) editor.toggleCanvasGrid(true); e.preventDefault(); return; }
        }
    if (!editor.selectedContainerId) return; if (!e.altKey) return; const id = editor.selectedContainerId; const el = document.querySelector(`.canvas-container[data-container-id="${id}"]`); if (!el) return; const step = (e.shiftKey ? editor.canvasSnap * 3 : editor.canvasSnap) || 8; let x = parseInt(el.style.left, 10) || el.offsetLeft || 0; let y = parseInt(el.style.top, 10) || el.offsetTop || 0; let w = parseInt(el.style.width, 10) || el.offsetWidth || 0; let h = parseInt(el.style.height, 10) || el.offsetHeight || 0; const maxW = editor.canvasBounds.w - x; const maxH = editor.canvasBounds.h - y; let handled = true; switch (e.key) { case 'ArrowRight': w = Math.min(maxW, w + step); break; case 'ArrowLeft': w = Math.max(40, w - step); break; case 'ArrowDown': h = Math.min(maxH, h + step); break; case 'ArrowUp': h = Math.max(40, h - step); break; default: handled = false; } if (!handled) return; e.preventDefault();
    let rect2 = { x, y, w, h };
    if (editor._smartSnappingEnabled) { try { guidesBeginSession(editor, id); rect2 = guidesApplySnap(editor, rect2); } catch(_){ } }
    el.style.width = `${rect2.w}px`; el.style.height = `${rect2.h}px`;
    try { if (typeof editor._updateActiveGuideHighlight === 'function') editor._updateActiveGuideHighlight(editor._activeGuide); } catch(_){ }
    editor._persistRectDebounced(id);
    });
}

export const macroCanvasInteractionsApi = { bindCanvasInteractions, bindContainerSelection };
