<?php
    use Illuminate\Support\Facades\Storage;
    $floorplanUrl = Storage::url($floorplan->image_path);
?>

<?php if (isset($component)) { $__componentOriginal9ac128a9029c0e4701924bd2d73d7f54 = $component; } ?>
<?php if (isset($attributes)) { $__attributesOriginal9ac128a9029c0e4701924bd2d73d7f54 = $attributes; } ?>
<?php $component = App\View\Components\AppLayout::resolve([] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? (array) $attributes->getIterator() : [])); ?>
<?php $component->withName('app-layout'); ?>
<?php if ($component->shouldRender()): ?>
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag && $constructor = (new ReflectionClass(App\View\Components\AppLayout::class))->getConstructor()): ?>
<?php $attributes = $attributes->except(collect($constructor->getParameters())->map->getName()->all()); ?>
<?php endif; ?>
<?php $component->withAttributes([]); ?>
    <style>
        html, body { height: 100%; }
        .ops-shell{
            position: fixed; left:0; right:0; top:64px; bottom:0;
            background:#000; display:flex; flex-direction:column; z-index:10;
        }
        #viewport{ touch-action:none; }
        #overlay, #overlay *{ -webkit-user-select:none; user-select:none; }

        /* Bottom sheet */
        .sheet-backdrop{
            position:absolute; inset:0;
            background:rgba(0,0,0,0.55);
            opacity:0; pointer-events:none;
            transition:opacity .18s ease;
            z-index: 40;
            touch-action: none;
        }
        .sheet-backdrop.open{ opacity:1; pointer-events:auto; }

        .sheet{
            position:absolute; left:0; right:0; bottom:0;
            z-index: 50;
            pointer-events: auto;
            background:#0b1220;
            border-top:1px solid rgba(255,255,255,0.12);
            border-radius:18px 18px 0 0;
            transform: translateY(102%);
            transition: transform .22s ease;
            height: min(72vh, 680px);
            display:flex; flex-direction:column;
            will-change: transform;
            overscroll-behavior: contain;
            touch-action: pan-y;
        }
        .sheet.open{ transform: translateY(0); }

        .sheet-handle{
            width:44px; height:5px; border-radius:999px;
            background:rgba(255,255,255,0.25);
            margin:10px auto 8px;
        }

        .sheet-header{
            padding: 0 12px 10px;
            border-bottom: 1px solid rgba(255,255,255,0.10);
            display:flex; align-items:center; gap:10px;
        }

        .sheet-body{
            overflow:auto;
            padding: 12px;
            padding-bottom: calc(16px + env(safe-area-inset-bottom));
            -webkit-overflow-scrolling: touch;
        }

        .chip{
            display:inline-flex; align-items:center; gap:6px;
            padding:6px 10px; border-radius:999px;
            background:rgba(255,255,255,0.08);
            border:1px solid rgba(255,255,255,0.10);
            color:rgba(255,255,255,0.9);
            font-size:12px;
        }
        .card{
            background:rgba(255,255,255,0.06);
            border:1px solid rgba(255,255,255,0.10);
            border-radius:14px;
            padding:12px;
        }

        .input{
            width:100%;
            background:#0b1020;
            border:1px solid rgba(255,255,255,0.14);
            color:#fff;
            border-radius:10px;
            padding:10px 12px;
            font-size:14px;
            outline:none;
        }
        .label{ font-size:12px; color:rgba(255,255,255,0.65); margin-bottom:6px; }

        /* Icon buttons */
        .iconbtn{
            width:42px; height:38px;
            border-radius:12px;
            display:inline-flex; align-items:center; justify-content:center;
            border:1px solid rgba(255,255,255,0.12);
            background:#111827;
            color:#fff;
        }
        .iconbtn:hover{ background:#0f172a; }
        .iconbtn:active{ transform: translateY(1px); }
        .iconbtn-green{ background:#10b981; color:#071015; border-color:rgba(16,185,129,0.65); }
        .iconbtn-green:hover{ background:#34d399; }
        .iconbtn-indigo{ background:#4f46e5; border-color:rgba(79,70,229,0.65); }
        .iconbtn-indigo:hover{ background:#6366f1; }
        .ico{ width:18px; height:18px; display:block; }

        .btn{
            border-radius:10px; padding:10px 14px; font-size:14px;
            font-weight:800; border:1px solid rgba(255,255,255,0.12);
        }
        .btn-secondary{ background:#111827; color:#fff; }
        .btn-secondary:hover{ background:#0f172a; }
        .btn-primary{ background:#10b981; color:#071015; border-color:rgba(16,185,129,0.65); }
        .btn-primary:hover{ background:#34d399; }
    </style>

    <div class="ops-shell">
        
        <div id="viewport" class="flex-1 relative overflow-hidden bg-black">
            <div id="zoomWrap" class="absolute left-0 top-0" style="transform-origin: 0 0;">
                <img id="fpimg"
                     src="<?php echo e($floorplanUrl); ?>"
                     alt="floorplan"
                     class="block"
                     style="max-width:none; max-height:none; width:1px; height:1px;">
                <svg id="linksSvg" class="absolute left-0 top-0 pointer-events-none"></svg>
                <div id="overlay" class="absolute left-0 top-0"></div>
            </div>

            <div class="absolute top-2 left-2 z-10 text-xs text-white/70 bg-black/50 px-2 py-1 rounded">
                PC: Wheel zoom • Drag pan • Mobile: Pinch zoom • 1-finger pan
            </div>

            
            <div id="sheetBackdrop" class="sheet-backdrop"></div>

            <div id="sheet" class="sheet" aria-hidden="true">
                <div class="sheet-handle"></div>

                <div class="sheet-header">
                    <div class="text-white font-semibold" id="sheetTitle">Panel</div>
                    <div class="ml-auto">
                        <button id="sheetClose" type="button" class="btn btn-secondary py-2 px-3">Close</button>
                    </div>
                </div>

                <div class="sheet-body" id="sheetBody"></div>
            </div>
        </div>

        
        <div class="bg-gray-900 border-t border-gray-800">
            <div class="px-3 py-2 flex flex-col gap-2 md:flex-row md:items-center md:gap-3">
                <div class="text-xs text-gray-200 md:w-72">
                    <div class="font-semibold text-white truncate">Mazzo • Operations</div>
                    <div class="truncate text-gray-300"><?php echo e($floorplan->name); ?> • <?php echo e($date); ?></div>
                    <div class="mt-1">Selected: <span id="selCount" class="text-white font-semibold">0</span></div>
                </div>

                <div class="flex flex-wrap items-center gap-2 md:flex-1">
                    <form method="GET" action="<?php echo e(route('ops.floorplan')); ?>" class="flex items-center gap-2">
                        <input type="date" name="date" value="<?php echo e($date); ?>"
                               class="rounded-lg px-2 py-1 text-sm bg-gray-800 text-white border border-gray-700 focus:outline-none focus:ring-2 focus:ring-indigo-500">
                    </form>

                    <button id="btnFit" type="button" class="iconbtn" title="Fit">
                        <svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                            <path d="M4 9V4h5"/><path d="M20 9V4h-5"/><path d="M4 15v5h5"/><path d="M20 15v5h-5"/>
                        </svg>
                    </button>

                    <button id="btnAdd" type="button" class="iconbtn iconbtn-green" title="Add reservation">
                        <svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                            <path d="M12 5v14"/><path d="M5 12h14"/>
                        </svg>
                    </button>

                    <button id="btnList" type="button" class="iconbtn iconbtn-indigo" title="Reservations">
                        <svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                            <path d="M8 6h13"/><path d="M8 12h13"/><path d="M8 18h13"/><path d="M3 6h.01"/><path d="M3 12h.01"/><path d="M3 18h.01"/>
                        </svg>
                    </button>

                    <button id="btnClear" type="button" class="iconbtn" title="Clear selection">
                        <svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                            <path d="M6 6l12 12"/><path d="M18 6L6 18"/>
                        </svg>
                    </button>
                </div>

                <div class="md:w-96">
                    <div id="hint" class="text-xs text-gray-200 bg-black/30 border border-white/10 rounded-xl px-3 py-2">
                        Tip: Select table(s) → Add Reservation. Tap a reserved table to view details.
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script>
        const tables = <?php echo json_encode($tables, 15, 512) ?>;
        const reservationGroups = <?php echo json_encode($reservationGroups, 15, 512) ?>;

        const viewport = document.getElementById('viewport');
        const zoomWrap = document.getElementById('zoomWrap');
        const img = document.getElementById('fpimg');
        const overlay = document.getElementById('overlay');
        const linksSvg = document.getElementById('linksSvg');
        const hint = document.getElementById('hint');

        const sheet = document.getElementById('sheet');
        const sheetBackdrop = document.getElementById('sheetBackdrop');
        const sheetTitle = document.getElementById('sheetTitle');
        const sheetBody = document.getElementById('sheetBody');
        const sheetClose = document.getElementById('sheetClose');

        const selected = new Set();
        const selCountEl = document.getElementById('selCount');

        let scale = 1, panX = 0, panY = 0;
        const MIN_SCALE = 0.15, MAX_SCALE = 3.5;

        let didDrag = false;
        let uiOpen = false;

        // Stop sheet/backdrop events from leaking to the floorplan
        ['pointerdown','pointermove','pointerup','pointercancel','wheel','click'].forEach(evt => {
            sheet.addEventListener(evt, (e) => { e.stopPropagation(); }, { passive: false });
            sheetBackdrop.addEventListener(evt, (e) => { e.stopPropagation(); }, { passive: false });
        });

        // ---------- Sheet open/close ----------
        function openSheet(title, html) {
            sheetTitle.textContent = title;
            sheetBody.innerHTML = html;
            sheet.classList.add('open');
            sheetBackdrop.classList.add('open');
            sheet.setAttribute('aria-hidden', 'false');
            uiOpen = true;
            requestAnimationFrame(() => { sheetBody.scrollTop = 0; });
        }
        function closeSheet() {
            sheet.classList.remove('open');
            sheetBackdrop.classList.remove('open');
            sheet.setAttribute('aria-hidden', 'true');
            sheet.style.transition = '';
            sheet.style.transform = '';
            sheet._dragY = 0;
            uiOpen = false;
        }
        sheetClose.addEventListener('click', closeSheet);
        sheetBackdrop.addEventListener('click', closeSheet);
        window.addEventListener('keydown', (e) => { if (e.key === 'Escape') closeSheet(); });

        // Drag-to-close: whole sheet, only when at top of scroll and dragging down
        (function enableWholeSheetDragClose(){
            let dragging = false;
            let startY = 0, startX = 0;
            let started = false;
            sheet._dragY = 0;

            function canStart(e){
                if (!sheet.classList.contains('open')) return false;
                const tag = (e.target && e.target.tagName) ? e.target.tagName.toLowerCase() : '';
                if (['input','textarea','select','button','label'].includes(tag)) return false;
                return (sheetBody.scrollTop <= 0);
            }

            function onDown(e){
                if (!canStart(e)) return;
                dragging = true;
                started = false;
                startY = e.clientY;
                startX = e.clientX;
                sheet.style.transition = 'none';
                sheet.setPointerCapture(e.pointerId);
                e.stopPropagation();
            }

            function onMove(e){
                if (!dragging) return;
                const dy = e.clientY - startY;
                const dx = e.clientX - startX;

                if (!started) {
                    if (Math.abs(dx) > 8) { dragging = false; sheet.style.transition=''; return; }
                    if (dy < 6) return;
                    started = true;
                }

                const y = Math.max(0, dy);
                sheet._dragY = y;
                sheet.style.transform = `translateY(${y}px)`;
                e.preventDefault();
                e.stopPropagation();
            }

            function onUp(e){
                if (!dragging) return;
                dragging = false;
                sheet.style.transition = '';
                const threshold = Math.min(180, (sheet.offsetHeight * 0.25));
                if (sheet._dragY > threshold) closeSheet();
                else sheet.style.transform = '';
                sheet._dragY = 0;
                e.stopPropagation();
            }

            sheet.addEventListener('pointerdown', onDown, { passive: false });
            sheet.addEventListener('pointermove', onMove, { passive: false });
            sheet.addEventListener('pointerup', onUp);
            sheet.addEventListener('pointercancel', onUp);
        })();

        // ---------- Selection helpers ----------
        function selectedTableLabels() {
            const map = new Map(tables.map(t => [Number(t.id), t]));
            return Array.from(selected).map(id => map.get(Number(id))?.label || ('#'+id));
        }
        function updateSelectedUi() { selCountEl.textContent = String(selected.size); }

        function clearSelection(msg = 'Selection cleared.') {
            selected.clear();
            overlay.querySelectorAll('[data-id]').forEach(el => {
                el.style.outline = '';
                el.style.outlineOffset = '';
            });
            updateSelectedUi();
            hint.textContent = msg;
        }

        // ---------- Transform helpers ----------
        function applyTransform() {
            zoomWrap.style.transform = `translate(${panX}px, ${panY}px) scale(${scale})`;
        }
        function clampPan() {
            const vw = viewport.clientWidth, vh = viewport.clientHeight;
            const iw = img.naturalWidth || 1, ih = img.naturalHeight || 1;
            const w = iw * scale, h = ih * scale;

            if (w <= vw) panX = (vw - w) / 2;
            else panX = Math.max(vw - w, Math.min(0, panX));

            if (h <= vh) panY = (vh - h) / 2;
            else panY = Math.max(vh - h, Math.min(0, panY));
        }
        function applyTransformClamped() { clampPan(); applyTransform(); }

        function setLayersToNaturalSize() {
            const w = img.naturalWidth || 1, h = img.naturalHeight || 1;
            img.style.width = w + 'px';
            img.style.height = h + 'px';
            zoomWrap.style.width = w + 'px';
            zoomWrap.style.height = h + 'px';
            overlay.style.width = w + 'px';
            overlay.style.height = h + 'px';
            linksSvg.setAttribute('width', w);
            linksSvg.setAttribute('height', h);
            linksSvg.style.width = w + 'px';
            linksSvg.style.height = h + 'px';
        }

        function fitToView() {
            const vw = viewport.clientWidth, vh = viewport.clientHeight;
            const iw = img.naturalWidth || 1, ih = img.naturalHeight || 1;
            const pad = 32;
            const sX = (vw - pad) / iw, sY = (vh - pad) / ih;
            scale = Math.max(MIN_SCALE, Math.min(MAX_SCALE, Math.min(sX, sY)));
            const scaledW = iw * scale, scaledH = ih * scale;
            panX = (vw - scaledW) / 2;
            panY = (vh - scaledH) / 2;
            applyTransformClamped();
            hint.textContent = 'Fit to screen.';
        }

        // ---------- Draw links ----------
        function colorForReservation(id) {
            const hue = (Number(id) * 47) % 360;
            return `hsl(${hue} 90% 60%)`;
        }
        function getTableCenterNatural(t) {
            const x = Number(t.x ?? 20);
            const y = Number(t.y ?? 20);
            const w = Number(t.w ?? 60);
            const h = Number(t.h ?? 60);
            return { cx: x + (w / 2), cy: y + (h / 2) };
        }
        function ensureSvgDefs() {
            if (linksSvg.querySelector('defs')) return;
            const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
            const filter = document.createElementNS('http://www.w3.org/2000/svg', 'filter');
            filter.setAttribute('id', 'glow');
            filter.innerHTML = `
                <feGaussianBlur stdDeviation="3" result="coloredBlur"></feGaussianBlur>
                <feMerge>
                    <feMergeNode in="coloredBlur"></feMergeNode>
                    <feMergeNode in="SourceGraphic"></feMergeNode>
                </feMerge>
            `;
            defs.appendChild(filter);
            linksSvg.appendChild(defs);
        }
        function drawReservationLinks() {
            ensureSvgDefs();
            Array.from(linksSvg.children).forEach(ch => { if (ch.tagName.toLowerCase() !== 'defs') ch.remove(); });
            const tById = new Map(tables.map(t => [Number(t.id), t]));
            reservationGroups.forEach(g => {
                const ids = (g.table_ids || []).map(Number).filter(id => tById.has(id));
                if (ids.length < 2) return;
                const baseC = getTableCenterNatural(tById.get(ids[0]));
                const stroke = colorForReservation(g.id);
                for (let i = 1; i < ids.length; i++) {
                    const c = getTableCenterNatural(tById.get(ids[i]));
                    const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
                    line.setAttribute('x1', baseC.cx);
                    line.setAttribute('y1', baseC.cy);
                    line.setAttribute('x2', c.cx);
                    line.setAttribute('y2', c.cy);
                    line.setAttribute('stroke', stroke);
                    line.setAttribute('stroke-width', '4');
                    line.setAttribute('opacity', '0.85');
                    line.setAttribute('filter', 'url(#glow)');
                    linksSvg.appendChild(line);
                }
            });
        }

        // ---------- Tables ----------
        function applyShape(el, shape) {
            const s = (shape || '');
            el.style.borderRadius = s.startsWith('circle') ? '9999px' : '10px';
        }
        function escapeHtml(s) {
            return String(s ?? '')
                .replaceAll('&','&amp;')
                .replaceAll('<','&lt;')
                .replaceAll('>','&gt;')
                .replaceAll('"','&quot;')
                .replaceAll("'","&#039;");
        }
        function findReservationForTable(tableId) {
            const tid = Number(tableId);
            return reservationGroups.find(g => Array.isArray(g.table_ids) && g.table_ids.map(Number).includes(tid)) || null;
        }

        window.__opsSelectTables = (ids) => {
            selected.clear();
            (ids || []).forEach(id => selected.add(Number(id)));
            overlay.querySelectorAll('[data-id]').forEach(el => {
                const id = Number(el.dataset.id);
                const on = selected.has(id);
                el.style.outline = on ? '3px solid #3b82f6' : '';
                el.style.outlineOffset = on ? '2px' : '';
            });
            updateSelectedUi();
            hint.textContent = selected.size ? `Highlighted: ${selectedTableLabels().join(', ')}` : 'Ready.';
            closeSheet();
        };

        function renderTables() {
            overlay.innerHTML = '';
            tables.forEach(t => {
                const el = document.createElement('div');
                el.dataset.id = String(t.id);

                el.style.position = 'absolute';
                el.style.left = (t.x ?? 20) + 'px';
                el.style.top = (t.y ?? 20) + 'px';
                el.style.width = (t.w ?? 60) + 'px';
                el.style.height = (t.h ?? 60) + 'px';
                el.style.transform = `rotate(${t.rotation ?? 0}deg)`;
                el.style.display = 'flex';
                el.style.alignItems = 'center';
                el.style.justifyContent = 'center';
                el.style.fontSize = '12px';
                el.style.fontWeight = '800';
                el.style.cursor = 'pointer';

                applyShape(el, t.shape);

                const r = findReservationForTable(t.id);
                if (r) {
                    if (r.is_seated) {
                        el.style.background = '#16a34a';
                        el.style.color = 'white';
                        el.textContent = '✓ ' + (r.guest_name || 'RES');
                    } else {
                        el.style.background = colorForReservation(r.id);
                        el.style.color = '#111';
                        el.textContent = (r.guest_name || 'RES');
                    }
                    const icons = (Number(r.advance_amount || 0) > 0 ? ' 💰' : '') + (r.locked_move ? ' 🔒' : '');
                    el.textContent = el.textContent + icons;
                } else {
                    el.style.background = 'rgba(255,255,255,0.92)';
                    el.style.border = '2px solid #111';
                    el.style.color = '#111';
                    el.textContent = t.label;
                }

                if (selected.has(Number(t.id))) {
                    el.style.outline = '3px solid #3b82f6';
                    el.style.outlineOffset = '2px';
                }

                el.addEventListener('pointerdown', (e) => e.stopPropagation());

                el.addEventListener('click', (e) => {
                    e.stopPropagation();
                    const id = Number(t.id);
                    const r = findReservationForTable(id);

                    if (r) {
                        const labels = (r.table_ids || []).map(tid => {
                            const tt = tables.find(x => Number(x.id) === Number(tid));
                            return tt ? tt.label : ('#'+tid);
                        });

                        openSheet('Reservation details', `
                            <div class="card">
                                <div class="text-white font-semibold text-lg">${escapeHtml(r.guest_name || 'Reservation')}</div>

                                <div class="text-white/70 text-sm mt-1">
                                    Time: <span class="text-white">${escapeHtml(r.expected_arrival_time || '-')}</span> •
                                    People: <span class="text-white">${escapeHtml(String(r.people_count || '-'))}</span>
                                </div>

                                <div class="text-white/70 text-sm mt-1">
                                    Phone: <span class="text-white">${escapeHtml(r.phone || '-')}</span>
                                </div>

                                <div class="text-white/70 text-sm mt-1">
                                    Tables: <span class="text-white">${escapeHtml(labels.join(', '))}</span>
                                </div>

                                <div class="text-white/70 text-sm mt-1">
                                    Advance: <span class="text-white">${escapeHtml(String(r.advance_amount || 0))}</span>
                                    ${r.locked_move ? ' • <span class="text-white">Locked 🔒</span>' : ''}
                                    ${r.is_seated ? ' • <span class="text-white">Seated ✓</span>' : ''}
                                </div>

                                <div class="mt-3 flex flex-wrap gap-2">
                                    <button type="button" class="btn btn-secondary"
                                            onclick="window.__opsSelectTables(${JSON.stringify(r.table_ids||[])})">
                                        Highlight tables
                                    </button>

                                    <button type="button" class="btn btn-primary"
                                            onclick="window.__opsToggleSeated(${Number(r.id)})">
                                        ${r.is_seated ? 'Unseat' : 'Настанени'}
                                    </button>

                                    <button type="button" class="btn btn-secondary"
                                            onclick="window.__opsToggleLock(${Number(r.id)}, ${r.locked_move ? 'false' : 'true'})">
                                        ${r.locked_move ? 'Unlock 🔓' : 'Lock 🔒'}
                                    </button>
                                </div>
                            </div>
                        `);
                        return;
                    }

                    // toggle selection
                    if (selected.has(id)) selected.delete(id);
                    else selected.add(id);

                    el.style.outline = selected.has(id) ? '3px solid #3b82f6' : '';
                    el.style.outlineOffset = selected.has(id) ? '2px' : '';

                    updateSelectedUi();
                    hint.textContent = selected.size
                        ? `Selected: ${selectedTableLabels().join(', ')}`
                        : 'Tip: Select table(s) → Add Reservation.';
                });

                overlay.appendChild(el);
            });

            updateSelectedUi();
        }

        // Empty-space click clears selection (when UI closed, not after drag)
        viewport.addEventListener('click', () => {
            if (uiOpen) return;
            if (didDrag) { didDrag = false; return; }
            if (selected.size > 0) clearSelection('Selection cleared.');
        });

        // ---------- Ops actions (seat/lock) ----------
        window.__opsToggleSeated = async (reservationId) => {
            const csrf = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '';
            try {
                const url = "<?php echo e(url('/ops/reservations')); ?>/" + reservationId + "/toggle-seated";
                const res = await fetch(url, {
                    method: 'POST',
                    headers: { 'X-CSRF-TOKEN': csrf, 'Accept': 'application/json' },
                });
                const json = await res.json().catch(() => ({}));
                if (!res.ok || !json.ok) { hint.textContent = 'Seated toggle failed.'; return; }

                const idx = reservationGroups.findIndex(x => Number(x.id) === Number(reservationId));
                if (idx >= 0) {
                    reservationGroups[idx].is_seated = !!json.is_seated;
                    reservationGroups[idx].seated_at = json.seated_at;
                    renderTables();
                    drawReservationLinks();
                }
                hint.textContent = json.is_seated ? 'Marked seated ✅' : 'Unseated.';
                closeSheet();
            } catch {
                hint.textContent = 'Network error.';
            }
        };

        window.__opsToggleLock = async (reservationId, lock) => {
            const csrf = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '';
            try {
                const url = "<?php echo e(url('/ops/reservations')); ?>/" + reservationId + "/toggle-lock";
                const res = await fetch(url, {
                    method: 'POST',
                    headers: { 'Content-Type':'application/json', 'X-CSRF-TOKEN': csrf, 'Accept': 'application/json' },
                    body: JSON.stringify({ locked_move: !!lock }),
                });
                const json = await res.json().catch(() => ({}));
                if (!res.ok || !json.ok) { hint.textContent = 'Lock toggle failed.'; return; }

                const idx = reservationGroups.findIndex(x => Number(x.id) === Number(reservationId));
                if (idx >= 0) {
                    reservationGroups[idx].locked_move = !!json.locked_move;
                    renderTables();
                    drawReservationLinks();
                }
                hint.textContent = json.locked_move ? 'Locked 🔒' : 'Unlocked 🔓';
                closeSheet();
            } catch {
                hint.textContent = 'Network error.';
            }
        };

        // ---------- Sheet content builders ----------
        function renderAddReservationSheet() {
            const labels = selectedTableLabels();
            openSheet('Add reservation', `
                <div class="space-y-3">
                    <div class="chip">Selected: <b>${escapeHtml(labels.length ? labels.join(', ') : 'none')}</b></div>

                    <div class="card space-y-3">
                        <div>
                            <div class="label">Guest name</div>
                            <input class="input" id="f_guest_name" placeholder="e.g. Ivan Ivanov">
                        </div>
                        <div>
                            <div class="label">Phone</div>
                            <input class="input" id="f_phone" placeholder="e.g. 0888...">
                        </div>
                        <div class="grid grid-cols-2 gap-2">
                            <div>
                                <div class="label">People</div>
                                <input class="input" id="f_people" type="number" min="1" value="2">
                            </div>
                            <div>
                                <div class="label">Time</div>
                                <input class="input" id="f_time" type="time">
                            </div>
                        </div>
                        <div class="grid grid-cols-2 gap-2">
                            <div>
                                <div class="label">Advance (BGN)</div>
                                <input class="input" id="f_advance" type="number" min="0" value="0">
                            </div>
                            <div class="flex items-end gap-2">
                                <label class="chip" style="cursor:pointer;">
                                    <input id="f_lock" type="checkbox" style="accent-color:#10b981;">
                                    <span>Lock move 🔒</span>
                                </label>
                            </div>
                        </div>
                        <div>
                            <div class="label">Notes</div>
                            <textarea class="input" id="f_notes" rows="3" placeholder="Optional"></textarea>
                        </div>

                        <div class="flex gap-2">
                            <button type="button" class="btn btn-primary" id="btnSubmitReservation">Save</button>
                            <button type="button" class="btn btn-secondary" id="btnCancelReservation">Cancel</button>
                        </div>
                    </div>
                </div>
            `);

            setTimeout(() => {
                document.getElementById('btnCancelReservation')?.addEventListener('click', closeSheet);

                // ✅ Step 3: POST reservation and update UI instantly
                document.getElementById('btnSubmitReservation')?.addEventListener('click', async () => {
                    if (selected.size === 0) { hint.textContent = 'Select at least one table first.'; return; }

                    const csrf = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '';

                    const payload = {
                        floorplan_id: <?php echo e((int)$floorplan->id); ?>,
                        table_ids: Array.from(selected).map(Number),
                        date: "<?php echo e($date); ?>",
                        guest_name: document.getElementById('f_guest_name')?.value?.trim() || '',
                        phone: document.getElementById('f_phone')?.value?.trim() || null,
                        people_count: Number(document.getElementById('f_people')?.value || 2),
                        expected_arrival_time: document.getElementById('f_time')?.value || null,
                        advance_amount: Number(document.getElementById('f_advance')?.value || 0),
                        notes: document.getElementById('f_notes')?.value?.trim() || null,
                        locked_move: !!document.getElementById('f_lock')?.checked,
                    };

                    if (!payload.guest_name) { hint.textContent = 'Guest name is required.'; return; }

                    try {
                        hint.textContent = 'Saving...';

                        const res = await fetch("<?php echo e(route('ops.reservations.store')); ?>", {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json',
                                'X-CSRF-TOKEN': csrf,
                                'Accept': 'application/json',
                            },
                            body: JSON.stringify(payload),
                        });

                        const json = await res.json().catch(() => ({}));

                        if (!res.ok || !json.ok) {
                            hint.textContent = json.message || 'Save failed.';
                            return;
                        }

                        // Update local data and re-render
                        reservationGroups.push(json.reservation);
                        renderTables();
                        drawReservationLinks();

                        clearSelection('Reservation created ✅');
                        closeSheet();
                    } catch (e) {
                        hint.textContent = 'Network error while saving.';
                    }
                });
            }, 0);
        }

        function renderReservationsListSheet() {
            const rows = (reservationGroups || []).slice().reverse().map(r => {
                const tablesTxt = (r.table_ids || []).map(tid => {
                    const tt = tables.find(x => Number(x.id) === Number(tid));
                    return tt ? tt.label : ('#'+tid);
                }).join(', ');

                return `
                    <button type="button" class="w-full text-left card hover:bg-white/10 transition"
                            onclick="window.__opsSelectTables(${JSON.stringify(r.table_ids||[])})">
                        <div class="flex items-center justify-between">
                            <div class="text-white font-semibold">${escapeHtml(r.guest_name || 'Reservation')}</div>
                            <div class="text-white/70 text-xs">${escapeHtml(r.expected_arrival_time || '')}</div>
                        </div>
                        <div class="text-white/70 text-sm mt-1">
                            ${escapeHtml(tablesTxt)} • ${escapeHtml(String(r.people_count || ''))} ppl
                            ${Number(r.advance_amount || 0) > 0 ? ' • 💰' : ''} ${r.locked_move ? ' • 🔒' : ''} ${r.is_seated ? ' • ✓' : ''}
                        </div>
                    </button>
                `;
            }).join('');

            openSheet('Reservations', `
                <div class="space-y-2">
                    <div class="text-white/70 text-sm">Tap a reservation to highlight its tables.</div>
                    <div class="space-y-2">
                        ${rows || `<div class="text-white/60">No reservations for this day.</div>`}
                    </div>
                </div>
            `);
        }

        // ---------- Zoom / Pan / Pinch (LOCKED when uiOpen) ----------
        function zoomAtViewportPoint(viewX, viewY, newScale) {
            const prev = scale;
            const next = Math.max(MIN_SCALE, Math.min(MAX_SCALE, newScale));
            if (next === prev) return;

            const wx = (viewX - panX) / prev;
            const wy = (viewY - panY) / prev;

            scale = next;
            panX = viewX - wx * scale;
            panY = viewY - wy * scale;

            applyTransformClamped();
        }

        viewport.addEventListener('wheel', (e) => {
            if (uiOpen) return;
            e.preventDefault();
            const rect = viewport.getBoundingClientRect();
            const x = e.clientX - rect.left;
            const y = e.clientY - rect.top;
            const factor = e.deltaY > 0 ? 0.92 : 1.08;
            zoomAtViewportPoint(x, y, scale * factor);
        }, { passive: false });

        const pointers = new Map();
        let isPinching = false;
        let pinchStartDist = 0;
        let pinchStartScale = 1;
        let pinchStartMid = { x: 0, y: 0 };
        let lastX = 0, lastY = 0;

        function getDist(a, b){ return Math.hypot(a.clientX - b.clientX, a.clientY - b.clientY); }
        function getMid(a, b){ return { x:(a.clientX + b.clientX)/2, y:(a.clientY + b.clientY)/2 }; }
        function toViewportPoint(clientX, clientY){
            const rect = viewport.getBoundingClientRect();
            return { x: clientX - rect.left, y: clientY - rect.top };
        }

        viewport.addEventListener('pointerdown', (e) => {
            if (uiOpen) return;
            pointers.set(e.pointerId, e);
            viewport.setPointerCapture(e.pointerId);

            if (pointers.size === 1) {
                didDrag = false;
                const p = pointers.get(e.pointerId);
                lastX = p.clientX; lastY = p.clientY;
            }
            if (pointers.size === 2) {
                isPinching = true;
                const arr = Array.from(pointers.values());
                pinchStartDist = getDist(arr[0], arr[1]);
                pinchStartScale = scale;
                const mid = getMid(arr[0], arr[1]);
                pinchStartMid = toViewportPoint(mid.x, mid.y);
            }
        });

        viewport.addEventListener('pointermove', (e) => {
            if (uiOpen) return;
            if (!pointers.has(e.pointerId)) return;
            pointers.set(e.pointerId, e);

            if (pointers.size === 2) {
                const arr = Array.from(pointers.values());
                const d = getDist(arr[0], arr[1]);
                if (pinchStartDist > 0) {
                    const ratio = d / pinchStartDist;
                    zoomAtViewportPoint(pinchStartMid.x, pinchStartMid.y, pinchStartScale * ratio);
                }
                didDrag = true;
                return;
            }

            if (pointers.size === 1 && !isPinching) {
                const p = pointers.values().next().value;
                const dx = p.clientX - lastX;
                const dy = p.clientY - lastY;
                if (Math.abs(dx) + Math.abs(dy) > 2) didDrag = true;
                lastX = p.clientX; lastY = p.clientY;
                panX += dx; panY += dy;
                applyTransformClamped();
            }
        });

        function endPointer(e){
            if (uiOpen) return;
            pointers.delete(e.pointerId);
            if (pointers.size < 2) isPinching = false;
            if (pointers.size === 1) {
                const p = pointers.values().next().value;
                lastX = p.clientX; lastY = p.clientY;
            }
        }
        viewport.addEventListener('pointerup', endPointer);
        viewport.addEventListener('pointercancel', endPointer);

        // ---------- Init ----------
        function init() {
            if (!img.naturalWidth || !img.naturalHeight) { hint.textContent = 'Image failed to load.'; return; }
            setLayersToNaturalSize();
            renderTables();
            drawReservationLinks();
            requestAnimationFrame(fitToView);
        }
        img.addEventListener('load', init);
        setTimeout(() => { if (img.complete) init(); }, 50);
        window.addEventListener('resize', () => requestAnimationFrame(fitToView));

        // Buttons
        document.getElementById('btnFit').addEventListener('click', () => requestAnimationFrame(fitToView));
        document.getElementById('btnClear').addEventListener('click', () => clearSelection());
        document.getElementById('btnAdd').addEventListener('click', () => renderAddReservationSheet());
        document.getElementById('btnList').addEventListener('click', () => renderReservationsListSheet());
    </script>
 <?php echo $__env->renderComponent(); ?>
<?php endif; ?>
<?php if (isset($__attributesOriginal9ac128a9029c0e4701924bd2d73d7f54)): ?>
<?php $attributes = $__attributesOriginal9ac128a9029c0e4701924bd2d73d7f54; ?>
<?php unset($__attributesOriginal9ac128a9029c0e4701924bd2d73d7f54); ?>
<?php endif; ?>
<?php if (isset($__componentOriginal9ac128a9029c0e4701924bd2d73d7f54)): ?>
<?php $component = $__componentOriginal9ac128a9029c0e4701924bd2d73d7f54; ?>
<?php unset($__componentOriginal9ac128a9029c0e4701924bd2d73d7f54); ?>
<?php endif; ?><?php /**PATH /home/mazzo/public_html/mazzodev.mazzo.bg/mazzodev/resources/views/ops/floorplan.blade.php ENDPATH**/ ?>