<template>
    <Head :title="automation.title + ' - Automation Funnel Builder'" />

    <div class="app-layout" :class="{ 'sidebar-collapsed': collapsed, 'mobile-open': mobileOpen }" id="app">
        <!-- Sidebar Navigation -->
        <AppSidebar :collapsed="collapsed" :mobileOpen="mobileOpen" @toggle-sidebar="toggleSidebar" />

        <!-- Main Wrapper -->
        <div class="main-wrapper af-main" style="display:flex; flex-direction:column; overflow:hidden;">
            <AppTopbar @toggle-sidebar="toggleSidebar" />
            <!-- Funnel Top Bar -->
            <div class="af-topbar">
                <div class="af-topbar-left">
                    <Link href="/automation" class="af-breadcrumb-link" style="display: inline-flex; align-items: center; gap: 6px;">
                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" style="width: 14px; height: 14px;">
                            <path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5L8.25 12l7.5-7.5" />
                        </svg>
                        Automation Funnel
                    </Link>
                    <span class="af-breadcrumb-sep">/</span>
                    
                    <span v-if="!editingName" class="af-funnel-name" @click="startEditName">{{ form.title }}</span>
                    <input 
                        v-else 
                        ref="nameInput" 
                        type="text" 
                        v-model="form.title" 
                        class="af-name-input" 
                        @blur="stopEditName" 
                        @keydown.enter="stopEditName"
                    >
                    
                    <span class="af-draft-badge" :style="{ color: form.status === 'active' ? '#16a34a' : '#dc2626' }">
                        {{ form.status }}
                    </span>
                    <button class="af-icon-btn" title="Rename" @click="startEditName">
                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
                            <path stroke-linecap="round" stroke-linejoin="round" d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931z" />
                        </svg>
                    </button>
                </div>
                <div class="af-topbar-right">
                    <!-- Mode Switcher -->
                    <div class="af-view-switcher" style="margin-right:8px;">
                        <button :class="['af-switch-btn', { 'is-active': canvasMode === 'drawio' }]" @click="canvasMode = 'drawio'" title="Draw.io Drag & Drop Canvas">
                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M10.5 6h9.75M10.5 6a1.5 1.5 0 11-3 0m3 0a1.5 1.5 0 10-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-9.75 0h9.75" /></svg>
                            Custome Flow
                        </button>
                        <button :class="['af-switch-btn', { 'is-active': canvasMode === 'flow' }]" @click="canvasMode = 'flow'" title="Vertical Tree Flow">
                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6A2.25 2.25 0 016 3.75h2.25A2.25 2.25 0 0110.5 6v2.25a2.25 2.25 0 01-2.25 2.25H6a2.25 2.25 0 01-2.25-2.25V6zM3.75 15.75A2.25 2.25 0 016 13.5h2.25a2.25 2.25 0 012.25 2.25V18a2.25 2.25 0 01-2.25 2.25H6A2.25 2.25 0 013.75 18v-2.25zM13.5 6a2.25 2.25 0 012.25-2.25H18A2.25 2.25 0 0120.25 6v2.25A2.25 2.25 0 0118 10.5h-2.25a2.25 2.25 0 01-2.25-2.25V6z" /></svg>
                            Tree Flow
                        </button>
                    </div>

                    <span v-if="saving" style="font-size:12px; color:#9ca3af; margin-right:12px;">Saving...</span>

                    <!-- Run & Restart Control Buttons (Icon-Only) -->
                    <div style="display:flex; gap:6px; margin-right:12px;">
                        <Link 
                            :href="`/automation/${automation.id}/report`" 
                            class="af-control-btn is-report" 
                            title="View Report / Analytics"
                        >
                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:16px;height:16px"><path stroke-linecap="round" stroke-linejoin="round" d="M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v5.25c0 .621-.504 1.125-1.125 1.125h-2.25A1.125 1.125 0 013 18.375v-5.25zM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v9.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 01-1.125-1.125v-9.75zM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v14.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 01-1.125-1.125V4.125z" /></svg>
                        </Link>
                        <button 
                            class="af-control-btn is-run" 
                            :class="{ 'is-active': form.status === 'active' }" 
                            :title="form.status === 'active' ? 'Pause Automation' : 'Resume / Run Automation'" 
                            type="button" 
                            @click="togglePlayPause"
                        >
                            <svg v-if="form.status === 'active'" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24" style="width:16px;height:16px"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>
                            <svg v-else xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24" style="width:16px;height:16px"><path d="M8 5v14l11-7z"/></svg>
                        </button>
                        <button class="af-control-btn is-restart" title="Restart / Reset Metrics Logs" type="button" @click="restartAutomation">
                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:16px;height:16px"><path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99" /></svg>
                        </button>
                    </div>
                    
                    <div class="af-status-group">
                        <span class="af-toggle-label">Status: <span id="statusLabel">{{ form.status }}</span></span>
                        <label class="af-toggle-switch">
                            <input type="checkbox" :checked="form.status === 'active'" @change="toggleStatus">
                            <span class="af-toggle-thumb"></span>
                        </label>
                    </div>
                </div>
            </div>

            <!-- Workspace: Canvas + Right Panel -->
            <div class="af-workspace" id="afWorkspace">
                <!-- Left Block Palette (Draw.io Mode) -->
                <div v-if="canvasMode === 'drawio'" class="af-drawio-palette">
                    <div class="af-palette-hdr">
                        <div class="af-palette-title">Block Palette</div>
                        <div class="af-palette-sub">Drag block onto canvas or click to add</div>
                    </div>
                    <div class="af-palette-body">
                        <div 
                            v-for="block in paletteBlocks" 
                            :key="block.type" 
                            class="af-palette-card"
                            draggable="true"
                            @dragstart="onPaletteDragStart(block.type, $event)"
                            @click="addNodeAtCenter(block.type)"
                        >
                            <div class="af-palette-icon" :style="{ color: block.color }">
                                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.8" stroke="currentColor">
                                    <path stroke-linecap="round" stroke-linejoin="round" :d="block.path" />
                                </svg>
                            </div>
                            <div class="af-palette-info">
                                <div class="af-palette-name">{{ block.title }}</div>
                                <div class="af-palette-desc">{{ block.desc }}</div>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- Canvas Area -->
                <div 
                    class="af-canvas" 
                    id="afCanvas" 
                    ref="canvasEl"
                    :class="{ 
                        'is-space-pressed': isSpacePressed, 
                        'is-panning': isPanningCanvas,
                        'is-fullscreen': isFullscreen
                    }"
                    @click="onCanvasClick"
                    @mousedown="onCanvasMouseDown"
                >
                    <!-- DRAW.IO 2D DRAG & DROP BOARD -->
                    <div 
                        v-if="canvasMode === 'drawio'"
                        class="af-drawio-board"
                        :class="{ 'is-drawing-line': drawingLine.active }"
                        ref="boardEl"
                        :style="{ transform: 'scale(' + zoomLevel + ')', transformOrigin: 'left top' }"
                        @mousemove="onBoardMouseMove"
                        @mouseup="onBoardMouseUp"
                        @dragover.prevent
                        @drop="onBoardDrop($event)"
                    >
                        <!-- Active Connecting Indicator Banner -->
                        <div v-if="drawingLine.active" class="af-connecting-banner">
                            <span>Connecting line... Click or drop on any step to complete connection (Press ESC to cancel)</span>
                        </div>



                        <!-- SVG Connecting Lines Layer -->
                        <svg class="af-drawio-svg">
                            <defs>
                                <marker id="drawio-arrow" viewBox="0 0 10 10" refX="6" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
                                    <path d="M 0 1 L 8 5 L 0 9 z" fill="#94a3b8" />
                                </marker>
                                <marker id="drawio-arrow-active" viewBox="0 0 10 10" refX="6" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
                                    <path d="M 0 1 L 8 5 L 0 9 z" fill="#3b82f6" />
                                </marker>
                            </defs>

                            <!-- Rendered Edges -->
                            <g 
                                v-for="edge in form.settings.edges" 
                                :key="edge.source + '-' + edge.target"
                                @mouseenter="hoveredEdgeKey = edge.source + '-' + edge.target"
                                @mouseleave="hoveredEdgeKey = null"
                            >
                                <!-- Thick invisible path for easy hover interaction -->
                                <path 
                                    :d="getEdgePath(edge)" 
                                    class="af-line-path-hover-helper"
                                />
                                <!-- Visible path -->
                                <path 
                                    :d="getEdgePath(edge)" 
                                    class="af-line-path"
                                    marker-end="url(#drawio-arrow)"
                                />
                            </g>

                            <!-- Live preview line when drawing line connection -->
                            <path 
                                v-if="drawingLine.active"
                                :d="getPreviewLinePath()"
                                class="af-line-preview"
                                marker-end="url(#drawio-arrow-active)"
                            />
                        </svg>

                        <!-- Edge Delete Buttons (Rendered at center of each line) -->
                        <button 
                            v-for="edge in form.settings.edges" 
                            :key="'del-' + edge.source + '-' + edge.target"
                            class="af-line-del-btn"
                            :class="{ 'is-visible': hoveredEdgeKey === edge.source + '-' + edge.target }"
                            :style="getEdgeMidpointStyle(edge)"
                            @mouseenter="hoveredEdgeKey = edge.source + '-' + edge.target"
                            @mouseleave="hoveredEdgeKey = null"
                            @click.stop="deleteEdge(edge)"
                            title="Delete Connecting Line"
                        >
                            ×
                        </button>

                        <!-- Draggable Node Cards -->
                        <div 
                            v-for="node in form.settings.nodes"
                            :key="node.id"
                            :id="`drawio-node-${node.id}`"
                            class="af-drawio-node"
                            :class="[
                                `af-node--${node.type}`,
                                { 
                                    'is-selected': selectedNodeId === node.id,
                                    'is-connect-target': drawingLine.active && hoveredTargetNodeId === node.id && drawingLine.sourceId !== node.id,
                                    'has-active-tooltip': openTooltipNodeId === node.id
                                }
                            ]"
                            :style="{ left: (node.x || 300) + 'px', top: (node.y || 100) + 'px' }"
                            @click.stop="onNodeClick(node)"
                            @mouseup="finishLineToNode(node.id)"
                            @mouseenter="hoveredTargetNodeId = node.id"
                            @mouseleave="hoveredTargetNodeId = (hoveredTargetNodeId === node.id ? null : hoveredTargetNodeId)"
                        >
                            <!-- 4 Flexible Connection Anchor Ports (Top, Bottom, Left, Right) -->
                            <div 
                                class="af-port af-port--top"
                                :class="{ 'is-connected': isPortConnected(node.id, 'top') }"
                                title="Top Connection Port"
                                @mousedown.stop="startLineDrag(node.id, 'top', $event)"
                                @mouseup.stop="finishLineToNode(node.id, 'top')"
                                @mouseenter="hoveredTargetPort = 'top'"
                                @mouseleave="hoveredTargetPort = null"
                            ></div>
                            <div 
                                class="af-port af-port--bottom"
                                :class="{ 'is-connected': isPortConnected(node.id, 'bottom') }"
                                title="Bottom Connection Port"
                                @mousedown.stop="startLineDrag(node.id, 'bottom', $event)"
                                @mouseup.stop="finishLineToNode(node.id, 'bottom')"
                                @mouseenter="hoveredTargetPort = 'bottom'"
                                @mouseleave="hoveredTargetPort = null"
                            ></div>
                            <div 
                                class="af-port af-port--left"
                                :class="{ 'is-connected': isPortConnected(node.id, 'left') }"
                                title="Left Connection Port"
                                @mousedown.stop="startLineDrag(node.id, 'left', $event)"
                                @mouseup.stop="finishLineToNode(node.id, 'left')"
                                @mouseenter="hoveredTargetPort = 'left'"
                                @mouseleave="hoveredTargetPort = null"
                            ></div>
                            <div 
                                class="af-port af-port--right"
                                :class="{ 'is-connected': isPortConnected(node.id, 'right') }"
                                title="Right Connection Port"
                                @mousedown.stop="startLineDrag(node.id, 'right', $event)"
                                @mouseup.stop="finishLineToNode(node.id, 'right')"
                                @mouseenter="hoveredTargetPort = 'right'"
                                @mouseleave="hoveredTargetPort = null"
                            ></div>

                            <!-- Node Card Header (Draggable Handle) -->
                            <div 
                                class="af-drawio-node-hdr"
                                @mousedown.stop="startNodeDrag(node, $event)"
                                @mouseup="finishLineToNode(node.id)"
                            >
                                <div class="af-node-icon-badge" :class="`af-icon--${node.type}`">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.8" stroke="currentColor">
                                        <path stroke-linecap="round" stroke-linejoin="round" :d="getNodeSvgPath(node.type)" />
                                    </svg>
                                </div>
                                <div class="af-node-title-wrap">
                                    <div class="af-node-title-row">
                                        <span class="af-node-title">{{ node.title || defaultTitle(node.type) }}</span>
                                    </div>
                                    <div class="af-node-cat-row">
                                        <span class="af-node-cat-badge" :class="`af-cat--${nodeCategory(node.type).toLowerCase()}`">{{ nodeCategory(node.type) }}</span>
                                    </div>
                                </div>
                                <div class="af-node-actions">
                                </div>
                            </div>

                            <!-- Subtitle Box -->
                            <div class="af-drawio-node-sub">
                                {{ getNodeSubText(node) }}
                            </div>

                            <!-- Node Stats & Tooltip Footer -->
                            <div v-if="nodeStatus[node.id]" class="af-node-status-footer">
                                <div class="af-status-indicators">
                                    <!-- Spinner if processing -->
                                    <span v-if="nodeStatus[node.id].processingCount > 0" class="af-status-badge is-processing" title="Processing contacts">
                                        <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-refresh-ccw-icon lucide-refresh-ccw animate-spin"><path d="M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/><path d="M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16"/><path d="M16 16h5v5"/></svg>
                                        {{ nodeStatus[node.id].processingCount }}
                                    </span>
                                    
                                    <!-- Success count -->
                                    <span v-if="nodeStatus[node.id].successCount > 0" class="af-status-badge is-success" title="Success count">
                                        ✓ {{ nodeStatus[node.id].successCount }}
                                    </span>
                                    
                                    <!-- Error count -->
                                    <span v-if="nodeStatus[node.id].errorCount > 0" class="af-status-badge is-error" title="Error count">
                                        ⚠ {{ nodeStatus[node.id].errorCount }}
                                    </span>
                                </div>
                                
                                <!-- Info Button with click-toggle tooltip -->
                                 <div class="af-tooltip-wrapper">
                                     <button class="af-info-btn" type="button" @click.stop="openTooltipNodeId = (openTooltipNodeId === node.id ? null : node.id)">
                                         <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-info-icon lucide-info"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>
                                     </button>
                                    <div class="af-tooltip-panel" v-if="openTooltipNodeId === node.id">
                                        <div class="af-tooltip-hdr" style="display:flex; justify-content:space-between; align-items:center; border-bottom: 1px solid #334155; padding-bottom: 6px; margin-bottom: 8px;">
                                            <span class="af-tooltip-title" style="margin:0; padding:0;">Step Execution Logs</span>
                                            <button class="af-tooltip-close" type="button" @click.stop="openTooltipNodeId = null">&times;</button>
                                        </div>
                                        <div class="af-tooltip-stats">
                                            <span class="stat-item is-success">✓ {{ nodeStatus[node.id].successCount }} success</span>
                                            <span class="stat-item is-processing">{{ nodeStatus[node.id].processingCount }} pending</span>
                                            <span class="stat-item is-error">⚠ {{ nodeStatus[node.id].errorCount }} errors</span>
                                        </div>
                                        <div class="af-tooltip-logs">
                                            <div v-for="log in nodeStatus[node.id].logs.slice(0, 5)" :key="log.id" class="af-tooltip-log-item" :class="`is-${log.event_type === 'enrolled' ? 'success' : log.event_type.replace('node_', '')}`">
                                                <div class="log-header">
                                                    <span class="log-email">{{ log.contact ? log.contact.email : 'Unknown' }}</span>
                                                    <span class="log-time">{{ formatLogTime(log.created_at) }}</span>
                                                </div>
                                                <div class="log-body">{{ log.reason }}</div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <!-- VERTICAL TREE FLOW MODE -->
                    <div v-else class="af-flow" id="afFlow">
                        <FunnelNode
                            v-if="triggerNode"
                            :node="triggerNode"
                            :nodes="form.settings.nodes"
                            :edges="form.settings.edges"
                            :selectedNodeId="selectedNodeId"
                            :nodeStatus="nodeStatus"
                            @select="onSelectNode"
                            @delete="onDeleteNode"
                            @add-click="onAddClick"
                        />
                    </div>

                    <!-- Floating Canvas Controls (Zoom & Fullscreen) -->
                    <div class="af-canvas-controls">
                        <button 
                            v-if="canvasMode === 'drawio'"
                            class="af-canvas-control-btn" 
                            title="Zoom Out (Ctrl + -)" 
                            @click="zoomOut" 
                            :disabled="zoomLevel <= 0.5"
                        >
                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" style="width:14px;height:14px;">
                                <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 12h-15" />
                            </svg>
                        </button>
                        <div 
                            v-if="canvasMode === 'drawio'"
                            style="position: relative; display: inline-flex;"
                        >
                            <button 
                                class="af-canvas-control-btn is-label" 
                                title="Choose Zoom Level (Ctrl + 0 to reset)" 
                                @click.stop="showZoomDropdown = !showZoomDropdown"
                                style="border: none; background: transparent; cursor: pointer;"
                            >
                                {{ Math.round(zoomLevel * 100) }}%
                            </button>
                            <div 
                                v-if="showZoomDropdown" 
                                class="af-zoom-dropdown"
                            >
                                <button 
                                    v-for="pct in [50, 80, 90, 100, 150, 200]" 
                                    :key="pct" 
                                    class="af-zoom-dropdown-item"
                                    :class="{ 'is-active': Math.round(zoomLevel * 100) === pct }"
                                    @click="setZoomPct(pct)"
                                >
                                    {{ pct }}%
                                </button>
                            </div>
                        </div>
                        <button 
                            v-if="canvasMode === 'drawio'"
                            class="af-canvas-control-btn" 
                            title="Zoom In (Ctrl + +)" 
                            @click="zoomIn" 
                            :disabled="zoomLevel >= 2.0"
                        >
                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" style="width:14px;height:14px;">
                                <path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
                            </svg>
                        </button>
                        <div v-if="canvasMode === 'drawio'" class="af-canvas-control-divider"></div>
                        <button 
                            class="af-canvas-control-btn" 
                            :title="isFullscreen ? 'Exit Fullscreen' : 'Enter Fullscreen'" 
                            @click="toggleFullscreen"
                        >
                            <svg v-if="isFullscreen" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:14px;height:14px;">
                                <path stroke-linecap="round" stroke-linejoin="round" d="M9 9V4.5M9 9H4.5M9 9L3 3m12 6V4.5m0 4.5h4.5m-4.5 0l6-6M9 15v4.5M9 15H4.5m4.5 0l-6 6m12-6v4.5m0-4.5h4.5m-4.5 0l6 6" />
                            </svg>
                            <svg v-else xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:14px;height:14px;">
                                <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 3.75v4.5m0-4.5h4.5m-4.5 0L9 9M3.75 20.25v-4.5m0 4.5h4.5m-4.5 0L9 15M20.25 3.75v4.5m0-4.5h-4.5m4.5 0L15 9m5.25 11.25v-4.5m0 4.5h-4.5m4.5 0l-6-6" />
                            </svg>
                        </button>
                    </div>
                </div>

                <!-- Right Settings Panel -->
                <Transition name="slide-panel">
                    <div v-if="activePanel" class="af-panel" :class="{ 'is-email-panel': activePanel === 'email', 'is-webhook-panel': activePanel === 'webhook' }" id="afPanel">
                    
                    <!-- Panel: Trigger Settings -->
                    <div v-if="activePanel === 'trigger' && selectedNode" class="af-panel-content">
                        <div class="af-panel-hdr">
                            <div>
                                <div class="af-panel-title">{{ selectedNode.title }} <span class="af-panel-badge af-panel-badge--trigger">Trigger</span></div>
                                <div class="af-panel-desc">Configure the initiation events for this funnel.</div>
                            </div>
                            <div style="display: flex; align-items: center; gap: 8px; flex-shrink: 0;">
                                <button class="af-panel-close" @click="activePanel = null">×</button>
                            </div>
                        </div>
                        <div class="af-panel-body">
                            <div class="af-form-group">
                                <label class="af-label">Automation Name</label>
                                <input type="text" class="af-input" v-model="form.title" @change="debouncedSave">
                            </div>
                            <div class="af-form-group">
                                <label class="af-label">Internal Description</label>
                                <textarea class="af-textarea" v-model="form.settings.description" placeholder="Internal Description" rows="3" @change="debouncedSave"></textarea>
                            </div>
                            <div class="af-form-group">
                                <label class="af-label">Trigger Rule Evaluation</label>
                                <CwSelect v-model="form.settings.trigger.logical_operator" :options="[{value: 'OR', label: 'Match ANY trigger condition (OR)'}, {value: 'AND', label: 'Match ALL trigger conditions (AND)'}]" @change="debouncedSave" />
                            </div>

                            <div v-for="(t, index) in form.settings.trigger.triggers" :key="index" class="af-settings-card" style="margin-top: 12px; position: relative;">
                                <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px;">
                                    <div class="af-settings-card-title" style="margin-bottom: 0;">Trigger #{{ index + 1 }}</div>
                                    <button v-if="form.settings.trigger.triggers.length > 1" @click="removeTrigger(index)" style="border: none; background: none; color: #ef4444; cursor: pointer; font-size: 13px; font-weight: 600;">Remove</button>
                                </div>
                                
                                <div class="af-form-group">
                                    <label class="af-label" style="font-size:11px;">Trigger Event Type</label>
                                    <CwSelect v-model="t.type" :options="triggerTypeOptions" @change="debouncedSave" />
                                </div>
                                
                                <div class="af-form-group" v-if="t.type === 'incoming_webhook'" style="margin-top: 8px;">
                                    <label class="af-label" style="font-size:11px;">Select Webhook</label>
                                    <CwSelect
                                        v-model="t.webhook_id"
                                        :options="webhookOptions"
                                        @change="debouncedSave"
                                    />

                                   
                                    <div v-if="getActiveWebhookForTrigger(t)" class="af-wh-box" style="margin-top: 10px;">
                                        <div class="af-wh-box-hdr">
                                            <div>
                                                <div class="af-wh-name-row">
                                                    <span class="af-wh-name">{{ getActiveWebhookForTrigger(t).name }}</span>
                                                    <span :class="['badge', getActiveWebhookForTrigger(t).is_active ? 'badge--success' : 'badge--gray']">
                                                        {{ getActiveWebhookForTrigger(t).is_active ? 'Active' : 'Paused' }}
                                                    </span>
                                                </div>
                                                <div class="af-wh-logs">
                                                    {{ getActiveWebhookForTrigger(t).logs_count || 0 }} log{{ getActiveWebhookForTrigger(t).logs_count === 1 ? '' : 's' }}
                                                </div>
                                            </div>
                                            <span v-if="getActiveWebhookForTrigger(t).has_secret" class="af-wh-secret-badge" title="HMAC Signature Security Enabled">
                                                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width: 12px; height: 12px; display: inline-block; vertical-align: text-bottom; margin-right: 3px;">
                                                    <path stroke-linecap="round" stroke-linejoin="round" d="M16.5 10.5V6.75a4.5 4.5 0 10-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H6.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z" />
                                                </svg>
                                                <span>Signature required</span>
                                            </span>
                                        </div>

                                        <div class="af-wh-url-wrap">
                                            <label class="af-wh-label">Inbound URL</label>
                                            <div class="af-wh-url-input-group">
                                                <input type="text" class="af-input af-wh-url-input" readonly :value="getActiveWebhookForTrigger(t).receive_url">
                                                <button class="btn btn-secondary af-wh-copy-btn" type="button" @click="copyIncomingWebhookUrlByUrl(getActiveWebhookForTrigger(t).receive_url)">
                                                    Copy
                                                </button>
                                            </div>
                                        </div>

                                        <div class="af-wh-grid">
                                            <div class="af-wh-grid-item">
                                                <span class="af-wh-grid-label">Default Status</span>
                                                <span class="af-wh-grid-val">{{ getActiveWebhookForTrigger(t).default_status || 'subscribed' }}</span>
                                            </div>
                                            <div class="af-wh-grid-item">
                                                <span class="af-wh-grid-label">Duplicate Handling</span>
                                                <span class="af-wh-grid-val">{{ getActiveWebhookForTrigger(t).duplicate_handling === 'skip' ? 'Skip Duplicate' : 'Update Existing' }}</span>
                                            </div>
                                        </div>

                                        
                                        <div class="af-wh-multi-section">
                                            <div class="af-wh-section-hdr">
                                                <span class="af-wh-label">Lists / Tags</span>
                                                <button type="button" class="af-wh-add-inline-btn" @click="t.showEditListsTags = !t.showEditListsTags">
                                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width: 13px; height: 13px; display: inline-block; vertical-align: text-bottom; margin-right: 4px;">
                                                        <path stroke-linecap="round" stroke-linejoin="round" d="M10.5 6h9.75M10.5 6a1.5 1.5 0 11-3 0m3 0a1.5 1.5 0 10-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 11-3 0m3 0a1.5 1.5 0 10-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 11-3 0m3 0a1.5 1.5 0 10-3 0m-9.75 0h9.75" />
                                                    </svg>
                                                    <span>{{ t.showEditListsTags ? 'Done Editing' : 'Manage Lists & Tags' }}</span>
                                                </button>
                                            </div>

                                            
                                            <div v-if="!t.showEditListsTags" class="af-wh-chips-row">
                                                <span v-for="l in (getActiveWebhookForTrigger(t).lists || [])" :key="'l-'+l.id" class="chip-list-item" :style="{ background: l.color + '22', color: l.color, border: '1px solid ' + l.color + '44' }">
                                                    {{ l.title }}
                                                </span>
                                                <span v-for="tagItem in (getActiveWebhookForTrigger(t).tags || [])" :key="'t-'+tagItem.id" class="chip-tag-item" :style="{ background: tagItem.color ? tagItem.color + '15' : '#fef3c7', color: tagItem.color || '#d97706', border: '1px solid ' + (tagItem.color ? tagItem.color + '33' : '#fde68a') }">
                                                    {{ tagItem.title }}
                                                </span>
                                                <span v-if="(!getActiveWebhookForTrigger(t).lists || getActiveWebhookForTrigger(t).lists.length === 0) && (!getActiveWebhookForTrigger(t).tags || getActiveWebhookForTrigger(t).tags.length === 0)" class="af-wh-empty-hint">
                                                    - (No lists or tags attached)
                                                </span>
                                            </div>

                                            
                                            <div v-else class="af-wh-editor-box">
                                                
                                                <div class="af-wh-editor-sub">
                                                    <div class="af-wh-section-hdr">
                                                        <span class="af-wh-grid-label">Attached Lists</span>
                                                        <button type="button" class="af-wh-add-inline-btn" @click="showCreateListInline = !showCreateListInline">
                                                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" style="width: 11px; height: 11px; display: inline-block; vertical-align: middle; margin-right: 2px;">
                                                                <path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
                                                            </svg>
                                                            <span>New List</span>
                                                        </button>
                                                    </div>

                                                    <div v-if="showCreateListInline" class="af-wh-inline-form">
                                                        <input type="text" class="af-input af-wh-inline-input" v-model="newListTitle" placeholder="List Name..." @keyup.enter="handleCreateInlineListForWebhook(getActiveWebhookForTrigger(t))">
                                                        <input type="color" class="af-wh-color-picker" v-model="newListColor" title="Choose List Color">
                                                        <button type="button" class="btn btn-primary btn-sm" :disabled="creatingList" @click="handleCreateInlineListForWebhook(getActiveWebhookForTrigger(t))">Add</button>
                                                    </div>

                                                    <div class="af-wh-select-row">
                                                        <CwSelect
                                                            :model-value="''"
                                                            :options="getWebhookListOptions(getActiveWebhookForTrigger(t))"
                                                            placeholder="+ Select List to Attach"
                                                            @change="(id) => toggleWebhookListForObject(getActiveWebhookForTrigger(t), id)"
                                                            style="flex: 1;"
                                                        />
                                                    </div>

                                                    <div class="af-wh-chips-row" style="margin-top: 4px;">
                                                        <span 
                                                            v-for="l in (getActiveWebhookForTrigger(t).lists || [])" 
                                                            :key="l.id" 
                                                            class="chip-list-item af-wh-active-chip"
                                                            :style="{ background: l.color + '22', color: l.color, border: '1px solid ' + l.color + '44' }"
                                                        >
                                                            <span>{{ l.title }}</span>
                                                            <button type="button" class="af-wh-chip-remove" @click.stop="toggleWebhookListForObject(getActiveWebhookForTrigger(t), l.id)" title="Remove List">
                                                                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" style="width: 10px; height: 10px;">
                                                                    <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
                                                                </svg>
                                                            </button>
                                                        </span>
                                                        <span v-if="!getActiveWebhookForTrigger(t).lists || getActiveWebhookForTrigger(t).lists.length === 0" class="af-wh-empty-hint">No lists attached. Select one above.</span>
                                                    </div>
                                                </div>

                                                <div class="af-wh-editor-sub">
                                                    <div class="af-wh-section-hdr">
                                                        <span class="af-wh-grid-label">Attached Tags</span>
                                                        <button type="button" class="af-wh-add-inline-btn" @click="showCreateTagInline = !showCreateTagInline">
                                                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" style="width: 11px; height: 11px; display: inline-block; vertical-align: middle; margin-right: 2px;">
                                                                <path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
                                                            </svg>
                                                            <span>New Tag</span>
                                                        </button>
                                                    </div>

                                                    <div v-if="showCreateTagInline" class="af-wh-inline-form">
                                                        <input type="text" class="af-input af-wh-inline-input" v-model="newTagTitle" placeholder="Tag Name..." @keyup.enter="handleCreateInlineTagForWebhook(getActiveWebhookForTrigger(t))">
                                                        <input type="color" class="af-wh-color-picker" v-model="newTagColor" title="Choose Tag Color">
                                                        <button type="button" class="btn btn-primary btn-sm" :disabled="creatingTag" @click="handleCreateInlineTagForWebhook(getActiveWebhookForTrigger(t))">Add</button>
                                                    </div>

                                                    <div class="af-wh-select-row">
                                                        <CwSelect
                                                            :model-value="''"
                                                            :options="getWebhookTagOptions(getActiveWebhookForTrigger(t))"
                                                            placeholder="+ Select Tag to Attach"
                                                            @change="(id) => toggleWebhookTagForObject(getActiveWebhookForTrigger(t), id)"
                                                            style="flex: 1;"
                                                        />
                                                    </div>

                                                    <div class="af-wh-chips-row" style="margin-top: 4px;">
                                                        <span 
                                                            v-for="tagItem in (getActiveWebhookForTrigger(t).tags || [])" 
                                                            :key="tagItem.id" 
                                                            class="chip-tag-item af-wh-active-chip"
                                                            :style="{ background: tagItem.color ? tagItem.color + '15' : '#fef3c7', color: tagItem.color || '#d97706', border: '1px solid ' + (tagItem.color ? tagItem.color + '33' : '#fde68a') }"
                                                        >
                                                            <span>{{ tagItem.title }}</span>
                                                            <button type="button" class="af-wh-chip-remove" @click.stop="toggleWebhookTagForObject(getActiveWebhookForTrigger(t), tagItem.id)" title="Remove Tag">
                                                                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" style="width: 10px; height: 10px;">
                                                                    <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
                                                                </svg>
                                                            </button>
                                                        </span>
                                                        <span v-if="!getActiveWebhookForTrigger(t).tags || getActiveWebhookForTrigger(t).tags.length === 0" class="af-wh-empty-hint">No tags attached. Select one above.</span>
                                                    </div>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                
                                <div class="af-form-group" v-if="t.type === 'subscribes_to_list' || t.type === 'unsubscribes_from_list'" style="margin-top: 8px;">
                                    <label class="af-label" style="font-size:11px;">Select List</label>
                                    <CwSelect v-model="t.list_id" :options="listOptions" placeholder="Select a list..." @change="debouncedSave" />
                                </div>
                                
                                <div class="af-form-group" v-if="t.type === 'tag_applied' || t.type === 'tag_removed'" style="margin-top: 8px;">
                                    <label class="af-label" style="font-size:11px;">Select Tag</label>
                                    <CwSelect v-model="t.tag_id" :options="tagOptions" placeholder="Select a tag..." @change="debouncedSave" />
                                </div>
                                
                                <div class="af-form-group" v-if="t.type === 'email_opened' || t.type === 'email_clicked'" style="margin-top: 8px;">
                                    <label class="af-label" style="font-size:11px;">Select Campaign</label>
                                    <CwSelect v-model="t.campaign_id" :options="campaignSelectOptions" placeholder="Select campaign..." @change="debouncedSave" />
                                </div>
                            </div>
                            
                            <button class="btn btn-secondary w-full" style="margin-top: 12px; display: flex; align-items: center; justify-content: center; gap: 6px; padding: 8px; border: 1px dashed #cbd5e1; border-radius: 6px; background: #fff; cursor: pointer; font-size: 13px; font-weight: 500; color: #475569;" @click="addTrigger">
                                + Add Trigger Event
                            </button>
                        </div>
                      
                    </div>

                    <!-- Panel: Condition Settings -->
                    <div v-if="activePanel === 'condition' && selectedNode" class="af-panel-content">
                        <div class="af-panel-hdr">
                            <div>
                                <div class="af-panel-title">{{ selectedNode.title }} <span class="af-panel-badge af-panel-badge--condition">Condition</span></div>
                                <div class="af-panel-desc">Split workflow based on contact properties or activity.</div>
                            </div>
                            <div style="display: flex; align-items: center; gap: 8px; flex-shrink: 0;">
                                <button class="af-panel-delete-btn" title="Delete Step" @click="onDeleteNode(selectedNode.id)">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:14px;height:14px">
                                        <path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
                                    </svg>
                                </button>
                                <button class="af-panel-close" @click="activePanel = null">×</button>
                            </div>
                        </div>
                        <div class="af-panel-body">
                            <div class="af-form-group">
                                <label class="af-label">Internal Label</label>
                                <input type="text" class="af-input" v-model="selectedNode.title" @change="debouncedSave">
                            </div>
                            <div class="af-settings-card">
                                <div class="af-settings-card-title">Condition Sets</div>
                                <div v-for="(cond, idx) in selectedNode.config.conditions" :key="idx" class="af-condition-row" style="margin-bottom: 16px; border: 1px solid #e2e8f0; border-radius: 8px; padding: 12px; background: #f8fafc; display: flex; flex-direction: column; gap: 8px;">
                                    <div style="display: flex; gap: 8px; width: 100%;">
                                        <CwSelect v-model="cond.field" :options="conditionFieldOptions" @change="onConditionFieldChange(cond)" style="flex: 1; min-width: 0;" />
                                        <CwSelect v-model="cond.operator" :options="getConditionOperatorOptions(cond.field)" @change="debouncedSave" style="flex: 1; min-width: 0;" />
                                    </div>
                                    <div style="display: flex; gap: 8px; align-items: center; width: 100%;">
                                        <!-- Value input depends on field selection -->
                                        <CwSelect v-if="cond.field === 'Contact Type'" v-model="cond.value" :options="contactTypeOptions" @change="debouncedSave" style="flex: 1; min-width: 0;" />
                                        <CwSelect v-else-if="cond.field === 'Subscription Status'" v-model="cond.value" :options="subscriptionStatusOptions" @change="debouncedSave" style="flex: 1; min-width: 0;" />
                                        <CwSelect v-else-if="cond.field === 'List'" v-model="cond.value" :options="listOptions" placeholder="Select list..." @change="debouncedSave" style="flex: 1; min-width: 0;" />
                                        <CwSelect v-else-if="cond.field === 'Tag'" v-model="cond.value" :options="tagOptions" placeholder="Select tag..." @change="debouncedSave" style="flex: 1; min-width: 0;" />
                                        <input v-else-if="['Lifetime Value', 'LTV', 'Company'].includes(cond.field)" type="number" class="af-input" v-model="cond.value" placeholder="100" @change="debouncedSave" style="flex: 1; min-width: 0;">
                                        <CwDateTimePicker v-else-if="['Birthday', 'Date Added', 'Last Activity'].includes(cond.field)" v-model="cond.value" mode="date" placeholder="Select Date" style="flex: 1; min-width: 0;" @update:modelValue="debouncedSave" />
                                        <!-- Relative Offset for Last Purchase Date -->
                                        <div v-else-if="cond.field === 'Last Purchase Date'" style="display:flex; gap:10px; align-items:center; flex:1">
                                            <input type="number" class="af-input" v-model="cond.value" placeholder="30" @change="debouncedSave" style="flex: 1; min-width: 0;">
                                            <CwSelect v-model="cond.unit" :options="relativeUnitOptions" @change="debouncedSave" style="width: 90px; flex-shrink: 0;" />
                                        </div>
                                        <input v-else type="text" class="af-input" v-model="cond.value" placeholder="Enter value..." @change="debouncedSave" style="flex: 1; min-width: 0;">

                                        <!-- Delete condition button -->
                                        <button class="af-tag-add-btn" style="color: #ef4444; border-color: #fca5a5; background: #fff; padding: 0 10px; height: 38px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;" @click="removeConditionSet(idx)" title="Remove Condition">
                                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width: 14px; height: 14px;">
                                                <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
                                            </svg>
                                        </button>
                                    </div>
                                </div>
                                <button class="af-add-condition-btn" @click="addConditionSet">+ Add Condition</button>
                            </div>
                        </div>
                   
                    </div>

                    <!-- Panel: Email Settings -->
                    <div v-if="activePanel === 'email' && selectedNode" class="af-panel-content">
                        <div class="af-panel-hdr">
                            <div>
                                <div class="af-panel-title">Send Email <span class="af-panel-badge af-panel-badge--action">Action</span></div>
                                <div class="af-panel-desc">Send custom design email campaign to contact.</div>
                            </div>
                            <div style="display: flex; align-items: center; gap: 8px; flex-shrink: 0;">
                                <button class="af-panel-delete-btn" title="Delete Step" @click="onDeleteNode(selectedNode.id)">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:14px;height:14px">
                                        <path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
                                    </svg>
                                </button>
                                <button class="af-panel-close" @click="activePanel = null">×</button>
                            </div>
                        </div>
                        <div class="af-panel-body">
                            <div class="af-form-group">
                                <label class="af-label">Internal Label</label>
                                <input type="text" class="af-input" v-model="selectedNode.title" @change="debouncedSave">
                            </div>

                            <!-- Send To settings -->
                            <div class="af-form-group">
                                <label class="af-label">Send Email to</label>
                                <div style="display: flex; gap: 16px; margin-top: 6px; margin-bottom: 8px;">
                                    <label style="display: flex; align-items: center; gap: 6px; font-size: 13px; cursor: pointer;">
                                        <input type="radio" v-model="selectedNode.config.send_to_type" value="contact" @change="debouncedSave">
                                        Send To the contact
                                    </label>
                                    <label style="display: flex; align-items: center; gap: 6px; font-size: 13px; cursor: pointer;">
                                        <input type="radio" v-model="selectedNode.config.send_to_type" value="custom" @change="debouncedSave">
                                        Send to Custom Email Address
                                    </label>
                                </div>
                            </div>
                            <div class="af-form-group" v-if="selectedNode.config.send_to_type === 'custom'">
                                <label class="af-label">Custom Email Address</label>
                                <input type="text" class="af-input" v-model="selectedNode.config.custom_email_address" placeholder="e.g. admin@example.com or {{contact.email}}" @change="debouncedSave">
                            </div>

                            <div class="af-form-group">
                                <label class="af-label">Email Subject</label>
                                <input type="text" class="af-input" v-model="selectedNode.config.subject" placeholder="Email Subject" @change="debouncedSave">
                            </div>

                            <div class="af-form-group">
                                <label class="af-label">Email Pre-Header</label>
                                <input type="text" class="af-input" v-model="selectedNode.config.pre_header" placeholder="Email Pre-Header" @change="debouncedSave">
                            </div>

                            <!-- SMTP / Sender Connection -->
                            <div class="af-form-group">
                                <label class="af-label">SMTP / Sender Connection</label>
                                <CwSelect v-model="selectedNode.config.smtp_config_id" :options="smtpConfigOptions" placeholder="System Default SMTP Profile" @change="onSmtpChange" />
                            </div>

                            <div style="display: flex; gap: 12px; margin-bottom: 15px;">
                                <div class="af-form-group" style="flex: 1;">
                                    <label class="af-label">Sender Name (Optional Override)</label>
                                    <input type="text" class="af-input" v-model="selectedNode.config.from_name" :placeholder="getSmtpPlaceholder('from_name', 'System Default')" @change="debouncedSave">
                                </div>
                                <div class="af-form-group" style="flex: 1;">
                                    <label class="af-label">Sender Email (Optional Override)</label>
                                    <input type="email" class="af-input" v-model="selectedNode.config.from_email" :placeholder="getSmtpPlaceholder('from_email', 'system@default.com')" @change="debouncedSave">
                                </div>
                            </div>

                            <!-- Visual Block Editor -->
                            <div class="af-form-group">
                                <label class="af-label">Email Body (Visual Builder)</label>
                                <button type="button" class="btn btn-secondary w-full" style="display: flex; align-items: center; justify-content: center; gap: 8px; padding: 12px; border: 1px dashed #cbd5e1; border-radius: 8px; background: #f8fafc; font-size: 13px; font-weight: 500; cursor: pointer; color: #475569; width: 100%; transition: background 0.2s;" @click="showEmailBuilderModal = true">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" style="width: 16px; height: 16px; color: #64748b;">
                                        <path stroke-linecap="round" stroke-linejoin="round" d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10" />
                                    </svg>
                                    Design Email Body
                                </button>
                                <span style="font-size: 11px; color: #16a34a; margin-top: 5px; display: flex; align-items: center; gap: 4px;" v-if="selectedNode.config.blocks && selectedNode.config.blocks.length">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" style="width: 12px; height: 12px;">
                                        <path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5" />
                                    </svg>
                                    Configured ({{ selectedNode.config.blocks.length }} content blocks)
                                </span>
                                <span style="font-size: 11px; color: #94a3b8; margin-top: 5px; display: block;" v-else>
                                    No blocks configured. Click button to design.
                                </span>
                            </div>
                        </div>
                     
                    </div>

                    <!-- Panel: Campaign Email Settings -->
                    <div v-if="activePanel === 'campaign_email' && selectedNode" class="af-panel-content">
                        <div class="af-panel-hdr">
                            <div>
                                <div class="af-panel-title">Campaign Email <span class="af-panel-badge af-panel-badge--action" style="background:#e0f2fe;color:#0369a1;">Campaign</span></div>
                                <div class="af-panel-desc">Import and send an existing email campaign.</div>
                            </div>
                            <div style="display: flex; align-items: center; gap: 8px; flex-shrink: 0;">
                                <button class="af-panel-delete-btn" title="Delete Step" @click="onDeleteNode(selectedNode.id)">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:14px;height:14px">
                                        <path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
                                    </svg>
                                </button>
                                <button class="af-panel-close" @click="activePanel = null">×</button>
                            </div>
                        </div>
                        <div class="af-panel-body">
                            <div class="af-form-group">
                                <label class="af-label">Internal Label</label>
                                <input type="text" class="af-input" v-model="selectedNode.title" @change="debouncedSave">
                            </div>

                            <div class="af-form-group">
                                <label class="af-label" style="color: #0284c7; font-weight: 600;">Select Campaign to Import</label>
                                <CwSelect style="border-color: #0284c7;" v-model="selectedNode.config.imported_campaign_id" :options="campaignImportOptions" placeholder="-- Select Campaign --" @change="debouncedSave" />
                                <span style="font-size:11px;color:#6b7280;margin-top:2px;display:block">The workflow will send the subject, layout body, and settings of the selected campaign.</span>
                            </div>

                            <!-- Send To settings -->
                            <div class="af-form-group">
                                <label class="af-label">Send Email to</label>
                                <div style="display: flex; gap: 16px; margin-top: 6px; margin-bottom: 8px;">
                                    <label style="display: flex; align-items: center; gap: 6px; font-size: 13px; cursor: pointer;">
                                        <input type="radio" v-model="selectedNode.config.send_to_type" value="contact" @change="debouncedSave">
                                        Send To the contact
                                    </label>
                                    <label style="display: flex; align-items: center; gap: 6px; font-size: 13px; cursor: pointer;">
                                        <input type="radio" v-model="selectedNode.config.send_to_type" value="custom" @change="debouncedSave">
                                        Send to Custom Email Address
                                    </label>
                                </div>
                            </div>
                            <div class="af-form-group" v-if="selectedNode.config.send_to_type === 'custom'">
                                <label class="af-label">Custom Email Address</label>
                                <input type="text" class="af-input" v-model="selectedNode.config.custom_email_address" placeholder="e.g. admin@example.com or {{contact.email}}" @change="debouncedSave">
                            </div>
                        </div>
                   
                    </div>

                    <!-- Panel: Wait Settings -->
                    <div v-if="activePanel === 'wait' && selectedNode" class="af-panel-content">
                        <div class="af-panel-hdr">
                            <div>
                                <div class="af-panel-title">Wait / Delay <span class="af-panel-badge af-panel-badge--action">Wait</span></div>
                                <div class="af-panel-desc">Wait defined timespan before executing the next action.</div>
                            </div>
                            <div style="display: flex; align-items: center; gap: 8px; flex-shrink: 0;">
                                <button class="af-panel-delete-btn" title="Delete Step" @click="onDeleteNode(selectedNode.id)">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:14px;height:14px">
                                        <path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
                                    </svg>
                                </button>
                                <button class="af-panel-close" @click="activePanel = null">×</button>
                            </div>
                        </div>
                        <div class="af-panel-body">
                            <div class="af-form-group">
                                <label class="af-label">Wait For</label>
                                <div style="display:flex; gap:10px; align-items:center">
                                    <input type="number" class="af-input" v-model="selectedNode.config.value" style="width:80px" @change="debouncedSave">
                                    <CwSelect v-model="selectedNode.config.unit" :options="waitUnitOptions" @change="debouncedSave" />
                                </div>
                            </div>
                            <div class="af-form-group">
                                <label class="af-label">Preferred Send Time</label>
                                <CwSelect v-model="selectedNode.config.send_time" :options="preferredSendTimeOptions" @change="debouncedSave" />
                            </div>
                        </div>
                    
                    </div>

                    <!-- Panel: Tag Settings -->
                    <div v-if="(activePanel === 'apply_tag' || activePanel === 'remove_tag') && selectedNode" class="af-panel-content">
                        <div class="af-panel-hdr">
                            <div>
                                <div class="af-panel-title">{{ selectedNode.type === 'apply_tag' ? 'Apply Tag' : 'Remove Tag' }} <span class="af-panel-badge af-panel-badge--action">Action</span></div>
                                <div class="af-panel-desc">Manage tags associated with contact in this funnel step.</div>
                            </div>
                            <div style="display: flex; align-items: center; gap: 8px; flex-shrink: 0;">
                                <button class="af-panel-delete-btn" title="Delete Step" @click="onDeleteNode(selectedNode.id)">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:14px;height:14px">
                                        <path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
                                    </svg>
                                </button>
                                <button class="af-panel-close" @click="activePanel = null">×</button>
                            </div>
                        </div>
                        <div class="af-panel-body">
                            <div class="af-form-group">
                                <label class="af-label">Internal Label</label>
                                <input type="text" class="af-input" v-model="selectedNode.title" @change="debouncedSave">
                            </div>
                            <div class="af-settings-card">
                                <div class="af-settings-card-title">Select Tag</div>
                                <CwSelect v-model="selectedNode.config.tag_id" :options="tagOptions" placeholder="Select a tag..." @change="onTagChange" />
                            </div>
                        </div>

                    </div>

                    <!-- Panel: List Settings -->
                    <div v-if="(activePanel === 'apply_list' || activePanel === 'remove_list') && selectedNode" class="af-panel-content">
                        <div class="af-panel-hdr">
                            <div>
                                <div class="af-panel-title">{{ selectedNode.type === 'apply_list' ? 'Subscribe to List' : 'Unsubscribe from List' }} <span class="af-panel-badge af-panel-badge--action">Action</span></div>
                                <div class="af-panel-desc">Manage lists associated with contact in this funnel step.</div>
                            </div>
                            <div style="display: flex; align-items: center; gap: 8px; flex-shrink: 0;">
                                <button class="af-panel-delete-btn" title="Delete Step" @click="onDeleteNode(selectedNode.id)">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:14px;height:14px">
                                        <path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
                                    </svg>
                                </button>
                                <button class="af-panel-close" @click="activePanel = null">×</button>
                            </div>
                        </div>
                        <div class="af-panel-body">
                            <div class="af-form-group">
                                <label class="af-label">Internal Label</label>
                                <input type="text" class="af-input" v-model="selectedNode.title" @change="debouncedSave">
                            </div>
                            <div class="af-settings-card">
                                <div class="af-settings-card-title">Select List</div>
                                <CwSelect v-model="selectedNode.config.list_id" :options="listOptions" placeholder="Select a list..." @change="onListChange" />
                            </div>
                        </div>

                    </div>

                    <!-- Panel: Incoming Webhook Settings -->
                    <div v-if="activePanel === 'incoming_webhook' && selectedNode" class="af-panel-content">
                        <div class="af-panel-hdr">
                            <div>
                                <div class="af-panel-title">Incoming Webhook <span class="af-panel-badge" style="background:#fce7f3;color:#db2777;">Trigger</span></div>
                                <div class="af-panel-desc">Trigger automation using an inbound webhook.</div>
                            </div>
                            <div style="display: flex; align-items: center; gap: 8px; flex-shrink: 0;">
                                <button class="af-panel-delete-btn" title="Delete Step" @click="onDeleteNode(selectedNode.id)">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:14px;height:14px">
                                        <path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
                                    </svg>
                                </button>
                                <button class="af-panel-close" @click="activePanel = null">×</button>
                            </div>
                        </div>
                        <div class="af-panel-body">
                            <div class="af-form-group">
                                <label class="af-label">Step Label</label>
                                <input type="text" class="af-input" v-model="selectedNode.title" @change="debouncedSave">
                            </div>

                            <!-- Card: Connected Webhook Settings -->
                            <div class="af-wh-card">
                                <div class="af-wh-hdr">
                                    <div class="af-wh-title">Connected Webhook</div>
                                    <a href="/webhooks" target="_blank" class="af-wh-link">
                                        + Manage Webhooks
                                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="12" height="12"><path stroke-linecap="round" stroke-linejoin="round" d="M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25" /></svg>
                                    </a>
                                </div>

                                <div class="af-form-group">
                                    <label class="af-label">Select Webhook</label>
                                    <CwSelect
                                        v-model="selectedNode.config.webhook_id"
                                        :options="webhookOptions"
                                        @change="onWebhookSelectChange"
                                    />
                                </div>

                                <!-- Selected Webhook Full Details -->
                                <div v-if="activeSelectedWebhook" class="af-wh-box">
                                    <div class="af-wh-box-hdr">
                                        <div>
                                            <div class="af-wh-name-row">
                                                <span class="af-wh-name">{{ activeSelectedWebhook.name }}</span>
                                                <span :class="['badge', activeSelectedWebhook.is_active ? 'badge--success' : 'badge--gray']">
                                                    {{ activeSelectedWebhook.is_active ? 'Active' : 'Paused' }}
                                                </span>
                                            </div>
                                            <div class="af-wh-logs">
                                                {{ activeSelectedWebhook.logs_count || 0 }} log{{ activeSelectedWebhook.logs_count === 1 ? '' : 's' }}
                                            </div>
                                        </div>
                                        <span v-if="activeSelectedWebhook.has_secret" class="af-wh-secret-badge" title="HMAC Signature Security Enabled">
                                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width: 12px; height: 12px; display: inline-block; vertical-align: text-bottom; margin-right: 3px;">
                                                <path stroke-linecap="round" stroke-linejoin="round" d="M16.5 10.5V6.75a4.5 4.5 0 10-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H6.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z" />
                                            </svg>
                                            <span>Signature required</span>
                                        </span>
                                    </div>

                                    <div class="af-wh-url-wrap">
                                        <label class="af-wh-label">Inbound URL</label>
                                        <div class="af-wh-url-input-group">
                                            <input type="text" class="af-input af-wh-url-input" readonly :value="activeSelectedWebhook.receive_url">
                                            <button class="btn btn-secondary af-wh-copy-btn" type="button" @click="copyIncomingWebhookUrl(selectedNode.id)">
                                                Copy
                                            </button>
                                        </div>
                                    </div>

                                    <div class="af-wh-grid">
                                        <div class="af-wh-grid-item">
                                            <span class="af-wh-grid-label">Default Status</span>
                                            <span class="af-wh-grid-val">{{ activeSelectedWebhook.default_status || 'subscribed' }}</span>
                                        </div>
                                        <div class="af-wh-grid-item">
                                            <span class="af-wh-grid-label">Duplicate Handling</span>
                                            <span class="af-wh-grid-val">{{ activeSelectedWebhook.duplicate_handling === 'skip' ? 'Skip Duplicate' : 'Update Existing' }}</span>
                                        </div>
                                    </div>

                                    <!-- Lists & Tags Section: Shows ONLY activeSelectedWebhook's own attached lists and tags -->
                                    <div class="af-wh-multi-section">
                                        <div class="af-wh-section-hdr">
                                            <span class="af-wh-label">Lists / Tags</span>
                                            <button type="button" class="af-wh-add-inline-btn" @click="showEditWebhookListsTags = !showEditWebhookListsTags">
                                                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width: 13px; height: 13px; display: inline-block; vertical-align: text-bottom; margin-right: 4px;">
                                                    <path stroke-linecap="round" stroke-linejoin="round" d="M10.5 6h9.75M10.5 6a1.5 1.5 0 11-3 0m3 0a1.5 1.5 0 10-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 11-3 0m3 0a1.5 1.5 0 10-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 11-3 0m3 0a1.5 1.5 0 10-3 0m-9.75 0h9.75" />
                                                </svg>
                                                <span>{{ showEditWebhookListsTags ? 'Done Editing' : 'Manage Lists & Tags' }}</span>
                                            </button>
                                        </div>

                                        <!-- Summary View: Displays ONLY this webhook's own attached lists & tags -->
                                        <div v-if="!showEditWebhookListsTags" class="af-wh-chips-row">
                                            <span v-for="l in (activeSelectedWebhook.lists || [])" :key="'l-'+l.id" class="chip-list-item" :style="{ background: l.color + '22', color: l.color, border: '1px solid ' + l.color + '44' }">
                                                {{ l.title }}
                                            </span>
                                            <span v-for="t in (activeSelectedWebhook.tags || [])" :key="'t-'+t.id" class="chip-tag-item" :style="{ background: t.color ? t.color + '15' : '#fef3c7', color: t.color || '#d97706', border: '1px solid ' + (t.color ? t.color + '33' : '#fde68a') }">
                                                {{ t.title }}
                                            </span>
                                            <span v-if="(!activeSelectedWebhook.lists || activeSelectedWebhook.lists.length === 0) && (!activeSelectedWebhook.tags || activeSelectedWebhook.tags.length === 0)" class="af-wh-empty-hint">
                                                - (No lists or tags attached)
                                            </span>
                                        </div>

                                        <!-- Manager View: Allows selecting/creating lists and tags using CwSelect -->
                                        <div v-else class="af-wh-editor-box">
                                            <!-- Lists Selection -->
                                            <div class="af-wh-editor-sub">
                                                <div class="af-wh-section-hdr">
                                                    <span class="af-wh-grid-label">Attached Lists</span>
                                                    <button type="button" class="af-wh-add-inline-btn" @click="showCreateListInline = !showCreateListInline">
                                                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" style="width: 11px; height: 11px; display: inline-block; vertical-align: middle; margin-right: 2px;">
                                                            <path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
                                                        </svg>
                                                        <span>New List</span>
                                                    </button>
                                                </div>

                                                <div v-if="showCreateListInline" class="af-wh-inline-form">
                                                    <input type="text" class="af-input af-wh-inline-input" v-model="newListTitle" placeholder="List Name..." @keyup.enter="handleCreateInlineList">
                                                    <input type="color" class="af-wh-color-picker" v-model="newListColor" title="Choose List Color">
                                                    <button type="button" class="btn btn-primary btn-sm" :disabled="creatingList" @click="handleCreateInlineList">Add</button>
                                                </div>

                                                <div class="af-wh-select-row">
                                                    <CwSelect
                                                        :model-value="''"
                                                        :options="listSelectOptions"
                                                        placeholder="+ Select List to Attach"
                                                        @change="onAddListSelect"
                                                        style="flex: 1;"
                                                    />
                                                </div>

                                                <div class="af-wh-chips-row" style="margin-top: 4px;">
                                                    <span 
                                                        v-for="l in (activeSelectedWebhook.lists || [])" 
                                                        :key="l.id" 
                                                        class="chip-list-item af-wh-active-chip"
                                                        :style="{ background: l.color + '22', color: l.color, border: '1px solid ' + l.color + '44' }"
                                                    >
                                                        <span>{{ l.title }}</span>
                                                        <button type="button" class="af-wh-chip-remove" @click.stop="toggleWebhookList(l.id)" title="Remove List">
                                                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" style="width: 10px; height: 10px;">
                                                                <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
                                                            </svg>
                                                        </button>
                                                    </span>
                                                    <span v-if="!activeSelectedWebhook.lists || activeSelectedWebhook.lists.length === 0" class="af-wh-empty-hint">No lists attached. Select one above.</span>
                                                </div>
                                            </div>

                                            <!-- Tags Selection -->
                                            <div class="af-wh-editor-sub">
                                                <div class="af-wh-section-hdr">
                                                    <span class="af-wh-grid-label">Attached Tags</span>
                                                    <button type="button" class="af-wh-add-inline-btn" @click="showCreateTagInline = !showCreateTagInline">
                                                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" style="width: 11px; height: 11px; display: inline-block; vertical-align: middle; margin-right: 2px;">
                                                            <path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
                                                        </svg>
                                                        <span>New Tag</span>
                                                    </button>
                                                </div>

                                                <div v-if="showCreateTagInline" class="af-wh-inline-form">
                                                    <input type="text" class="af-input af-wh-inline-input" v-model="newTagTitle" placeholder="Tag Name..." @keyup.enter="handleCreateInlineTag">
                                                    <input type="color" class="af-wh-color-picker" v-model="newTagColor" title="Choose Tag Color">
                                                    <button type="button" class="btn btn-primary btn-sm" :disabled="creatingTag" @click="handleCreateInlineTag">Add</button>
                                                </div>

                                                <div class="af-wh-select-row">
                                                    <CwSelect
                                                        :model-value="''"
                                                        :options="tagSelectOptions"
                                                        placeholder="+ Select Tag to Attach"
                                                        @change="onAddTagSelect"
                                                        style="flex: 1;"
                                                    />
                                                </div>

                                                <div class="af-wh-chips-row" style="margin-top: 4px;">
                                                    <span 
                                                        v-for="t in (activeSelectedWebhook.tags || [])" 
                                                        :key="t.id" 
                                                        class="chip-tag-item af-wh-active-chip"
                                                        :style="{ background: t.color ? t.color + '15' : '#fef3c7', color: t.color || '#d97706', border: '1px solid ' + (t.color ? t.color + '33' : '#fde68a') }"
                                                    >
                                                        <span>{{ t.title }}</span>
                                                        <button type="button" class="af-wh-chip-remove" @click.stop="toggleWebhookTag(t.id)" title="Remove Tag">
                                                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" style="width: 10px; height: 10px;">
                                                                <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
                                                            </svg>
                                                        </button>
                                                    </span>
                                                    <span v-if="!activeSelectedWebhook.tags || activeSelectedWebhook.tags.length === 0" class="af-wh-empty-hint">No tags attached. Select one above.</span>
                                                </div>
                                            </div>
                                        </div>
                                    </div>

                                    <div class="af-wh-footer-stats">
                                        <span>Received: <strong class="af-wh-stat-bold">{{ activeSelectedWebhook.total_received || 0 }}</strong></span>
                                        <span>Last triggered: <strong class="af-wh-stat-bold">{{ activeSelectedWebhook.last_triggered_at ? formatDate(activeSelectedWebhook.last_triggered_at) : 'Never' }}</strong></span>
                                    </div>
                                </div>
                            </div>

                            <!-- Card: Flow Data Sync & Merge Variable Reference -->
                            <div class="af-wh-card">
                                <div class="af-wh-hdr">
                                    <div class="af-wh-title">Automation Flow Data Sync</div>
                                    <span class="badge badge--info">Variable Sync</span>
                                </div>
                                <p class="af-wh-desc">
                                    Data ingested by this webhook is synced to downstream blocks. Copy these tags to use in Send Email, Condition, or API steps:
                                </p>

                                <div class="af-wh-vars-list">
                                    <div class="af-wh-var-item" v-for="v in flowVariables" :key="v.tag">
                                        <div class="af-wh-var-info">
                                            <code class="af-wh-var-code">{{ v.tag }}</code>
                                            <span class="af-wh-var-label">{{ v.label }}</span>
                                        </div>
                                        <button type="button" class="btn btn-secondary af-wh-var-copy" @click="copyVariableTag(v.tag)">
                                            {{ copiedVariable === v.tag ? 'Copied!' : 'Copy' }}
                                        </button>
                                    </div>
                                </div>
                            </div>

                            <!-- Card: Automation Trigger Policy & Filtering -->
                            <div class="af-wh-card">
                                <div class="af-wh-hdr">
                                    <div class="af-wh-title">Trigger & Enrollment Rules</div>
                                </div>
                                
                                <div class="af-form-group">
                                    <label class="af-label">Re-enrollment Policy</label>
                                    <CwSelect
                                        v-model="selectedNode.config.enrollment_policy"
                                        :options="enrollmentPolicyOptions"
                                        placeholder="Select Re-enrollment Policy"
                                        @change="debouncedSave"
                                    />
                                </div>

                                <div class="af-form-group">
                                    <label class="af-label">Payload Execution Filter</label>
                                    <CwSelect
                                        v-model="selectedNode.config.filter_mode"
                                        :options="filterModeOptions"
                                        placeholder="Select Payload Filter Mode"
                                        @change="debouncedSave"
                                    />
                                </div>

                                <div v-if="selectedNode.config.filter_mode === 'match'" class="af-wh-filter-grid">
                                    <div class="af-form-group">
                                        <label class="af-label">Parameter Key</label>
                                        <input type="text" class="af-input" v-model="selectedNode.config.filter_key" placeholder="e.g. event_type" @change="debouncedSave">
                                    </div>
                                    <div class="af-form-group">
                                        <label class="af-label">Expected Value</label>
                                        <input type="text" class="af-input" v-model="selectedNode.config.filter_value" placeholder="e.g. order.created" @change="debouncedSave">
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <!-- Panel: Webhook / HTTP Request Settings -->
                    <div v-if="activePanel === 'webhook' && selectedNode" class="af-panel-content">
                        <div class="af-panel-hdr">
                            <div>
                                <div class="af-panel-title">Outgoing Webhook <span class="af-panel-badge af-panel-badge--action" style="background:#d1fae5;color:#059669;">API</span></div>
                                <div class="af-panel-desc">Call external APIs, n8n webhook, or Zapier automation.</div>
                            </div>
                            <div style="display: flex; align-items: center; gap: 8px; flex-shrink: 0;">
                                <button class="af-panel-delete-btn" title="Delete Step" @click="onDeleteNode(selectedNode.id)">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:14px;height:14px">
                                        <path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
                                    </svg>
                                </button>
                                <button class="af-panel-close" @click="activePanel = null">×</button>
                            </div>
                        </div>
                        <div class="af-panel-body">
                            <div class="af-form-group">
                                <label class="af-label">Step Label</label>
                                <input type="text" class="af-input" v-model="selectedNode.title" @change="debouncedSave">
                            </div>

                            <!-- Card: Endpoint Configuration -->
                            <div class="af-settings-card">
                                <div class="af-settings-card-title">Endpoint Configuration</div>
                                <div class="af-form-group">
                                    <label class="af-label">Webhook URL</label>
                                    <div style="position: relative; display: flex; align-items: center;">
                                        <span style="position: absolute; left: 10px; color: #94a3b8; display: flex; align-items: center;">
                                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width: 14px; height: 14px;"><path stroke-linecap="round" stroke-linejoin="round" d="M12 21a9.004 9.004 0 0 0 8.716-6.747M12 21a9.004 9.004 0 0 1-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9s2.015-9 4.5-9m0 0a9.004 9.004 0 0 1 8.716 6.747M12 3a9.004 9.004 0 0 0-8.716 6.747M3 12h18" /></svg>
                                        </span>
                                        <input type="url" class="af-input" v-model="selectedNode.config.url" placeholder="https://api.n8n.io/webhook/..." style="padding-left: 32px;" @change="debouncedSave">
                                    </div>
                                </div>
                                <div class="af-form-group" style="margin-bottom: 0;">
                                    <label class="af-label">HTTP Method</label>
                                    <div class="af-segmented-control">
                                        <button 
                                            type="button" 
                                            class="af-segmented-btn method-get" 
                                            :class="{ 'is-active': selectedNode.config.method === 'GET' }"
                                            @click="selectedNode.config.method = 'GET'; debouncedSave();"
                                        >GET</button>
                                        <button 
                                            type="button" 
                                            class="af-segmented-btn method-post" 
                                            :class="{ 'is-active': selectedNode.config.method === 'POST' }"
                                            @click="selectedNode.config.method = 'POST'; debouncedSave();"
                                        >POST</button>
                                        <button 
                                            type="button" 
                                            class="af-segmented-btn method-put" 
                                            :class="{ 'is-active': selectedNode.config.method === 'PUT' }"
                                            @click="selectedNode.config.method = 'PUT'; debouncedSave();"
                                        >PUT</button>
                                    </div>
                                </div>
                            </div>

                            <!-- Card: Authentication -->
                            <div class="af-settings-card">
                                <div class="af-settings-card-title">Authentication</div>
                                <div class="af-form-group" style="margin-bottom: 0;">
                                    <label class="af-label" style="font-size: 11px; color: #64748b;">Auth Type</label>
                                    <select 
                                        class="af-input" 
                                        v-model="webhookAuthType" 
                                        @change="syncWebhookAuth"
                                        style="background-image: url('data:image/svg+xml;charset=utf-8,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' fill=\'none\' viewBox=\'0 0 20 20\'%3E%3Cpath stroke=\'%236b7280\' stroke-linecap=\'round\' stroke-linejoin=\'round\' stroke-width=\'1.5\' d=\'m6 8 4 4 4-4\'/%3E%3C/svg%3E'); background-position: right 0.5rem center; background-repeat: no-repeat; background-size: 1.5em 1.5em; padding-right: 2.5rem;"
                                    >
                                        <option value="none">None (No Authentication)</option>
                                        <option value="bearer">Bearer Token</option>
                                        <option value="basic">Basic Auth (User/Password)</option>
                                        <option value="custom">Custom Header (Authorization)</option>
                                    </select>
                                </div>
                                <div v-if="webhookAuthType === 'bearer'" class="af-form-group" style="margin-top: 10px; margin-bottom: 0;">
                                    <label class="af-label" style="font-size: 11px; color: #64748b;">Bearer Token</label>
                                    <input 
                                        type="text" 
                                        class="af-input" 
                                        v-model="webhookBearerToken" 
                                        placeholder="eyJhbGciOiJIUzI1NiIsInR5cCI6..." 
                                        @input="syncWebhookAuth"
                                    >
                                </div>
                                <div v-if="webhookAuthType === 'basic'" style="display: flex; gap: 8px; margin-top: 10px;">
                                    <div class="af-form-group" style="flex: 1; margin-bottom: 0;">
                                        <label class="af-label" style="font-size: 11px; color: #64748b;">Username</label>
                                        <input 
                                            type="text" 
                                            class="af-input" 
                                            v-model="webhookBasicUser" 
                                            placeholder="api_user" 
                                            @input="syncWebhookAuth"
                                        >
                                    </div>
                                    <div class="af-form-group" style="flex: 1; margin-bottom: 0;">
                                        <label class="af-label" style="font-size: 11px; color: #64748b;">Password</label>
                                        <input 
                                            type="password" 
                                            class="af-input" 
                                            v-model="webhookBasicPass" 
                                            placeholder="password" 
                                            @input="syncWebhookAuth"
                                        >
                                    </div>
                                </div>
                            </div>

                            <!-- Card: Payload Config -->
                            <div class="af-settings-card">
                                <div class="af-settings-card-title">Payload Configuration</div>
                                <div class="af-form-group">
                                    <label class="af-label">Payload Format</label>
                                    <div class="af-segmented-control">
                                        <button 
                                            type="button" 
                                            class="af-segmented-btn" 
                                            :class="{ 'is-active': selectedNode.config.payload_type === 'json' }"
                                            @click="selectedNode.config.payload_type = 'json'; debouncedSave();"
                                        >JSON Format</button>
                                        <button 
                                            type="button" 
                                            class="af-segmented-btn" 
                                            :class="{ 'is-active': selectedNode.config.payload_type === 'form' }"
                                            @click="selectedNode.config.payload_type = 'form'; debouncedSave();"
                                        >Form URL-encoded</button>
                                    </div>
                                </div>
                                <div class="af-form-group" style="margin-bottom: 0;">
                                    <label class="af-label">Request Body Contents</label>
                                    <div class="af-segmented-control">
                                        <button 
                                            type="button" 
                                            class="af-segmented-btn" 
                                            :class="{ 'is-active': selectedNode.config.payload_mode === 'merged' || !selectedNode.config.payload_mode }"
                                            @click="selectedNode.config.payload_mode = 'merged'; debouncedSave();"
                                        >Full Contact (Raw)</button>
                                        <button 
                                            type="button" 
                                            class="af-segmented-btn" 
                                            :class="{ 'is-active': selectedNode.config.payload_mode === 'custom' }"
                                            @click="selectedNode.config.payload_mode = 'custom'; debouncedSave();"
                                        >Custom Data Only</button>
                                    </div>
                                </div>

                                <!-- Live JSON Payload Preview -->
                                <div class="af-form-group" style="margin-top: 12px; margin-bottom: 0;">
                                    <div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px;">
                                        <label class="af-label" style="margin-bottom: 0; cursor: pointer; user-select: none;" @click="showPayloadPreview = !showPayloadPreview">
                                            JSON Payload Preview
                                        </label>
                                        <div style="display: flex; align-items: center; gap: 6px;">
                                            <span class="live-pulse-dot"></span>
                                            <span style="font-size: 10px; font-weight: 700; color: #10b981; text-transform: uppercase; letter-spacing: 0.05em; line-height: 1;">Live</span>
                                            <button 
                                                type="button" 
                                                style="border: none; background: none; color: #2563eb; font-size: 11px; cursor: pointer; padding: 0 4px; font-weight: 600;"
                                                @click="showPayloadPreview = !showPayloadPreview"
                                            >
                                                {{ showPayloadPreview ? 'Hide' : 'Show' }}
                                            </button>
                                        </div>
                                    </div>
                                    <div v-show="showPayloadPreview" class="payload-preview-container">
                                        <pre style="margin: 0; white-space: pre-wrap; font-size: 11px; font-family: monospace;">{{ webhookPayloadPreview }}</pre>
                                    </div>
                                </div>
                            </div>

                            <!-- Card: Custom Headers -->
                            <div class="af-settings-card">
                                <div class="af-settings-card-title" style="display:flex; justify-content:space-between; align-items:center; margin-bottom: 4px;">
                                    <span>Custom Request Headers</span>
                                    <button class="btn-link" style="font-size:11px;color:#2563eb;background:none;border:none;cursor:pointer;font-weight:600;" @click="addWebhookHeader">+ Add Header</button>
                                </div>
                                <div v-if="!selectedNode.config.headers || !selectedNode.config.headers.filter(h => !(h.key && h.key.toLowerCase() === 'authorization' && ['bearer', 'basic'].includes(webhookAuthType))).length" style="font-size: 11px; color: #94a3b8; text-align: center; padding: 6px 0;">
                                    No custom headers configured.
                                </div>
                                <div v-for="(h, idx) in selectedNode.config.headers" :key="idx">
                                    <div v-if="h.key && h.key.toLowerCase() === 'authorization' && ['bearer', 'basic'].includes(webhookAuthType)" class="hidden"></div>
                                    <div v-else style="display:flex; gap:6px; margin-bottom:6px; align-items: center;">
                                        <input type="text" class="af-input" v-model="h.key" placeholder="X-API-Key" style="flex:1; font-size:12px; height: 34px;" @change="debouncedSave">
                                        <input type="text" class="af-input" v-model="h.value" placeholder="Value..." style="flex:1; font-size:12px; height: 34px;" @change="debouncedSave">
                                        <button class="af-panel-close" style="padding:0 6px;height:34px;line-height:34px;display:flex;align-items:center;justify-content:center;color:#ef4444;" @click="removeWebhookHeader(idx)">
                                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width: 14px; height: 14px;"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" /></svg>
                                        </button>
                                    </div>
                                </div>
                            </div>

                            <!-- Card: Custom Parameters -->
                            <div class="af-settings-card" v-if="selectedNode.config.payload_mode === 'custom' || selectedNode.config.payload_mode === 'merged' || !selectedNode.config.payload_mode">
                                <div class="af-settings-card-title" style="display:flex; justify-content:space-between; align-items:center; margin-bottom: 4px;">
                                    <span>Custom Parameters</span>
                                    <button class="btn-link" style="font-size:11px;color:#2563eb;background:none;border:none;cursor:pointer;font-weight:600;" @click="addWebhookParam">+ Add Parameter</button>
                                </div>
                                <div v-if="!selectedNode.config.params || !selectedNode.config.params.length" style="font-size: 11px; color: #94a3b8; text-align: center; padding: 6px 0;">
                                    No custom parameters configured.
                                </div>
                                <div v-for="(p, idx) in selectedNode.config.params" :key="idx" style="display:flex; gap:6px; margin-bottom:6px; align-items: center;">
                                    <input type="text" class="af-input" v-model="p.key" placeholder="lead_source" style="flex:1; font-size:12px; height: 34px;" @change="debouncedSave">
                                    <input type="text" class="af-input" v-model="p.value" placeholder="crm_system" style="flex:1; font-size:12px; height: 34px;" @change="debouncedSave">
                                    <button class="af-panel-close" style="padding:0 6px;height:34px;line-height:34px;display:flex;align-items:center;justify-content:center;color:#ef4444;" @click="removeWebhookParam(idx)">
                                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width: 14px; height: 14px;"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" /></svg>
                                    </button>
                                </div>
                            </div>

                            <!-- Test Connection / Send request -->
                            <div style="border-top:1px solid #e2e8f0; padding-top:12px; width: 100%;">
                                <button 
                                    class="btn" 
                                    style="width: 100%; display: flex; justify-content: center; align-items: center; gap: 8px; background: #3b82f6; color: white; font-weight: 600; height: 38px; border-radius: 6px;" 
                                    :disabled="testingWebhook" 
                                    @click="runWebhookTest"
                                >
                                    <svg v-if="testingWebhook" class="animate-spin" style="width:16px; height:16px; animation: spin 1s linear infinite;" viewBox="0 0 24 24" fill="none">
                                        <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" style="opacity:0.25;"></circle>
                                        <path fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" style="opacity:0.75;"></path>
                                    </svg>
                                    <span>{{ testingWebhook ? 'Sending Test...' : 'Send Test Request' }}</span>
                                </button>
                                
                                <div v-if="testWebhookResult" style="margin-top: 10px; border: 1px solid; border-radius: 8px; padding: 10px 12px; font-size: 11px; text-align: left; transition: all 0.2s;" :style="{
                                    backgroundColor: testWebhookResult.success ? '#f0fdf4' : '#fef2f2',
                                    borderColor: testWebhookResult.success ? '#bbf7d0' : '#fecaca',
                                    color: testWebhookResult.success ? '#166534' : '#991b1b'
                                }">
                                    <div style="font-weight: 700; display: flex; justify-content: space-between; align-items: center;">
                                        <span>Status: {{ testWebhookResult.status }}</span>
                                        <span style="font-size: 10px; padding: 1px 6px; border-radius: 12px;" :style="{
                                            backgroundColor: testWebhookResult.success ? '#d1fae5' : '#fee2e2',
                                            color: testWebhookResult.success ? '#065f46' : '#dc2626'
                                        }">{{ testWebhookResult.success ? 'SUCCESS' : 'FAILED' }}</span>
                                    </div>
                                    <div style="margin-top: 6px; font-family: monospace; white-space: pre-wrap; word-break: break-all; max-height: 100px; overflow-y: auto; background: rgba(255,255,255,0.7); padding: 6px; border-radius: 4px; border: 1px solid rgba(0,0,0,0.05);">
                                        {{ testWebhookResult.body }}
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>



                    <!-- Panel: A/B Split Test Settings -->
                    <div v-if="activePanel === 'ab_split' && selectedNode" class="af-panel-content">
                        <div class="af-panel-hdr">
                            <div>
                                <div class="af-panel-title">A/B Split Test <span class="af-panel-badge af-panel-badge--condition">Logic</span></div>
                                <div class="af-panel-desc">Split traffic evenly between two paths.</div>
                            </div>
                            <div style="display: flex; align-items: center; gap: 8px; flex-shrink: 0;">
                                <button class="af-panel-delete-btn" title="Delete Step" @click="onDeleteNode(selectedNode.id)">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:14px;height:14px">
                                        <path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
                                    </svg>
                                </button>
                                <button class="af-panel-close" @click="activePanel = null">×</button>
                            </div>
                        </div>
                        <div class="af-panel-body">
                            <div class="af-form-group">
                                <label class="af-label">Step Label</label>
                                <input type="text" class="af-input" v-model="selectedNode.title" @change="debouncedSave">
                            </div>
                            <div class="af-form-group">
                                <label class="af-label">Traffic Allocation</label>
                                <CwSelect v-model="selectedNode.config.split_percentage" :options="abSplitOptions" @change="debouncedSave" />
                            </div>
                        </div>
                        <div class="af-panel-footer">
                            <span style="font-size: 11px; color: #64748b; margin-right: auto; display: flex; align-items: center; gap: 4px;">
                                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" style="width: 12px; height: 12px; color: #10b981;">
                                    <path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                                </svg>
                                Saved automatically
                            </span>
                            <button class="btn btn-secondary" @click="activePanel = null">Close</button>
                            <button class="af-delete-btn" title="Delete" @click="onDeleteNode(selectedNode.id)">
                                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width: 14px; height: 14px;">
                                    <path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
                                </svg>
                            </button>
                        </div>
                    </div>

                    <!-- Panel: Update Contact Property Settings -->
                    <div v-if="activePanel === 'update_field' && selectedNode" class="af-panel-content">
                        <div class="af-panel-hdr">
                            <div>
                                <div class="af-panel-title">Update Contact Property <span class="af-panel-badge af-panel-badge--action" style="background:#e0f2fe;color:#0369a1;">CRM</span></div>
                                <div class="af-panel-desc">Update contact properties or lead status automatically.</div>
                            </div>
                            <div style="display: flex; align-items: center; gap: 8px; flex-shrink: 0;">
                                <button class="af-panel-delete-btn" title="Delete Step" @click="onDeleteNode(selectedNode.id)">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:14px;height:14px">
                                        <path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
                                    </svg>
                                </button>
                                <button class="af-panel-close" @click="activePanel = null">×</button>
                            </div>
                        </div>
                        <div class="af-panel-body">
                            <div class="af-form-group">
                                <label class="af-label">Step Label</label>
                                <input type="text" class="af-input" v-model="selectedNode.title" @change="debouncedSave">
                            </div>
                            <div class="af-form-group">
                                <label class="af-label">Target Field</label>
                                <CwSelect v-model="selectedNode.config.field_name" :options="targetPropertyFieldOptions" @change="debouncedSave" />
                            </div>
                            <div class="af-form-group">
                                <label class="af-label">New Value</label>
                                <CwSelect v-if="selectedNode.config.field_name === 'contact_type'" v-model="selectedNode.config.value" :options="contactTypeOptions" @change="debouncedSave" />
                                <CwSelect v-else-if="selectedNode.config.field_name === 'status'" v-model="selectedNode.config.value" :options="subscriptionStatusOptions" @change="debouncedSave" />
                                <input v-else-if="selectedNode.config.field_name === 'life_time_value'" type="number" class="af-input" v-model="selectedNode.config.value" placeholder="100" @change="debouncedSave">
                                <input v-else type="text" class="af-input" v-model="selectedNode.config.value" placeholder="New Value..." @change="debouncedSave">
                            </div>
                        </div>
                        <div class="af-panel-footer">
                            <span style="font-size: 11px; color: #64748b; margin-right: auto; display: flex; align-items: center; gap: 4px;">
                                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" style="width: 12px; height: 12px; color: #10b981;">
                                    <path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                                </svg>
                                Saved automatically
                            </span>
                            <button class="btn btn-secondary" @click="activePanel = null">Close</button>
                            <button class="af-delete-btn" title="Delete" @click="onDeleteNode(selectedNode.id)">
                                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width: 14px; height: 14px;">
                                    <path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
                                </svg>
                            </button>
                        </div>
                    </div>

                    <!-- Panel: End settings -->
                    <div v-if="activePanel === 'end' && selectedNode" class="af-panel-content">
                        <div class="af-panel-hdr">
                            <div>
                                <div class="af-panel-title">End Funnel <span class="af-panel-badge af-panel-badge--action">End</span></div>
                                <div class="af-panel-desc">No further action will run after this point.</div>
                            </div>
                            <div style="display: flex; align-items: center; gap: 8px; flex-shrink: 0;">
                                <button class="af-panel-delete-btn" title="Delete Step" @click="onDeleteNode(selectedNode.id)">
                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width:14px;height:14px">
                                        <path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
                                    </svg>
                                </button>
                                <button class="af-panel-close" @click="activePanel = null">×</button>
                            </div>
                        </div>
                        <div class="af-panel-body">
                            <div class="af-form-group">
                                <label class="af-label">Internal Label</label>
                                <input type="text" class="af-input" v-model="selectedNode.title" @change="debouncedSave">
                            </div>
                        </div>
                        <div class="af-panel-footer">
                            <span style="font-size: 11px; color: #64748b; margin-right: auto; display: flex; align-items: center; gap: 4px;">
                                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" style="width: 12px; height: 12px; color: #10b981;">
                                    <path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                                </svg>
                                Saved automatically
                            </span>
                            <button class="btn btn-secondary" @click="activePanel = null">Close</button>
                        </div>
                    </div>

                    <!-- Panel: Add Action (Block Picker) -->
                    <div v-if="activePanel === 'add-action'" class="af-panel-content">
                        <div class="af-panel-hdr">
                            <div class="af-panel-title">Add Action</div>
                            <div style="display: flex; align-items: center; gap: 8px; flex-shrink: 0;">
                                <button class="af-panel-close" @click="activePanel = null">×</button>
                            </div>
                        </div>
                        <div class="af-add-search-wrap">
                            <input v-model="blockSearch" type="search" class="af-add-search" placeholder="Search blocks...">
                        </div>
                        <!-- Tabs -->
                        <div class="af-add-tabs">
                            <button 
                                v-for="tab in ['actions', 'condition', 'all']" 
                                :key="tab"
                                class="af-add-tab" 
                                :class="{ 'is-active': activeTab === tab }"
                                @click="activeTab = tab"
                            >
                                {{ tab.charAt(0).toUpperCase() + tab.slice(1) }}
                            </button>
                        </div>

                        <div class="af-add-body">
                            <div class="af-add-section-label">Select Block Type</div>
                            <div class="af-block-grid">
                                <div v-if="shouldShowBlock('email')" class="af-block-card" @click="insertNode('email')">
                                    <div class="af-block-icon" style="color:#3b82f6">
                                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
                                            <path stroke-linecap="round" stroke-linejoin="round" d="M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75" />
                                        </svg>
                                    </div>
                                    <div class="af-block-name">Send Email</div>
                                    <div class="af-block-desc">Send design template email to contact</div>
                                </div>

                                <div v-if="shouldShowBlock('campaign_email')" class="af-block-card" @click="insertNode('campaign_email')">
                                    <div class="af-block-icon" style="color:#0284c7">
                                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
                                            <path stroke-linecap="round" stroke-linejoin="round" d="M19.113 12.09a2 2 0 01-.218.83L15 20l-2.68-2.68A2 2 0 0111.91 16.5H5a2 2 0 01-2-2v-5a2 2 0 012-2h6.91a2 2 0 011.41.59L15 4l3.895 7.08a2 2 0 01.218.83v.18zM19.5 12h.008v.008H19.5V12z" />
                                        </svg>
                                    </div>
                                    <div class="af-block-name">Campaign Email</div>
                                    <div class="af-block-desc">Import and send an existing email campaign</div>
                                </div>

                                <div v-if="shouldShowBlock('wait')" class="af-block-card" @click="insertNode('wait')">
                                    <div class="af-block-icon" style="color:#f59e0b">
                                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
                                            <path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z" />
                                        </svg>
                                    </div>
                                    <div class="af-block-name">Wait / Delay</div>
                                    <div class="af-block-desc">Wait defined duration before next step</div>
                                </div>

                                <div v-if="shouldShowBlock('condition')" class="af-block-card" @click="insertNode('condition')">
                                    <div class="af-block-icon" style="color:#3b82f6">
                                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
                                            <path stroke-linecap="round" stroke-linejoin="round" d="M7.5 21L3 16.5m0 0L7.5 12M3 16.5h13.5m0-13.5L21 7.5m0 0L16.5 12M21 7.5H7.5" />
                                        </svg>
                                    </div>
                                    <div class="af-block-name">If / Else Condition</div>
                                    <div class="af-block-desc">Check logic rules and split flow branches</div>
                                </div>

                                <div v-if="shouldShowBlock('webhook')" class="af-block-card" @click="insertNode('webhook')">
                                    <div class="af-block-icon" style="color:#10b981">
                                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
                                            <path stroke-linecap="round" stroke-linejoin="round" d="M14.25 9.75L16.5 12l-2.25 2.25m-4.5 0L7.5 12l2.25-2.25M6 20.25h12A2.25 2.25 0 0020.25 18V6A2.25 2.25 0 0018 3.75H6A2.25 2.25 0 003.75 6v12A2.25 2.25 0 006 20.25z" />
                                        </svg>
                                    </div>
                                    <div class="af-block-name">Outgoing Webhook</div>
                                    <div class="af-block-desc">Call external APIs, n8n, or Zapier</div>
                                </div>

                                <div v-if="shouldShowBlock('incoming_webhook')" class="af-block-card" @click="insertNode('incoming_webhook')">
                                    <div class="af-block-icon" style="color:#ec4899">
                                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
                                            <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 13.5L12 21m0 0l-7.5-7.5M12 21V3" />
                                        </svg>
                                    </div>
                                    <div class="af-block-name">Incoming Webhook</div>
                                    <div class="af-block-desc">Trigger funnel from Outgoing Webhook POST</div>
                                </div>



                                <div v-if="shouldShowBlock('ab_split')" class="af-block-card" @click="insertNode('ab_split')">
                                    <div class="af-block-icon" style="color:#8b5cf6">
                                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
                                            <path stroke-linecap="round" stroke-linejoin="round" d="M7.5 21L3 16.5m0 0L7.5 12M3 16.5h13.5m0-13.5L21 7.5m0 0L16.5 12M21 7.5H7.5" />
                                        </svg>
                                    </div>
                                    <div class="af-block-name">A/B Split Test</div>
                                    <div class="af-block-desc">Split traffic evenly between two branches</div>
                                </div>

                                <div v-if="shouldShowBlock('update_field')" class="af-block-card" @click="insertNode('update_field')">
                                    <div class="af-block-icon" style="color:#06b6d4">
                                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
                                            <path stroke-linecap="round" stroke-linejoin="round" d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931z" />
                                        </svg>
                                    </div>
                                    <div class="af-block-name">Update Property</div>
                                    <div class="af-block-desc">Update contact CRM property automatically</div>
                                </div>

                                <div v-if="shouldShowBlock('apply_tag')" class="af-block-card" @click="insertNode('apply_tag')">
                                    <div class="af-block-icon" style="color:#6b7280">
                                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
                                            <path stroke-linecap="round" stroke-linejoin="round" d="M9.568 3H5.25A2.25 2.25 0 003 5.25v4.318c0 .597.237 1.17.659 1.591l9.581 9.581c.699.699 1.78.872 2.607.33a18.095 18.095 0 005.223-5.223c.542-.827.369-1.908-.33-2.607L11.16 3.66A2.25 2.25 0 009.568 3z" />
                                        </svg>
                                    </div>
                                    <div class="af-block-name">Apply Tag</div>
                                    <div class="af-block-desc">Add tag label to contact</div>
                                </div>

                                <div v-if="shouldShowBlock('remove_tag')" class="af-block-card" @click="insertNode('remove_tag')">
                                    <div class="af-block-icon" style="color:#6b7280">
                                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
                                            <path stroke-linecap="round" stroke-linejoin="round" d="M9.568 3H5.25A2.25 2.25 0 003 5.25v4.318c0 .597.237 1.17.659 1.591l9.581 9.581c.699.699 1.78.872 2.607.33a18.095 18.095 0 005.223-5.223c.542-.827.369-1.908-.33-2.607L11.16 3.66A2.25 2.25 0 009.568 3z" />
                                        </svg>
                                    </div>
                                    <div class="af-block-name">Remove Tag</div>
                                    <div class="af-block-desc">Strip tag from contact profile</div>
                                </div>

                                <div v-if="shouldShowBlock('end')" class="af-block-card" @click="insertNode('end')">
                                    <div class="af-block-icon" style="color:#ef4444">
                                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
                                            <path stroke-linecap="round" stroke-linejoin="round" d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636" />
                                        </svg>
                                    </div>
                                    <div class="af-block-name">End Funnel</div>
                                    <div class="af-block-desc">Explicit termination of the branch</div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </Transition>
            </div>
        </div>
    </div>

    <!-- Email Builder Modal Overlay -->
    <div v-if="showEmailBuilderModal && selectedNode" class="email-builder-modal-overlay">
        <div class="email-builder-modal-container">
            <div class="email-builder-modal-header">
                <div class="email-builder-modal-header-left">
                    <h3 class="email-builder-modal-title">Design Email Content</h3>
                    <span class="email-builder-modal-subtitle">{{ selectedNode.title }}</span>
                </div>
                <button class="email-builder-modal-done-btn" @click="showEmailBuilderModal = false">
                    Save & Close
                </button>
            </div>
            <div class="email-builder-modal-body">
                <EmailEditor
                    v-model="selectedNode.config.blocks"
                    :global-settings="globalSettings"
                    @update:modelValue="onBlocksUpdate"
                />
            </div>
        </div>
    </div>
    <!-- Mobile Sidebar Backdrop Overlay -->
    <Transition name="fade">
        <div v-if="mobileOpen" class="sidebar-backdrop" @click="mobileOpen = false"></div>
    </Transition>
</template>

<script setup>
import { ref, computed, reactive, onMounted, nextTick, watch } from 'vue';
import { Head, Link, usePage } from '@inertiajs/vue3';
import AppSidebar from '@/Components/AppSidebar.vue';
import AppTopbar from '@/Components/AppTopbar.vue';
import FunnelNode from '@/Components/Automation/FunnelNode.vue';
import EmailEditor from '@/Components/EmailEditor/EmailEditor.vue';
import CwDateTimePicker from '@/Components/CwDateTimePicker.vue';
import CwSelect from '@/Components/CwSelect.vue';

const collapsed = ref(
    typeof window !== 'undefined' ? localStorage.getItem('sidebar-collapsed') === 'true' : false
);
const mobileOpen = ref(false);

const toggleSidebar = () => {
    if (typeof window !== 'undefined' && window.innerWidth <= 1024) {
        mobileOpen.value = !mobileOpen.value;
    } else {
        collapsed.value = !collapsed.value;
        if (typeof window !== 'undefined') {
            localStorage.setItem('sidebar-collapsed', collapsed.value ? 'true' : 'false');
        }
    }
};

const page = usePage();
watch(() => page.url, () => {
    mobileOpen.value = false;
});

const props = defineProps({
    automation: Object,
    lists: Array,
    tags: Array,
    webhooks: {
        type: Array,
        default: () => []
    },
    campaigns: {
        type: Array,
        default: () => []
    },
    smtpConfigs: {
        type: Array,
        default: () => []
    },
    defaultSender: Object,
    globalSettings: { type: Object, default: () => ({}) },
});

const webhookOptions = computed(() => {
    const opts = [
        { value: '', label: '-- Select Webhook --' }
    ];
    if (props.webhooks && props.webhooks.length > 0) {
        props.webhooks.forEach(w => {
            const count = w.total_received || 0;
            opts.push({
                value: String(w.id),
                label: `${w.name} (${count} received)`
            });
        });
        opts.push({ value: 'all', label: 'All Inbound Webhooks (Triggers on any webhook)' });
    } else {
        opts.push({ value: '', label: 'No Webhooks Found (Create One)' });
    }
    return opts;
});

const activeSelectedWebhook = computed(() => {
    const wId = selectedNode.value?.config?.webhook_id;
    if (!wId || wId === 'all') return null;
    return (props.webhooks || []).find(w => String(w.id) === String(wId)) || null;
});

function onWebhookSelectChange() {
    if (selectedNode.value) {
        if (!selectedNode.value.config) selectedNode.value.config = {};
        if (activeSelectedWebhook.value && selectedNode.value.config.webhook_id !== 'all') {
            selectedNode.value.sub = `Webhook: ${activeSelectedWebhook.value.name}`;
        } else if (selectedNode.value.config?.webhook_id === 'all') {
            selectedNode.value.sub = 'Triggers on All Webhooks';
        } else {
            selectedNode.value.sub = 'Incoming Webhook';
        }
    }
    debouncedSave();
}

const copiedVariable = ref(null);
const flowVariables = [
    { tag: '{{ contact.email }}', label: 'Contact Email' },
    { tag: '{{ contact.first_name }}', label: 'First Name' },
    { tag: '{{ contact.last_name }}', label: 'Last Name' },
    { tag: '{{ contact.phone }}', label: 'Phone Number' },
    { tag: '{{ contact.company }}', label: 'Company Name' },
    { tag: '{{ webhook.payload.event }}', label: 'Event Name' }
];

async function copyVariableTag(tag) {
    try {
        await navigator.clipboard.writeText(tag);
        copiedVariable.value = tag;
        setTimeout(() => {
            if (copiedVariable.value === tag) copiedVariable.value = null;
        }, 2000);
    } catch (e) {}
}

const enrollmentPolicyOptions = [
    { value: 'allow_multiple', label: 'Allow Re-enrollment (Triggers every time)' },
    { value: 'single', label: 'Single Enrollment Only (Contact enters flow once)' }
];

const filterModeOptions = [
    { value: 'all', label: 'Trigger on all payload requests' },
    { value: 'match', label: 'Filter by payload parameter' }
];

const listSelectOptions = computed(() => {
    const opts = [{ value: '', label: '+ Select List to Attach' }];
    (availableLists.value || []).forEach(l => {
        const isAttached = isListSelected(l.id);
        opts.push({
            value: String(l.id),
            label: `${isAttached ? '✓ ' : ''}${l.title}`
        });
    });
    return opts;
});

const tagSelectOptions = computed(() => {
    const opts = [{ value: '', label: '+ Select Tag to Attach' }];
    (availableTags.value || []).forEach(t => {
        const isAttached = isTagSelected(t.id);
        opts.push({
            value: String(t.id),
            label: `${isAttached ? '✓ ' : ''}${t.title}`
        });
    });
    return opts;
});

function onAddListSelect(listId) {
    if (listId) {
        toggleWebhookList(listId);
    }
}

function onAddTagSelect(tagId) {
    if (tagId) {
        toggleWebhookTag(tagId);
    }
}

function getActiveWebhookForTrigger(t) {
    if (!t || !t.webhook_id || t.webhook_id === 'all') return null;
    return (props.webhooks || []).find(w => String(w.id) === String(t.webhook_id)) || null;
}

function getWebhookListOptions(webhook) {
    const opts = [{ value: '', label: '+ Select List to Attach' }];
    (availableLists.value || []).forEach(l => {
        const isAttached = webhook?.lists?.some(item => Number(item.id) === Number(l.id));
        opts.push({
            value: String(l.id),
            label: `${isAttached ? '✓ ' : ''}${l.title}`
        });
    });
    return opts;
}

function getWebhookTagOptions(webhook) {
    const opts = [{ value: '', label: '+ Select Tag to Attach' }];
    (availableTags.value || []).forEach(t => {
        const isAttached = webhook?.tags?.some(item => Number(item.id) === Number(t.id));
        opts.push({
            value: String(t.id),
            label: `${isAttached ? '✓ ' : ''}${t.title}`
        });
    });
    return opts;
}

async function toggleWebhookListForObject(webhook, listId) {
    if (!webhook || !listId) return;
    let currentIds = (webhook.lists || []).map(l => l.id);
    if (currentIds.some(id => Number(id) === Number(listId))) {
        currentIds = currentIds.filter(id => Number(id) !== Number(listId));
    } else {
        currentIds.push(listId);
    }
    await syncWebhookListsAndTags(webhook, currentIds, (webhook.tags || []).map(t => t.id));
}

async function toggleWebhookTagForObject(webhook, tagId) {
    if (!webhook || !tagId) return;
    let currentIds = (webhook.tags || []).map(t => t.id);
    if (currentIds.some(id => Number(id) === Number(tagId))) {
        currentIds = currentIds.filter(id => Number(id) !== Number(tagId));
    } else {
        currentIds.push(tagId);
    }
    await syncWebhookListsAndTags(webhook, (webhook.lists || []).map(l => l.id), currentIds);
}

async function handleCreateInlineListForWebhook(webhook) {
    if (!newListTitle.value.trim()) return;
    creatingList.value = true;
    try {
        const slug = newListTitle.value.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
        const res = await window.axios.post('/lists', {
            title: newListTitle.value.trim(),
            slug: slug || 'list-' + Date.now(),
            color: newListColor.value
        }, { headers: { Accept: 'application/json' } });

        if (res.data?.success && res.data?.list) {
            const list = res.data.list;
            availableLists.value.push(list);
            newListTitle.value = '';
            showCreateListInline.value = false;
            if (webhook) {
                await toggleWebhookListForObject(webhook, list.id);
            }
        }
    } catch (e) {
        console.error('Failed to create list inline:', e);
    } finally {
        creatingList.value = false;
    }
}

async function handleCreateInlineTagForWebhook(webhook) {
    if (!newTagTitle.value.trim()) return;
    creatingTag.value = true;
    try {
        const slug = newTagTitle.value.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
        const res = await window.axios.post('/tags', {
            title: newTagTitle.value.trim(),
            slug: slug || 'tag-' + Date.now(),
            color: newTagColor.value
        }, { headers: { Accept: 'application/json' } });

        if (res.data?.success && res.data?.tag) {
            const tag = res.data.tag;
            availableTags.value.push(tag);
            newTagTitle.value = '';
            showCreateTagInline.value = false;
            if (webhook) {
                await toggleWebhookTagForObject(webhook, tag.id);
            }
        }
    } catch (e) {
        console.error('Failed to create tag inline:', e);
    } finally {
        creatingTag.value = false;
    }
}

async function copyIncomingWebhookUrlByUrl(url) {
    try {
        await navigator.clipboard.writeText(url);
        alert('Webhook URL copied to clipboard!');
    } catch (err) {
        console.error('Failed to copy text', err);
    }
}

const availableLists = ref([...(props.lists || [])]);
const availableTags  = ref([...(props.tags || [])]);

watch(() => props.lists, (val) => { if (val) availableLists.value = [...val]; }, { deep: true });
watch(() => props.tags,  (val) => { if (val) availableTags.value  = [...val]; }, { deep: true });

const showEditWebhookListsTags = ref(false);
const showCreateListInline = ref(false);
const newListTitle = ref('');
const newListColor = ref('#3b82f6');
const creatingList  = ref(false);

const showCreateTagInline = ref(false);
const newTagTitle = ref('');
const newTagColor = ref('#ec4899');
const creatingTag  = ref(false);

function isListSelected(listId) {
    if (!activeSelectedWebhook.value?.lists) return false;
    return activeSelectedWebhook.value.lists.some(l => Number(l.id) === Number(listId));
}

function isTagSelected(tagId) {
    if (!activeSelectedWebhook.value?.tags) return false;
    return activeSelectedWebhook.value.tags.some(t => Number(t.id) === Number(tagId));
}

async function toggleWebhookList(listId) {
    if (!activeSelectedWebhook.value) return;
    const w = activeSelectedWebhook.value;
    let currentIds = (w.lists || []).map(l => l.id);
    if (currentIds.some(id => Number(id) === Number(listId))) {
        currentIds = currentIds.filter(id => Number(id) !== Number(listId));
    } else {
        currentIds.push(listId);
    }
    await syncWebhookListsAndTags(w, currentIds, (w.tags || []).map(t => t.id));
}

async function toggleWebhookTag(tagId) {
    if (!activeSelectedWebhook.value) return;
    const w = activeSelectedWebhook.value;
    let currentIds = (w.tags || []).map(t => t.id);
    if (currentIds.some(id => Number(id) === Number(tagId))) {
        currentIds = currentIds.filter(id => Number(id) !== Number(tagId));
    } else {
        currentIds.push(tagId);
    }
    await syncWebhookListsAndTags(w, (w.lists || []).map(l => l.id), currentIds);
}

async function syncWebhookListsAndTags(webhook, listIds, tagIds) {
    try {
        const payload = {
            name: webhook.name,
            default_status: webhook.default_status || 'subscribed',
            duplicate_handling: webhook.duplicate_handling || 'update',
            is_active: webhook.is_active,
            list_ids: listIds,
            tag_ids: tagIds
        };
        const res = await window.axios.put(`/webhooks/${webhook.id}`, payload, {
            headers: { Accept: 'application/json' }
        });
        if (res.data?.success && res.data?.webhook) {
            webhook.lists = res.data.webhook.lists || [];
            webhook.tags  = res.data.webhook.tags || [];
        }
    } catch (e) {
        console.error('Failed to sync webhook lists/tags:', e);
    }
}

async function handleCreateInlineList() {
    if (!newListTitle.value.trim()) return;
    creatingList.value = true;
    try {
        const slug = newListTitle.value.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
        const res = await window.axios.post('/lists', {
            title: newListTitle.value.trim(),
            slug: slug || 'list-' + Date.now(),
            color: newListColor.value
        }, { headers: { Accept: 'application/json' } });

        if (res.data?.success && res.data?.list) {
            const list = res.data.list;
            availableLists.value.push(list);
            newListTitle.value = '';
            showCreateListInline.value = false;
            if (activeSelectedWebhook.value) {
                await toggleWebhookList(list.id);
            }
        }
    } catch (e) {
        console.error('Failed to create list inline:', e);
    } finally {
        creatingList.value = false;
    }
}

async function handleCreateInlineTag() {
    if (!newTagTitle.value.trim()) return;
    creatingTag.value = true;
    try {
        const slug = newTagTitle.value.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
        const res = await window.axios.post('/tags', {
            title: newTagTitle.value.trim(),
            slug: slug || 'tag-' + Date.now(),
            color: newTagColor.value
        }, { headers: { Accept: 'application/json' } });

        if (res.data?.success && res.data?.tag) {
            const tag = res.data.tag;
            availableTags.value.push(tag);
            newTagTitle.value = '';
            showCreateTagInline.value = false;
            if (activeSelectedWebhook.value) {
                await toggleWebhookTag(tag.id);
            }
        }
    } catch (e) {
        console.error('Failed to create tag inline:', e);
    } finally {
        creatingTag.value = false;
    }
}


const form = ref({
    id: props.automation.id,
    title: props.automation.title,
    status: props.automation.status,
    settings: props.automation.settings || {
        trigger: { type: 'new_user_signup', list_id: null, tag_id: null },
        description: '',
        subscription_status: 'subscribed',
        run_on_unsubscribed: false,
        nodes: [
            { id: 'n_trigger', type: 'trigger', title: props.automation.title, sub: 'New User Sign Up', config: {} }
        ],
        edges: []
    }
});

// Normalize trigger settings on load to support multiple triggers
const triggerSettings = form.value.settings.trigger || {};
if (!triggerSettings.triggers) {
    triggerSettings.triggers = [];
    if (triggerSettings.type) {
        triggerSettings.triggers.push({
            type: triggerSettings.type,
            list_id: triggerSettings.list_id || null,
            tag_id: triggerSettings.tag_id || null,
            campaign_id: triggerSettings.campaign_id || null
        });
    }
    triggerSettings.logical_operator = triggerSettings.logical_operator || 'OR';
    form.value.settings.trigger = triggerSettings;
}

function addTrigger() {
    if (!form.value.settings.trigger.triggers) {
        form.value.settings.trigger.triggers = [];
    }
    form.value.settings.trigger.triggers.push({
        type: 'new_user_signup',
        list_id: null,
        tag_id: null,
        campaign_id: null
    });
    debouncedSave();
}

function removeTrigger(index) {
    if (form.value.settings.trigger.triggers) {
        form.value.settings.trigger.triggers.splice(index, 1);
        debouncedSave();
    }
}

const saving = ref(false);
const editingName = ref(false);
const nameInput = ref(null);
const selectedNodeId = ref(null);
const activePanel = ref(null);
const testingWebhook = ref(false);
const testWebhookResult = ref(null);
const webhookAuthType = ref('none');
const webhookBearerToken = ref('');
const webhookBasicUser = ref('');
const webhookBasicPass = ref('');
const showPayloadPreview = ref(false);

const testingInboundWebhook = ref(false);
const testInboundWebhookResult = ref(null);
const inboundSimulationPayload = reactive({
    email: 'test-simulation@example.com',
    first_name: 'John',
    last_name: 'Doe',
    phone: '+1234567890',
    company: 'Acme Inc.'
});

const undoStack = [];
const redoStack = [];
const copiedNode = ref(null);
let isUndoingOrRedoing = false;

function undo() {
    if (undoStack.length <= 1) return;
    isUndoingOrRedoing = true;
    const currentState = undoStack.pop();
    redoStack.push(currentState);
    const previousState = undoStack[undoStack.length - 1];
    form.value.settings = JSON.parse(previousState);
    if (selectedNodeId.value) {
        const stillExists = form.value.settings.nodes.some(n => n.id === selectedNodeId.value);
        if (!stillExists) {
            selectedNodeId.value = null;
            activePanel.value = null;
        }
    }
    debouncedSave();
    setTimeout(() => {
        isUndoingOrRedoing = false;
    }, 100);
}

function redo() {
    if (redoStack.length === 0) return;
    isUndoingOrRedoing = true;
    const nextState = redoStack.pop();
    undoStack.push(nextState);
    form.value.settings = JSON.parse(nextState);
    if (selectedNodeId.value) {
        const stillExists = form.value.settings.nodes.some(n => n.id === selectedNodeId.value);
        if (!stillExists) {
            selectedNodeId.value = null;
            activePanel.value = null;
        }
    }
    debouncedSave();
    setTimeout(() => {
        isUndoingOrRedoing = false;
    }, 100);
}

function copyNode(nodeId) {
    const node = form.value.settings.nodes.find(n => n.id === nodeId);
    if (!node) return;
    if (node.type === 'trigger') return;
    copiedNode.value = JSON.parse(JSON.stringify(node));
}

function pasteNode() {
    if (!copiedNode.value) return;
    const node = JSON.parse(JSON.stringify(copiedNode.value));
    node.id = 'n_' + Math.random().toString(36).substr(2, 9);
    node.x = (node.x || 0) + 45;
    node.y = (node.y || 0) + 45;
    copiedNode.value.x = node.x;
    copiedNode.value.y = node.y;
    form.value.settings.nodes.push(node);
    if (node.type === 'webhook') {
        initWebhookAuthState(node);
    }
    selectedNodeId.value = node.id;
    activePanel.value = node.type;
    debouncedSave();
}

let recordTimeout = null;
watch(() => form.value.settings, (newVal) => {
    if (isUndoingOrRedoing) return;
    clearTimeout(recordTimeout);
    recordTimeout = setTimeout(() => {
        const currentStateStr = JSON.stringify(form.value.settings);
        if (undoStack.length === 0 || undoStack[undoStack.length - 1] !== currentStateStr) {
            undoStack.push(currentStateStr);
            if (undoStack.length > 50) {
                undoStack.shift();
            }
        }
    }, 300);
}, { deep: true });

function initWebhookAuthState(node) {
    if (!node.config) {
        node.config = { method: 'POST', url: '', payload_type: 'json', payload_mode: 'merged', headers: [], params: [] };
    }
    if (!node.config.headers) {
        node.config.headers = [];
    }
    if (!node.config.params) {
        node.config.params = [];
    }
    if (!node.config.payload_mode) {
        node.config.payload_mode = 'merged';
    }

    const authHeader = node.config.headers.find(h => h.key && h.key.toLowerCase() === 'authorization');
    if (authHeader) {
        const val = authHeader.value || '';
        if (val.toLowerCase().startsWith('bearer ')) {
            webhookAuthType.value = 'bearer';
            webhookBearerToken.value = val.substring(7);
            webhookBasicUser.value = '';
            webhookBasicPass.value = '';
        } else if (val.toLowerCase().startsWith('basic ')) {
            webhookAuthType.value = 'basic';
            try {
                const decoded = atob(val.substring(6));
                const parts = decoded.split(':');
                webhookBasicUser.value = parts[0] || '';
                webhookBasicPass.value = parts.slice(1).join(':') || '';
            } catch (e) {
                webhookBasicUser.value = '';
                webhookBasicPass.value = '';
            }
            webhookBearerToken.value = '';
        } else {
            webhookAuthType.value = 'custom';
            webhookBearerToken.value = '';
            webhookBasicUser.value = '';
            webhookBasicPass.value = '';
        }
    } else {
        webhookAuthType.value = 'none';
        webhookBearerToken.value = '';
        webhookBasicUser.value = '';
        webhookBasicPass.value = '';
    }
}

function syncWebhookAuth() {
    if (!selectedNode.value || selectedNode.value.type !== 'webhook') return;
    const config = selectedNode.value.config;
    if (!config.headers) config.headers = [];

    // Remove existing Authorization header
    config.headers = config.headers.filter(h => h.key && h.key.toLowerCase() !== 'authorization');

    if (webhookAuthType.value === 'bearer') {
        if (webhookBearerToken.value.trim()) {
            config.headers.push({ key: 'Authorization', value: `Bearer ${webhookBearerToken.value.trim()}` });
        }
    } else if (webhookAuthType.value === 'basic') {
        const user = webhookBasicUser.value.trim();
        const pass = webhookBasicPass.value.trim();
        if (user || pass) {
            try {
                const encoded = btoa(`${user}:${pass}`);
                config.headers.push({ key: 'Authorization', value: `Basic ${encoded}` });
            } catch (e) {
                // Ignore encoding errors
            }
        }
    }
    debouncedSave();
}

const webhookPayloadPreview = computed(() => {
    if (!selectedNode.value || selectedNode.value.type !== 'webhook') return '';
    const config = selectedNode.value.config || {};
    const mode = config.payload_mode || 'merged';
    const params = config.params || [];

    const customParams = {};
    params.forEach(p => {
        if (p.key) {
            customParams[p.key] = p.value || '';
        }
    });

    const contactData = {
        id: 999999,
        email: 'test@example.com',
        first_name: 'John',
        last_name: 'Doe',
        phone: '+15551234567',
        status: 'subscribed',
        contact_type: 'lead',
        total_points: 100,
        life_time_value: 500.00,
        timezone: 'UTC'
    };

    const payload = mode === 'custom' ? customParams : { ...contactData, ...customParams };
    return JSON.stringify(payload, null, 2);
});
const hoveredEdgeKey = ref(null);
const openTooltipNodeId = ref(null);
const showEmailBuilderModal = ref(false);

// Block selector state
const activeTab = ref('all');
const blockSearch = ref('');
const addActionContext = ref(null); // stores { sourceId, branch }

const triggerNode = computed(() => {
    return form.value.settings.nodes.find(n => n.type === 'trigger');
});

const selectedNode = computed(() => {
    return form.value.settings.nodes.find(n => n.id === selectedNodeId.value);
});

// Group node events by node_id and count statuses
const nodeStatus = computed(() => {
    const events = props.automation.node_events || [];
    const statusMap = {};
    
    events.forEach(e => {
        if (!statusMap[e.node_id]) {
            statusMap[e.node_id] = {
                processingCount: 0,
                successCount: 0,
                errorCount: 0,
                logs: []
            };
        }
        
        statusMap[e.node_id].logs.push(e);
        
        if (e.event_type === 'node_processing') {
            statusMap[e.node_id].processingCount++;
        } else if (e.event_type === 'node_success' || e.event_type === 'enrolled') {
            statusMap[e.node_id].successCount++;
        } else if (e.event_type === 'node_error') {
            statusMap[e.node_id].errorCount++;
        }
    });
    
    return statusMap;
});

// Log relative time formatting
function formatLogTime(isoString) {
    const date = new Date(isoString);
    const now = new Date();
    const diffMs = now - date;
    const diffSec = Math.floor(diffMs / 1000);
    const diffMin = Math.floor(diffSec / 60);
    const diffHr = Math.floor(diffMin / 60);
    
    if (diffSec < 60) return 'just now';
    if (diffMin < 60) return `${diffMin}m ago`;
    if (diffHr < 24) return `${diffHr}h ago`;
    return date.toLocaleDateString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' });
}

function formatDate(iso) {
    if (!iso) return 'Never';
    try {
        return new Date(iso).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric', hour: '2-digit', minute: '2-digit' });
    } catch (e) {
        return iso;
    }
}

// Polling setup to reload node_events when the automation is active
import { onUnmounted } from 'vue';
import { router } from '@inertiajs/vue3';

let pollTimer = null;
onMounted(() => {
    pollTimer = setInterval(() => {
        if (form.value.status === 'active') {
            router.reload({
                only: ['automation'],
                preserveScroll: true,
                preserveState: true,
            });
        }
    }, 5000);
});

onUnmounted(() => {
    if (pollTimer) {
        clearInterval(pollTimer);
    }
});

// ── DRAW.IO DRAG & DROP CANVAS LOGIC ──
const canvasMode = ref('drawio');
const boardEl = ref(null);
const canvasEl = ref(null);

// Spacebar Canvas Panning State
const isSpacePressed = ref(false);
const isPanningCanvas = ref(false);
let panStartX = 0;
let panStartY = 0;
let panStartScrollLeft = 0;
let panStartScrollTop = 0;

// Canvas Zoom & Fullscreen state
const zoomLevel = ref(1.0);
const isFullscreen = ref(false);
const showZoomDropdown = ref(false);

function zoomIn() {
    zoomLevel.value = Math.min(2.0, Math.round((zoomLevel.value + 0.1) * 10) / 10);
}

function zoomOut() {
    zoomLevel.value = Math.max(0.5, Math.round((zoomLevel.value - 0.1) * 10) / 10);
}

function resetZoom() {
    zoomLevel.value = 1.0;
}

function setZoomPct(pct) {
    zoomLevel.value = pct / 100;
    showZoomDropdown.value = false;
}

function toggleFullscreen() {
    isFullscreen.value = !isFullscreen.value;
}

const paletteBlocks = [
    { type: 'email', title: 'Send Email', desc: 'Send design template email', color: '#3b82f6', path: 'M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75' },
    { type: 'campaign_email', title: 'Campaign Email', desc: 'Import campaign mail', color: '#0284c7', path: 'M19.113 12.09a2 2 0 01-.218.83L15 20l-2.68-2.68A2 2 0 0111.91 16.5H5a2 2 0 01-2-2v-5a2 2 0 012-2h6.91a2 2 0 011.41.59L15 4l3.895 7.08a2 2 0 01.218.83v.18zM19.5 12h.008v.008H19.5V12z' },
    { type: 'wait', title: 'Wait / Delay', desc: 'Wait defined duration', color: '#f59e0b', path: 'M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z' },
    { type: 'condition', title: 'If / Else Condition', desc: 'Evaluate rule and split', color: '#8b5cf6', path: 'M7.5 21L3 16.5m0 0L7.5 12M3 16.5h13.5m0-13.5L21 7.5m0 0L16.5 12M21 7.5H7.5' },
    { type: 'webhook', title: 'Outgoing Webhook', desc: 'Call external endpoint', color: '#10b981', path: 'M14.25 9.75L16.5 12l-2.25 2.25m-4.5 0L7.5 12l2.25-2.25M6 20.25h12A2.25 2.25 0 0020.25 18V6A2.25 2.25 0 0018 3.75H6A2.25 2.25 0 003.75 6v12A2.25 2.25 0 006 20.25z' },
    // { type: 'incoming_webhook', title: 'Incoming Webhook', desc: 'Trigger funnel from Outgoing Webhook', color: '#ec4899', path: 'M19.5 13.5L12 21m0 0l-7.5-7.5M12 21V3' },

    { type: 'ab_split', title: 'A/B Split Test', desc: 'Split 50% / 50%', color: '#6366f1', path: 'M7.5 21L3 16.5m0 0L7.5 12M3 16.5h13.5m0-13.5L21 7.5m0 0L16.5 12M21 7.5H7.5' },
    { type: 'update_field', title: 'Update Property', desc: 'Update contact field', color: '#06b6d4', path: 'M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931z' },
    { type: 'apply_tag', title: 'Apply Tag', desc: 'Add tag label', color: '#64748b', path: 'M9.568 3H5.25A2.25 2.25 0 003 5.25v4.318c0 .597.237 1.17.659 1.591l9.581 9.581c.699.699 1.78.872 2.607.33a18.095 18.095 0 005.223-5.223c.542-.827.369-1.908-.33-2.607L11.16 3.66A2.25 2.25 0 009.568 3z' },
    { type: 'remove_tag', title: 'Remove Tag', desc: 'Strip tag from lead', color: '#64748b', path: 'M9.568 3H5.25A2.25 2.25 0 003 5.25v4.318c0 .597.237 1.17.659 1.591l9.581 9.581c.699.699 1.78.872 2.607.33a18.095 18.095 0 005.223-5.223c.542-.827.369-1.908-.33-2.607L11.16 3.66A2.25 2.25 0 009.568 3z' },
    { type: 'apply_list', title: 'Subscribe to List', desc: 'Add contact to list', color: '#10b981', path: 'M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z' },
    { type: 'remove_list', title: 'Unsubscribe from List', desc: 'Remove contact from list', color: '#ef4444', path: 'M9 12h6m2 9H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z' },
    { type: 'end', title: 'End Funnel', desc: 'Terminate workflow', color: '#ef4444', path: 'M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636' }
];

function ensureCoordinates() {
    form.value.settings.nodes.forEach((node, idx) => {
        if (typeof node.x !== 'number' || typeof node.y !== 'number') {
            node.x = 350;
            node.y = 80 + idx * 160;
        }
    });
}

function startCanvasPan(event) {
    isPanningCanvas.value = true;
    panStartX = event.clientX;
    panStartY = event.clientY;
    if (canvasEl.value) {
        panStartScrollLeft = canvasEl.value.scrollLeft;
        panStartScrollTop = canvasEl.value.scrollTop;
    }
}

function onCanvasMouseDown(event) {
    const isBgClick = event.target === boardEl.value || 
                      event.target === canvasEl.value || 
                      event.target.classList?.contains('af-drawio-svg') ||
                      event.target.tagName === 'svg';

    if (isSpacePressed.value || event.button === 1 || (event.button === 0 && isBgClick)) {
        startCanvasPan(event);
    }
}

onMounted(() => {
    ensureCoordinates();

    // Sync trigger node sub label dynamically on load
    const trgNode = form.value.settings.nodes.find(n => n.type === 'trigger');
    if (trgNode) {
        trgNode.sub = getNodeSubText(trgNode);
    }

    // Initialize undo stack with the starting state
    undoStack.push(JSON.stringify(form.value.settings));

    window.addEventListener('keydown', (e) => {
        if (e.target && (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.tagName === 'SELECT' || e.target.isContentEditable)) {
            return;
        }
        // Zoom In (Ctrl + Plus / Equal / Numpad Add)
        if ((e.ctrlKey || e.metaKey) && (e.key === '=' || e.key === '+' || e.key === 'Add')) {
            e.preventDefault();
            zoomIn();
        }
        // Zoom Out (Ctrl + Minus / Numpad Subtract)
        if ((e.ctrlKey || e.metaKey) && (e.key === '-' || e.key === 'Subtract')) {
            e.preventDefault();
            zoomOut();
        }
        // Reset Zoom (Ctrl + 0 / Numpad 0)
        if ((e.ctrlKey || e.metaKey) && (e.key === '0')) {
            e.preventDefault();
            resetZoom();
        }
        if (e.code === 'Space' || e.key === ' ') {
            isSpacePressed.value = true;
            e.preventDefault();
        }
        if (e.key === 'Escape' && drawingLine.active) {
            drawingLine.active = false;
            drawingLine.sourceId = null;
            hoveredTargetNodeId.value = null;
            hoveredTargetPort.value = null;
        }
        // Delete block on keypress
        if (e.key === 'Delete' || e.key === 'Backspace') {
            if (selectedNodeId.value) {
                onDeleteNode(selectedNodeId.value);
                selectedNodeId.value = null;
                activePanel.value = null;
            }
        }
        // Copy block (Ctrl + C / Cmd + C)
        if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'c') {
            if (selectedNodeId.value) {
                copyNode(selectedNodeId.value);
            }
        }
        // Paste block (Ctrl + V / Cmd + V)
        if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'v') {
            pasteNode();
        }
        // Undo (Ctrl + Z / Cmd + Z)
        if ((e.ctrlKey || e.metaKey) && !e.shiftKey && e.key.toLowerCase() === 'z') {
            e.preventDefault();
            undo();
        }
        // Redo (Ctrl + Y or Ctrl + Shift + Z / Cmd + Y or Cmd + Shift + Z)
        if (((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'y') || 
            ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key.toLowerCase() === 'z')) {
            e.preventDefault();
            redo();
        }
    });

    window.addEventListener('keyup', (e) => {
        if (e.code === 'Space' || e.key === ' ') {
            isSpacePressed.value = false;
            isPanningCanvas.value = false;
        }
    });

    window.addEventListener('mousemove', (e) => {
        if (isPanningCanvas.value && canvasEl.value) {
            const dx = e.clientX - panStartX;
            const dy = e.clientY - panStartY;
            canvasEl.value.scrollLeft = panStartScrollLeft - dx;
            canvasEl.value.scrollTop = panStartScrollTop - dy;
        }
    });

    window.addEventListener('mouseup', () => {
        if (isPanningCanvas.value) {
            isPanningCanvas.value = false;
        }
    });

    if (canvasEl.value) {
        canvasEl.value.addEventListener('wheel', (e) => {
            if (e.ctrlKey) {
                e.preventDefault();
                if (e.deltaY < 0) {
                    zoomIn();
                } else {
                    zoomOut();
                }
            }
        }, { passive: false });
    }

    const closeDropdown = () => {
        showZoomDropdown.value = false;
    };
    window.addEventListener('click', closeDropdown);

    onUnmounted(() => {
        window.removeEventListener('click', closeDropdown);
    });
});

function onPaletteDragStart(type, event) {
    event.dataTransfer.setData('application/x-automation-block', type);
    event.dataTransfer.effectAllowed = 'copy';
}

function onBoardDrop(event) {
    event.preventDefault();
    const type = event.dataTransfer.getData('application/x-automation-block');
    if (!type) return;

    const rect = boardEl.value ? boardEl.value.getBoundingClientRect() : { left: 0, top: 0 };
    const x = Math.max(20, Math.round(((event.clientX - rect.left) / zoomLevel.value) / 10) * 10);
    const y = Math.max(20, Math.round(((event.clientY - rect.top) / zoomLevel.value) / 10) * 10);

    const newNode = {
        id: 'n_' + Math.random().toString(36).substr(2, 9),
        type: type,
        title: defaultTitle(type),
        sub: defaultSubText(type),
        x: x,
        y: y,
        config: defaultConfig(type)
    };

    form.value.settings.nodes.push(newNode);
    debouncedSave();
}

function addNodeAtCenter(type) {
    let x = 350;
    let y = 150;
    if (canvasEl.value) {
        const scrollLeft = canvasEl.value.scrollLeft || 0;
        const scrollTop = canvasEl.value.scrollTop || 0;
        const width = canvasEl.value.clientWidth || 800;
        const height = canvasEl.value.clientHeight || 600;
        x = Math.round(((scrollLeft + width / 2) / zoomLevel.value - 145) / 10) * 10;
        y = Math.round(((scrollTop + height / 2) / zoomLevel.value - 40) / 10) * 10;
    }
    const newNode = {
        id: 'n_' + Math.random().toString(36).substr(2, 9),
        type: type,
        title: defaultTitle(type),
        sub: defaultSubText(type),
        x: Math.max(20, x),
        y: Math.max(20, y),
        config: defaultConfig(type)
    };

    form.value.settings.nodes.push(newNode);
    debouncedSave();
}

// Dragging nodes on canvas
const draggingNode = reactive({
    active: false,
    node: null,
    offsetX: 0,
    offsetY: 0
});

function startNodeDrag(node, event) {
    if (isSpacePressed.value || event.button === 1) {
        startCanvasPan(event);
        return;
    }
    if (event.button !== 0) return; // left click only
    draggingNode.active = true;
    draggingNode.node = node;
    const rect = boardEl.value ? boardEl.value.getBoundingClientRect() : { left: 0, top: 0 };
    draggingNode.offsetX = ((event.clientX - rect.left) / zoomLevel.value) - (node.x || 300);
    draggingNode.offsetY = ((event.clientY - rect.top) / zoomLevel.value) - (node.y || 100);
}

// Drawing connection lines between 2 blocks
const drawingLine = reactive({
    active: false,
    sourceId: null,
    sourcePort: 'bottom',
    startX: 0,
    startY: 0,
    currentX: 0,
    currentY: 0,
    startedAt: 0
});

const hoveredTargetNodeId = ref(null);
const hoveredTargetPort = ref(null);

function getNodeHeight(node) {
    const el = document.getElementById(`drawio-node-${node.id}`);
    return el ? el.offsetHeight : 78;
}

function getPortCoords(node, portType = 'bottom') {
    const h = getNodeHeight(node);
    const x = node.x || 300;
    const y = node.y || 100;
    if (portType === 'top') return { x: x + 145, y: y, dir: { dx: 0, dy: -1 } };
    if (portType === 'left') return { x: x, y: y + h / 2, dir: { dx: -1, dy: 0 } };
    if (portType === 'right') return { x: x + 290, y: y + h / 2, dir: { dx: 1, dy: 0 } };
    return { x: x + 145, y: y + h, dir: { dx: 0, dy: 1 } };
}

function getBestPorts(n1, n2) {
    const h1 = getNodeHeight(n1);
    const h2 = getNodeHeight(n2);
    const cx1 = (n1.x || 300) + 145;
    const cy1 = (n1.y || 100) + h1 / 2;
    const cx2 = (n2.x || 300) + 145;
    const cy2 = (n2.y || 100) + h2 / 2;
    const dx = cx2 - cx1;
    const dy = cy2 - cy1;

    if (Math.abs(dy) >= Math.abs(dx)) {
        return {
            sourcePort: dy >= 0 ? 'bottom' : 'top',
            targetPort: dy >= 0 ? 'top' : 'bottom'
        };
    } else {
        return {
            sourcePort: dx >= 0 ? 'right' : 'left',
            targetPort: dx >= 0 ? 'left' : 'right'
        };
    }
}

function isPortConnected(nodeId, portType) {
    if (!form.value?.settings?.edges) return false;
    return form.value.settings.edges.some(edge => {
        const n1 = form.value.settings.nodes.find(n => n.id === edge.source);
        const n2 = form.value.settings.nodes.find(n => n.id === edge.target);
        if (!n1 || !n2) return false;

        let sp = edge.sourcePort;
        let tp = edge.targetPort;
        if (!sp || !tp) {
            const best = getBestPorts(n1, n2);
            sp = sp || best.sourcePort;
            tp = tp || best.targetPort;
        }

        if (edge.source === nodeId && sp === portType) return true;
        if (edge.target === nodeId && tp === portType) return true;
        return false;
    });
}

function startLineDrag(nodeId, portType, event) {
    if (isSpacePressed.value || event.button === 1) {
        startCanvasPan(event);
        return;
    }
    if (event.button !== 0) return;
    const node = form.value.settings.nodes.find(n => n.id === nodeId);
    if (!node) return;
    drawingLine.active = true;
    drawingLine.sourceId = nodeId;
    drawingLine.sourcePort = portType || 'bottom';

    const coords = getPortCoords(node, drawingLine.sourcePort);
    drawingLine.startX = coords.x;
    drawingLine.startY = coords.y;
    drawingLine.startedAt = Date.now();

    const rect = boardEl.value ? boardEl.value.getBoundingClientRect() : { left: 0, top: 0 };
    drawingLine.currentX = (event.clientX - rect.left) / zoomLevel.value;
    drawingLine.currentY = (event.clientY - rect.top) / zoomLevel.value;
}

function finishLineToNode(targetId, targetPort = null) {
    if (drawingLine.active && drawingLine.sourceId && drawingLine.sourceId !== targetId) {
        const sourceNode = form.value.settings.nodes.find(n => n.id === drawingLine.sourceId);
        const targetNode = form.value.settings.nodes.find(n => n.id === targetId);
        let sp = drawingLine.sourcePort;
        let tp = targetPort;
        if (sourceNode && targetNode && (!sp || !tp)) {
            const best = getBestPorts(sourceNode, targetNode);
            sp = sp || best.sourcePort;
            tp = tp || best.targetPort;
        }

        const existingIdx = form.value.settings.edges.findIndex(e => e.source === drawingLine.sourceId && e.target === targetId);
        if (existingIdx !== -1) {
            form.value.settings.edges[existingIdx].sourcePort = sp;
            form.value.settings.edges[existingIdx].targetPort = tp;
        } else {
            form.value.settings.edges.push({
                source: drawingLine.sourceId,
                target: targetId,
                sourcePort: sp,
                targetPort: tp
            });
        }
        debouncedSave();
        drawingLine.active = false;
        drawingLine.sourceId = null;
        hoveredTargetNodeId.value = null;
        hoveredTargetPort.value = null;
    }
}

function onNodeClick(node) {
    if (drawingLine.active && drawingLine.sourceId && drawingLine.sourceId !== node.id) {
        finishLineToNode(node.id, hoveredTargetPort.value);
        return;
    }
    onSelectNode(node);
}

function onBoardMouseMove(event) {
    if (!boardEl.value) return;
    const rect = boardEl.value.getBoundingClientRect();
    const mouseX = (event.clientX - rect.left) / zoomLevel.value;
    const mouseY = (event.clientY - rect.top) / zoomLevel.value;

    if (isPanningCanvas.value && canvasEl.value) {
        const dx = event.clientX - panStartX;
        const dy = event.clientY - panStartY;
        canvasEl.value.scrollLeft = panStartScrollLeft - dx;
        canvasEl.value.scrollTop = panStartScrollTop - dy;
        return;
    }

    if (draggingNode.active && draggingNode.node) {
        draggingNode.node.x = Math.max(20, Math.round((mouseX - draggingNode.offsetX) / 10) * 10);
        draggingNode.node.y = Math.max(20, Math.round((mouseY - draggingNode.offsetY) / 10) * 10);
    }

    if (drawingLine.active) {
        drawingLine.currentX = mouseX;
        drawingLine.currentY = mouseY;
    }
}

function onBoardMouseUp() {
    if (isPanningCanvas.value) {
        isPanningCanvas.value = false;
    }
    if (draggingNode.active) {
        draggingNode.active = false;
        draggingNode.node = null;
        debouncedSave();
    }
    if (drawingLine.active) {
        if (hoveredTargetNodeId.value && hoveredTargetNodeId.value !== drawingLine.sourceId) {
            finishLineToNode(hoveredTargetNodeId.value, hoveredTargetPort.value);
        } else {
            if (Date.now() - (drawingLine.startedAt || 0) > 350) {
                drawingLine.active = false;
                drawingLine.sourceId = null;
                hoveredTargetNodeId.value = null;
                hoveredTargetPort.value = null;
            }
        }
    }
}

function onCanvasClick() {
    if (drawingLine.active) {
        drawingLine.active = false;
        drawingLine.sourceId = null;
        return;
    }
    selectedNodeId.value = null;
    activePanel.value = null;
}

// SVG line computation
function getEdgePath(edge) {
    const n1 = form.value.settings.nodes.find(n => n.id === edge.source);
    const n2 = form.value.settings.nodes.find(n => n.id === edge.target);
    if (!n1 || !n2) return '';

    let sp = edge.sourcePort;
    let tp = edge.targetPort;
    if (!sp || !tp) {
        const best = getBestPorts(n1, n2);
        sp = sp || best.sourcePort;
        tp = tp || best.targetPort;
    }

    const p1 = getPortCoords(n1, sp);
    const p2 = getPortCoords(n2, tp);

    const dist = Math.hypot(p2.x - p1.x, p2.y - p1.y);
    const offset = Math.max(45, Math.min(dist * 0.45, 160));

    const c1x = p1.x + p1.dir.dx * offset;
    const c1y = p1.y + p1.dir.dy * offset;
    const c2x = p2.x + p2.dir.dx * offset;
    const c2y = p2.y + p2.dir.dy * offset;

    return `M ${p1.x} ${p1.y} C ${c1x} ${c1y}, ${c2x} ${c2y}, ${p2.x} ${p2.y}`;
}

function getPreviewLinePath() {
    const sourceNode = form.value.settings.nodes.find(n => n.id === drawingLine.sourceId);
    const p1 = sourceNode 
        ? getPortCoords(sourceNode, drawingLine.sourcePort || 'bottom') 
        : { x: drawingLine.startX, y: drawingLine.startY, dir: { dx: 0, dy: 1 } };

    let x2 = drawingLine.currentX;
    let y2 = drawingLine.currentY;
    let dir2 = { dx: 0, dy: -1 };

    if (hoveredTargetNodeId.value && hoveredTargetNodeId.value !== drawingLine.sourceId) {
        const targetNode = form.value.settings.nodes.find(n => n.id === hoveredTargetNodeId.value);
        if (targetNode) {
            const tp = hoveredTargetPort.value || getBestPorts(sourceNode, targetNode).targetPort;
            const p2 = getPortCoords(targetNode, tp);
            x2 = p2.x;
            y2 = p2.y;
            dir2 = p2.dir;
        }
    }

    const dist = Math.hypot(x2 - p1.x, y2 - p1.y);
    const offset = Math.max(40, Math.min(dist * 0.45, 150));

    const c1x = p1.x + p1.dir.dx * offset;
    const c1y = p1.y + p1.dir.dy * offset;
    const c2x = x2 + dir2.dx * offset;
    const c2y = y2 + dir2.dy * offset;

    return `M ${p1.x} ${p1.y} C ${c1x} ${c1y}, ${c2x} ${c2y}, ${x2} ${y2}`;
}

function getEdgeMidpointStyle(edge) {
    const n1 = form.value.settings.nodes.find(n => n.id === edge.source);
    const n2 = form.value.settings.nodes.find(n => n.id === edge.target);
    if (!n1 || !n2) return { display: 'none' };

    let sp = edge.sourcePort;
    let tp = edge.targetPort;
    if (!sp || !tp) {
        const best = getBestPorts(n1, n2);
        sp = sp || best.sourcePort;
        tp = tp || best.targetPort;
    }

    const p1 = getPortCoords(n1, sp);
    const p2 = getPortCoords(n2, tp);

    const dist = Math.hypot(p2.x - p1.x, p2.y - p1.y);
    const offset = Math.max(45, Math.min(dist * 0.45, 160));

    const c1x = p1.x + p1.dir.dx * offset;
    const c1y = p1.y + p1.dir.dy * offset;
    const c2x = p2.x + p2.dir.dx * offset;
    const c2y = p2.y + p2.dir.dy * offset;

    const midX = 0.125 * p1.x + 0.375 * c1x + 0.375 * c2x + 0.125 * p2.x;
    const midY = 0.125 * p1.y + 0.375 * c1y + 0.375 * c2y + 0.125 * p2.y;

    return {
        left: midX + 'px',
        top: midY + 'px'
    };
}

function deleteEdge(edge) {
    const idx = form.value.settings.edges.findIndex(e => e.source === edge.source && e.target === edge.target);
    if (idx !== -1) {
        form.value.settings.edges.splice(idx, 1);
        debouncedSave();
    }
}

function getNodeSvgPath(type) {
    const found = paletteBlocks.find(b => b.type === type);
    return found ? found.path : 'M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z';
}

function nodeCategory(type) {
    if (type === 'trigger') return 'Trigger';
    if (type === 'condition' || type === 'ab_split' || type === 'wait') return 'Logic';
    if (type === 'webhook') return 'API';

    if (type === 'end') return 'End';
    return 'Action';
}

// Auto-save logic
let saveTimer = null;
function debouncedSave() {
    // Sync trigger node sub text dynamically
    const trgNode = form.value.settings.nodes.find(n => n.type === 'trigger');
    if (trgNode) {
        trgNode.sub = getNodeSubText(trgNode);
    }

    clearTimeout(saveTimer);
    saving.value = true;
    saveTimer = setTimeout(() => {
        window.axios.put(`/automation/${form.value.id}`, {
            title: form.value.title,
            status: form.value.status,
            settings: form.value.settings
        }).then(() => {
            saving.value = false;
        }).catch(err => {
            console.error('Failed to save automation settings', err);
            saving.value = false;
        });
    }, 1000);
}

function runWebhookTest() {
    if (!selectedNode.value?.config?.url) {
        alert('Please specify a Webhook URL first.');
        return;
    }
    testingWebhook.value = true;
    testWebhookResult.value = null;

    window.axios.post('/automation/test-webhook', {
        url: selectedNode.value.config.url,
        method: selectedNode.value.config.method || 'POST',
        payload_type: selectedNode.value.config.payload_type || 'json',
        payload_mode: selectedNode.value.config.payload_mode || 'merged',
        headers: selectedNode.value.config.headers || [],
        params: selectedNode.value.config.params || []
    }).then(res => {
        testingWebhook.value = false;
        testWebhookResult.value = {
            success: res.data.success,
            status: res.data.status,
            body: res.data.body || '(Empty Response Body)'
        };
    }).catch(err => {
        testingWebhook.value = false;
        testWebhookResult.value = {
            success: false,
            status: err.response?.status || 500,
            body: err.response?.data?.message || err.message || 'Connection Error'
        };
    });
}

function runInboundWebhookTest() {
    testingInboundWebhook.value = true;
    testInboundWebhookResult.value = null;

    const url = getIncomingWebhookUrl(selectedNode.value.id);

    window.axios.post(url, inboundSimulationPayload)
        .then(res => {
            testingInboundWebhook.value = false;
            testInboundWebhookResult.value = {
                success: res.data.success !== false,
                status: res.status,
                body: typeof res.data === 'object' ? JSON.stringify(res.data, null, 2) : res.data || '(Empty Response Body)'
            };
        })
        .catch(err => {
            testingInboundWebhook.value = false;
            testInboundWebhookResult.value = {
                success: false,
                status: err.response?.status || 500,
                body: typeof err.response?.data === 'object' ? JSON.stringify(err.response.data, null, 2) : err.response?.data?.message || err.message || 'Connection Error'
            };
        });
}

function updateConditionNodeSubtitle() {
    if (selectedNode.value && selectedNode.value.type === 'condition') {
        const count = selectedNode.value.config?.conditions?.length || 0;
        selectedNode.value.sub = `Matching ${count} condition set${count !== 1 ? 's' : ''}`;
    }
}

function onConditionFieldChange(cond) {
    if (cond.field === 'Last Purchase Date' || cond.field === 'Last Activity' || cond.field === 'Birthday' || cond.field === 'Date Added') {
        cond.operator = 'is before';
        cond.value = '';
        cond.unit = 'days ago';
    } else if (cond.field === 'Subscription Status') {
        cond.operator = 'equals';
        cond.value = 'subscribed';
    } else if (cond.field === 'Contact Type') {
        cond.operator = 'equals';
        cond.value = 'lead';
    } else if (cond.field === 'Lifetime Value' || cond.field === 'LTV') {
        cond.operator = 'greater than';
        cond.value = 100;
    } else if (cond.field === 'Company') {
        cond.operator = 'equals';
        cond.value = '';
    } else if (cond.field === 'List') {
        cond.operator = 'equals';
        cond.value = props.lists?.[0]?.id || null;
    } else if (cond.field === 'Tag') {
        cond.operator = 'equals';
        cond.value = props.tags?.[0]?.id || null;
    } else {
        cond.operator = 'equals';
        cond.value = '';
    }
    updateConditionNodeSubtitle();
    debouncedSave();
}

function getIncomingWebhookUrl(nodeId) {
    if (activeSelectedWebhook.value && activeSelectedWebhook.value.receive_url) {
        return activeSelectedWebhook.value.receive_url;
    }
    if (!props.automation) return '';
    return `${window.location.origin}/api/webhooks/incoming/${props.automation.id}/${nodeId}`;
}

async function copyIncomingWebhookUrl(nodeId) {
    const url = getIncomingWebhookUrl(nodeId);
    try {
        await navigator.clipboard.writeText(url);
        alert('Webhook URL copied to clipboard!');
    } catch (err) {
        console.error('Failed to copy text', err);
    }
}

function startEditName() {
    editingName.value = true;
    nextTick(() => {
        if (nameInput.value) {
            nameInput.value.focus();
            nameInput.value.select();
        }
    });
}

function stopEditName() {
    editingName.value = false;
    debouncedSave();
}

function toggleStatus(e) {
    form.value.status = e.target.checked ? 'active' : 'draft';
    debouncedSave();
}

function togglePlayPause() {
    const isActivating = form.value.status !== 'active';
    form.value.status = isActivating ? 'active' : 'draft';

    // Disable play button while transitioning/saving
    saving.value = true;

    window.axios.put(`/automation/${form.value.id}`, {
        title: form.value.title,
        status: form.value.status,
        settings: form.value.settings
    }).then(() => {
        saving.value = false;
        if (isActivating) {
            router.post(route('automation.run', props.automation.id), {}, {
                preserveScroll: true,
                preserveState: true,
            });
        } else {
            router.get(route('automation.edit', props.automation.id), {}, {
                preserveScroll: true,
                preserveState: true,
            });
        }
    }).catch(err => {
        saving.value = false;
        console.error('Failed to update automation status', err);
    });
}

function runAutomation() {
    if (confirm('Are you sure you want to manually run/enroll matching contacts in this automation?')) {
        router.post(route('automation.run', props.automation.id), {}, {
            preserveScroll: true,
            preserveState: true,
        });
    }
}

function restartAutomation() {
    if (confirm('Are you sure you want to restart this automation? This will delete all execution event logs and reset metrics.')) {
        router.post(route('automation.restart', props.automation.id), {}, {
            preserveScroll: true,
            preserveState: true,
        });
    }
}

function importCampaignDesign() {
    const campaignId = selectedNode.value.config.imported_campaign_id;
    if (!campaignId) return;

    const campaign = props.campaigns.find(c => c.id === parseInt(campaignId));
    if (!campaign) return;

    if (!selectedNode.value.config) {
        selectedNode.value.config = {};
    }

    selectedNode.value.config.subject = campaign.email_subject || '';
    selectedNode.value.config.email_body = campaign.email_body || '';
    selectedNode.value.config.design_template = campaign.design_template || null;
    selectedNode.value.config.template_id = campaign.template_id || null;

    if (campaign.settings && campaign.settings.smtp_config_id) {
        selectedNode.value.config.smtp_config_id = campaign.settings.smtp_config_id;
    }

    if (campaign.settings && campaign.settings.blocks) {
        selectedNode.value.config.blocks = JSON.parse(JSON.stringify(campaign.settings.blocks));
    } else {
        selectedNode.value.config.blocks = [];
    }

    selectedNode.value.config.pre_header = campaign.email_pre_header || '';

    selectedNode.value.sub = 'Design: ' + campaign.title;
    debouncedSave();
}

function onBlocksUpdate(newBlocks) {
    if (selectedNode.value && selectedNode.value.config) {
        selectedNode.value.config.blocks = newBlocks;
        debouncedSave();
    }
}

function onSmtpChange() {
    debouncedSave();
}

function getSmtpPlaceholder(field, fallback) {
    if (selectedNode.value?.config?.smtp_config_id) {
        const s = props.smtpConfigs.find(s => s.id === selectedNode.value.config.smtp_config_id);
        if (s && s[field]) return s[field];
    }
    if (props.defaultSender && props.defaultSender[field]) {
        return props.defaultSender[field];
    }
    if (props.globalSettings?.email && props.globalSettings.email[field]) {
        return props.globalSettings.email[field];
    }
    return fallback;
}

function onSelectNode(node) {
    selectedNodeId.value = node.id;
    activePanel.value = node.type;
    if (node.type === 'email' && node.config) {
        if (node.config.smtp_config_id === undefined) {
            node.config.smtp_config_id = null;
        }
        if (node.config.imported_campaign_id === undefined) {
            node.config.imported_campaign_id = null;
        }
        if (!node.config.send_to_type) {
            node.config.send_to_type = 'contact';
        }
        if (node.config.custom_email_address === undefined) {
            node.config.custom_email_address = '';
        }
        if (node.config.pre_header === undefined) {
            node.config.pre_header = '';
        }
        if (!node.config.blocks) {
            node.config.blocks = [];
        }
    }
    if (node.type === 'webhook') {
        initWebhookAuthState(node);
    }
}

function onAddClick(context) {
    addActionContext.value = context; // { sourceId, branch }
    activePanel.value = 'add-action';
}

function addConditionSet() {
    if (!selectedNode.value.config.conditions) {
        selectedNode.value.config.conditions = [];
    }
    selectedNode.value.config.conditions.push({
        field: 'Last Purchase Date',
        operator: 'is before',
        value: 30,
        unit: 'days ago'
    });
    updateConditionNodeSubtitle();
    debouncedSave();
}

function removeConditionSet(idx) {
    selectedNode.value.config.conditions.splice(idx, 1);
    updateConditionNodeSubtitle();
    debouncedSave();
}

function insertNode(type) {
    if (!addActionContext.value) return;
    const { sourceId, branch } = addActionContext.value;
    const newId = 'n_' + Math.random().toString(36).substr(2, 9);
    
    const newNode = {
        id: newId,
        type,
        title: defaultTitle(type),
        sub: defaultSubText(type),
        config: defaultConfig(type),
    };

    // 1. Add node to array
    form.value.settings.nodes.push(newNode);

    // 2. Adjust edges
    // Find the existing edge originating from sourceId (with matching branch if condition)
    const oldEdgeIdx = form.value.settings.edges.findIndex(e => e.source === sourceId && e.branch === branch);

    if (oldEdgeIdx !== -1) {
        const oldTarget = form.value.settings.edges[oldEdgeIdx].target;
        // Point sourceId -> newNode
        form.value.settings.edges[oldEdgeIdx].target = newId;

        // If newNode is a condition or ab_split, we don't automatically connect it downstream on both branches.
        // If it's a regular action node, it should reconnect to oldTarget.
        if (type !== 'condition' && type !== 'ab_split') {
            form.value.settings.edges.push({
                source: newId,
                target: oldTarget
            });
        } else {
            // For a newly added condition or ab_split, oldTarget goes to the 'yes' branch by default
            form.value.settings.edges.push({
                source: newId,
                target: oldTarget,
                branch: 'yes'
            });
        }
    } else {
        // No existing edge downstream, just connect sourceId -> newNode
        form.value.settings.edges.push({
            source: sourceId,
            target: newId,
            branch
        });
    }

    activePanel.value = null;
    addActionContext.value = null;
    debouncedSave();
}

function onDeleteNode(nodeId) {
    // Cannot delete trigger
    if (nodeId === triggerNode.value.id) return;

    // 1. Find downstream edges and nodes
    const incomingEdgeIdx = form.value.settings.edges.findIndex(e => e.target === nodeId);
    const outgoingEdges = form.value.settings.edges.filter(e => e.source === nodeId);

    if (incomingEdgeIdx !== -1) {
        const sourceId = form.value.settings.edges[incomingEdgeIdx].source;
        const branch = form.value.settings.edges[incomingEdgeIdx].branch;

        // Remove incoming edge
        form.value.settings.edges.splice(incomingEdgeIdx, 1);

        // If it was a condition node, we might have multiple outgoing branches.
        // We delete outgoing edges as well. To keep visual tree clean, we don't orphaned children.
        // Let's reconnect the parent (sourceId) to the 'yes' branch of the deleted node, or the default next node.
        const defaultOutgoing = outgoingEdges.find(e => !e.branch || e.branch === 'yes');
        if (defaultOutgoing) {
            form.value.settings.edges.push({
                source: sourceId,
                target: defaultOutgoing.target,
                branch
            });
        }

        // Delete all other branches outgoing edges/nodes to prevent orphans
        outgoingEdges.forEach(outEdge => {
            if (outEdge !== defaultOutgoing) {
                deleteSubtree(outEdge.target);
            }
        });
    }

    // 2. Remove the node itself
    const nodeIdx = form.value.settings.nodes.findIndex(n => n.id === nodeId);
    if (nodeIdx !== -1) {
        form.value.settings.nodes.splice(nodeIdx, 1);
    }

    // Clean up any remaining outgoing edges of the deleted node
    form.value.settings.edges = form.value.settings.edges.filter(e => e.source !== nodeId);

    selectedNodeId.value = null;
    activePanel.value = null;
    debouncedSave();
}

// Recursively delete all nodes downstream from startingNodeId
function deleteSubtree(startingNodeId) {
    const nodesToDelete = [startingNodeId];
    const visited = new Set();

    while (nodesToDelete.length > 0) {
        const current = nodesToDelete.pop();
        if (visited.has(current)) continue;
        visited.add(current);

        // Find child edges
        const children = form.value.settings.edges.filter(e => e.source === current);
        children.forEach(c => {
            nodesToDelete.push(c.target);
        });
    }

    // Filter out deleted nodes & edges
    form.value.settings.nodes = form.value.settings.nodes.filter(n => !visited.has(n.id));
    form.value.settings.edges = form.value.settings.edges.filter(e => !visited.has(e.source) && !visited.has(e.target));
}

function defaultTitle(type) {
    const titles = {
        email: 'Send Email',
        campaign_email: 'Campaign Email',
        wait: 'Wait / Delay',
        condition: 'If / Else Condition',
        webhook: 'Outgoing Webhook',
        incoming_webhook: 'Incoming Webhook',

        ab_split: 'A/B Split Test',
        update_field: 'Update Property',
        apply_tag: 'Apply Tag',
        remove_tag: 'Remove Tag',
        apply_list: 'Subscribe to List',
        remove_list: 'Unsubscribe from List',
        end: 'End Funnel',
    };
    return titles[type] || type;
}

function onListChange() {
    if (selectedNode.value && selectedNode.value.config?.list_id) {
        const l = props.lists.find(l => l.id === selectedNode.value.config.list_id);
        if (l) {
            selectedNode.value.sub = (selectedNode.value.type === 'apply_list' ? 'Subscribe: ' : 'Unsubscribe: ') + l.title;
        }
    } else {
        selectedNode.value.sub = selectedNode.value.type === 'apply_list' ? 'Subscribe to list' : 'Unsubscribe from list';
    }
    debouncedSave();
}

function onTagChange() {
    if (selectedNode.value && selectedNode.value.config?.tag_id) {
        const t = props.tags.find(t => t.id === selectedNode.value.config.tag_id);
        if (t) {
            selectedNode.value.sub = (selectedNode.value.type === 'apply_tag' ? 'Apply: ' : 'Remove: ') + t.title;
        }
    } else {
        selectedNode.value.sub = selectedNode.value.type === 'apply_tag' ? 'Apply tag' : 'Remove tag';
    }
    debouncedSave();
}

function addWebhookHeader() {
    if (!selectedNode.value.config.headers) {
        selectedNode.value.config.headers = [];
    }
    selectedNode.value.config.headers.push({ key: '', value: '' });
    debouncedSave();
}

function removeWebhookHeader(idx) {
    selectedNode.value.config.headers.splice(idx, 1);
    debouncedSave();
}

function addWebhookParam() {
    if (!selectedNode.value.config.params) {
        selectedNode.value.config.params = [];
    }
    selectedNode.value.config.params.push({ key: '', value: '' });
    debouncedSave();
}

function removeWebhookParam(idx) {
    selectedNode.value.config.params.splice(idx, 1);
    debouncedSave();
}

function getNodeSubText(node) {
    const type = node.type;
    const config = node.config || {};

    if (type === 'trigger') {
        const trg = form.value.settings.trigger || {};
        const triggers = trg.triggers || [];
        if (triggers.length === 0) {
            const singleType = trg.type || 'new_user_signup';
            const opt = triggerTypeOptions.find(o => o.value === singleType);
            return opt ? opt.label : 'New User Sign Up';
        }
        
        if (triggers.length === 1) {
            const t = triggers[0];
            const opt = triggerTypeOptions.find(o => o.value === t.type);
            const label = opt ? opt.label : t.type;
            if (t.type === 'incoming_webhook') {
                const w = getActiveWebhookForTrigger(t);
                return w ? `Webhook: ${w.name}` : 'Incoming Webhook';
            }
            if (t.type === 'subscribes_to_list') {
                const list = props.lists.find(l => l.id === parseInt(t.list_id));
                return list ? `Subscribes to: ${list.title}` : 'Subscribes to List';
            }
            if (t.type === 'tag_applied') {
                const tag = props.tags.find(tg => tg.id === parseInt(t.tag_id));
                return tag ? `Tag Applied: ${tag.title}` : 'Tag Applied';
            }
            return label;
        }

        if (triggers.length > 2) {
            return `${triggers.length} Trigger Events`;
        }

        const labels = triggers.map(t => {
            const opt = triggerTypeOptions.find(o => o.value === t.type);
            return opt ? opt.label : t.type;
        });
        return `Triggers: ${labels.join(' & ')}`;
    }
    
    if (type === 'wait') {
        const val = config.value !== undefined ? config.value : 1;
        const unit = config.unit || 'days';
        return `Wait ${val} ${unit}`;
    }
    if (type === 'email') {
        if (config.imported_campaign_id) {
            const campaign = props.campaigns.find(c => c.id === parseInt(config.imported_campaign_id));
            if (campaign) return `Design: ${campaign.title}`;
        }
        return `Subject: ${config.subject || 'Hey there!'}`;
    }
    if (type === 'campaign_email') {
        if (config.imported_campaign_id) {
            const campaign = props.campaigns.find(c => c.id === parseInt(config.imported_campaign_id));
            if (campaign) return `Campaign: ${campaign.title}`;
        }
        return 'Select a Campaign...';
    }
    if (type === 'webhook') {
        return `${config.method || 'POST'} ${config.url || 'https://api.external.endpoint'}`;
    }
    if (type === 'incoming_webhook') {
        return 'HTTP POST Webhook Trigger';
    }
    if (type === 'ab_split') {
        return `Split ${config.split_percentage || 50}% / ${100 - (config.split_percentage || 50)}%`;
    }
    if (type === 'update_field') {
        return `Set ${config.field_name || 'contact_type'} = ${config.value || 'lead'}`;
    }
    if (type === 'apply_tag') {
        const tag = props.tags.find(t => t.id === parseInt(config.tag_id));
        return tag ? `Apply: ${tag.title}` : 'Attach tag to profile';
    }
    if (type === 'remove_tag') {
        const tag = props.tags.find(t => t.id === parseInt(config.tag_id));
        return tag ? `Remove: ${tag.title}` : 'Remove tag from profile';
    }
    if (type === 'apply_list') {
        const list = props.lists.find(l => l.id === parseInt(config.list_id));
        return list ? `Subscribe: ${list.title}` : 'Subscribe contact to list';
    }
    if (type === 'remove_list') {
        const list = props.lists.find(l => l.id === parseInt(config.list_id));
        return list ? `Unsubscribe: ${list.title}` : 'Unsubscribe contact from list';
    }
    return node.sub || '';
}

function defaultSubText(type) {
    if (type === 'wait') return 'Wait 1 days';
    if (type === 'email') return 'Custom email content';
    if (type === 'campaign_email') return 'Imported campaign mail';
    if (type === 'webhook') return 'POST External API Endpoint';
    if (type === 'incoming_webhook') return 'HTTP POST Webhook Trigger';

    if (type === 'ab_split') return 'Split 50% / 50% (A/B Test)';
    if (type === 'update_field') return 'Set contact_type = lead';
    if (type === 'apply_list') return 'Subscribe to list';
    if (type === 'remove_list') return 'Unsubscribe from list';
    return '';
}

function defaultConfig(type) {
    if (type === 'wait') return { value: 1, unit: 'days', send_time: 'immediately' };
    if (type === 'email') return { subject: 'Hey there!', pre_header: '', template_id: null, from_name: '', from_email: '', email_body: '', smtp_config_id: null, imported_campaign_id: null, send_to_type: 'contact', custom_email_address: '', blocks: [] };
    if (type === 'campaign_email') return { imported_campaign_id: null, send_to_type: 'contact', custom_email_address: '' };
    if (type === 'condition') return { conditions: [{ field: 'Last Purchase Date', operator: 'is before', value: 30, unit: 'days ago' }] };
    if (type === 'webhook') return { method: 'POST', url: '', payload_type: 'json', headers: [], params: [] };
    if (type === 'incoming_webhook') return { auth_type: 'none', token: '' };

    if (type === 'ab_split') return { split_percentage: 50 };
    if (type === 'update_field') return { field_name: 'contact_type', value: 'lead' };
    if (type === 'apply_tag' || type === 'remove_tag') return { tag_id: null };
    if (type === 'apply_list' || type === 'remove_list') return { list_id: null };
    return {};
}

function shouldShowBlock(type) {
    // Filtering by tab
    if (activeTab.value === 'actions' && (type === 'condition' || type === 'ab_split' || type === 'wait' || type === 'end')) return false;
    if (activeTab.value === 'condition' && (type !== 'condition' && type !== 'ab_split' && type !== 'wait')) return false;

    // Filtering by search query
    if (blockSearch.value) {
        const query = blockSearch.value.toLowerCase();
        const text = defaultTitle(type).toLowerCase();
        return text.includes(query);
    }
    return true;
}

// Dropdown options config for CwSelect components
const triggerTypeOptions = [
    { value: 'new_user_signup', label: 'New User Sign Up' },
    { value: 'incoming_webhook', label: 'Incoming Webhook' },
    { value: 'contact_created', label: 'Contact Created' },
    { value: 'contact_updated', label: 'Contact Updated' },
    { value: 'subscribes_to_list', label: 'Contact Subscribes to List' },
    { value: 'unsubscribes_from_list', label: 'Contact Unsubscribes from List' },
    { value: 'tag_applied', label: 'Tag Applied' },
    { value: 'tag_removed', label: 'Tag Removed' },
    { value: 'email_opened', label: 'Email Opened' },
    { value: 'email_clicked', label: 'Email Clicked' },
    { value: 'unsubscribed', label: 'Contact Unsubscribed' },
    { value: 'birthday', label: 'Contact Birthday' }
];

const campaignSelectOptions = computed(() => {
    return props.campaigns.map(c => ({ value: c.id, label: c.title }));
});

const listOptions = computed(() => {
    return props.lists.map(l => ({ value: l.id, label: l.title }));
});

const tagOptions = computed(() => {
    return props.tags.map(t => ({ value: t.id, label: t.title }));
});

const conditionFieldOptions = computed(() => [
    { group: 'Contact Details' },
    { value: 'First Name', label: 'First Name' },
    { value: 'Last Name', label: 'Last Name' },
    { value: 'Email Address', label: 'Email Address' },
    { value: 'Phone Number', label: 'Phone Number' },
    { value: 'Birthday', label: 'Birthday' },
    { value: 'Company', label: 'Company ID' },
    { value: 'City', label: 'City' },
    { value: 'Country', label: 'Country' },
    { value: 'Lifetime Value', label: 'Lifetime Value (LTV)' },
    { value: 'Contact Type', label: 'Contact Type' },
    { group: 'How contacts were acquired' },
    { value: 'Date Added', label: 'Email Date Added' },
    { value: 'Signup Source', label: 'Signup source' },
    { group: 'Email & Automations Activity' },
    { value: 'Subscription Status', label: 'Email subscription status' },
    { value: 'List', label: 'List Membership' },
    { value: 'Tag', label: 'Tag Membership' },
    { value: 'Last Activity', label: 'Last Activity (Purchase/Send)' },
    { value: 'Last Purchase Date', label: 'Last Purchase Date (Relative)' }
]);

function getConditionOperatorOptions(field) {
    if (['Last Purchase Date', 'Last Activity', 'Birthday', 'Date Added'].includes(field)) {
        return [
            { value: 'is before', label: 'is before' },
            { value: 'is after', label: 'is after' },
            { value: 'equals', label: 'is on' }
        ];
    }
    if (field === 'List') {
        return [
            { value: 'equals', label: 'is in list' },
            { value: 'does not equal', label: 'is not in list' }
        ];
    }
    if (field === 'Tag') {
        return [
            { value: 'equals', label: 'has tag' },
            { value: 'does not equal', label: 'does not have tag' }
        ];
    }
    if (['First Name', 'Last Name', 'Email Address', 'Phone Number', 'Signup Source', 'City', 'Country'].includes(field)) {
        return [
            { value: 'equals', label: 'equals' },
            { value: 'does not equal', label: 'does not equal' },
            { value: 'contains', label: 'contains' },
            { value: 'does not contain', label: 'does not contain' },
            { value: 'starts with', label: 'starts with' },
            { value: 'ends with', label: 'ends with' }
        ];
    }
    return [
        { value: 'equals', label: 'equals' },
        { value: 'does not equal', label: 'does not equal' },
        { value: 'greater than', label: 'greater than' },
        { value: 'less than', label: 'less than' }
    ];
}

const contactTypeOptions = [
    { value: 'lead', label: 'Lead' },
    { value: 'customer', label: 'Customer' },
    { value: 'prospect', label: 'Prospect' },
    { value: 'partner', label: 'Partner' }
];

const subscriptionStatusOptions = [
    { value: 'subscribed', label: 'Subscribed' },
    { value: 'unsubscribed', label: 'Unsubscribed' },
    { value: 'bounced', label: 'Bounced' }
];

const relativeUnitOptions = [
    { value: 'days ago', label: 'days' },
    { value: 'hours ago', label: 'hours' }
];

const campaignImportOptions = computed(() => {
    const list = props.campaigns.map(c => ({ value: c.id, label: c.title }));
    return [{ value: null, label: '-- Select Campaign to Copy Content --' }, ...list];
});

const smtpConfigOptions = computed(() => {
    const list = props.smtpConfigs.map(s => ({ value: s.id, label: `${s.name} (${s.from_email})` }));
    return [{ value: null, label: 'System Default SMTP Profile' }, ...list];
});

const waitUnitOptions = [
    { value: 'days', label: 'Days' },
    { value: 'hours', label: 'Hours' },
    { value: 'minutes', label: 'Minutes' },
    { value: 'weeks', label: 'Weeks' }
];

const preferredSendTimeOptions = [
    { value: 'immediately', label: 'Send immediately after wait' },
    { value: 'specific', label: 'Send on specific time of day' }
];

const webhookMethodOptions = [
    { value: 'POST', label: 'POST' },
    { value: 'GET', label: 'GET' },
    { value: 'PUT', label: 'PUT' }
];

const webhookPayloadOptions = [
    { value: 'json', label: 'JSON (Full Contact Object)' },
    { value: 'form', label: 'Form Data' }
];

const abSplitOptions = [
    { value: 50, label: '50% Path A / 50% Path B' },
    { value: 80, label: '80% Path A / 20% Path B' }
];

const targetPropertyFieldOptions = [
    { value: 'contact_type', label: 'Lead Type (contact_type)' },
    { value: 'status', label: 'Subscription Status (status)' },
    { value: 'life_time_value', label: 'Lifetime Value (life_time_value)' }
];
</script>

<style scoped>
.af-panel.is-email-panel.is-visible {
    width: 450px;
    max-width: 90vw;
}

/* Email Builder Fullscreen Modal Styles */
.email-builder-modal-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    background: rgba(15, 23, 42, 0.6);
    backdrop-filter: blur(4px);
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}

.email-builder-modal-container {
    width: 100%;
    height: 100%;
    max-width: 1400px;
    background: #ffffff;
    border-radius: 12px;
    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.email-builder-modal-header {
    height: 70px;
    background: #f8fafc;
    border-bottom: 1px solid #e2e8f0;
    padding: 0 24px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-shrink: 0;
}

.email-builder-modal-header-left {
    display: flex;
    flex-direction: column;
}

.email-builder-modal-title {
    font-size: 16px;
    font-weight: 600;
    color: #0f172a;
    margin: 0;
}

.email-builder-modal-subtitle {
    font-size: 12px;
    color: #64748b;
    margin-top: 2px;
}

.email-builder-modal-done-btn {
    background: #16a34a;
    color: #ffffff;
    font-size: 14px;
    font-weight: 500;
    padding: 8px 18px;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    transition: background 0.15s ease-in-out;
}

.email-builder-modal-done-btn:hover {
    background: #15803d;
}

.email-builder-modal-body {
    flex: 1;
    overflow: hidden;
    position: relative;
    background: #f1f5f9;
}

/* Override date picker popover alignment to show below input, preventing top cutoff in the side panel */
:deep(.cw-dt-popover) {
    bottom: auto !important;
    top: calc(100% + 6px) !important;
    z-index: 9999 !important;
}

/* Allow date picker and select popovers to overflow the panel body without clipping */
.af-panel,
.af-panel-content,
.af-settings-card,
.af-condition-row {
    overflow: visible !important;
}

.af-panel-body {
    overflow-y: auto !important;
    overflow-x: hidden !important;
}

.af-panel.is-webhook-panel.is-visible {
    width: 460px;
    max-width: 90vw;
}

.af-segmented-control {
    display: flex;
    border: 1px solid #cbd5e1;
    border-radius: 6px;
    background: #f8fafc;
    padding: 3px;
    gap: 4px;
}

.af-segmented-btn {
    flex: 1;
    padding: 6px 12px;
    font-size: 12px;
    font-weight: 600;
    border: none;
    border-radius: 4px;
    background: transparent;
    cursor: pointer;
    color: #64748b;
    transition: all 0.15s ease;
    text-align: center;
}

.af-segmented-btn:hover {
    color: #0f172a;
    background: rgba(0, 0, 0, 0.03);
}

.af-segmented-btn.is-active {
    background: #ffffff;
    color: #0f172a;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06);
}

/* Custom HTTP Method active styles */
.af-segmented-btn.is-active.method-get {
    background: #dbeafe;
    color: #1e40af;
}
.af-segmented-btn.is-active.method-post {
    background: #d1fae5;
    color: #065f46;
}
.af-segmented-btn.is-active.method-put {
    background: #fef3c7;
    color: #92400e;
}

.payload-preview-container {
    background: #0f172a;
    border-radius: 6px;
    padding: 12px;
    overflow-x: auto;
    max-height: 180px;
    border: 1px solid #1e293b;
    margin-top: 6px;
    box-shadow: inset 0 2px 4px rgba(0,0,0,0.2);
}

.payload-preview-container pre {
    margin: 0;
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
    font-size: 11px;
    color: #38bdf8;
}

/* Pulsating green dot for live indicator */
.live-pulse-dot {
    width: 6px;
    height: 6px;
    background-color: #10b981;
    border-radius: 50%;
    display: inline-block;
    box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7);
    animation: pulse-green 1.5s infinite;
}

@keyframes pulse-green {
    0% {
        transform: scale(0.95);
        box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7);
    }
    70% {
        transform: scale(1);
        box-shadow: 0 0 0 4px rgba(16, 185, 129, 0);
    }
    100% {
        transform: scale(0.95);
        box-shadow: 0 0 0 0 rgba(16, 185, 129, 0);
    }
}

/* Zoom dropdown */
.af-zoom-dropdown {
    position: absolute;
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%);
    margin-bottom: 8px;
    background: var(--bg-surface, #fff);
    border: 1px solid var(--border-color, #e2e8f0);
    border-radius: 8px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
    padding: 4px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    z-index: 110;
    min-width: 70px;
}

.af-zoom-dropdown-item {
    width: 100%;
    padding: 6px 10px;
    font-size: 11px;
    font-weight: 600;
    color: var(--text-secondary, #64748b);
    border: none;
    background: transparent;
    border-radius: 5px;
    cursor: pointer;
    text-align: center;
    transition: all 0.1s ease;
}

.af-zoom-dropdown-item:hover {
    background: var(--bg-hover, #f1f5f9);
    color: var(--text-primary, #0f172a);
}

.af-zoom-dropdown-item.is-active {
    background: var(--bg-hover-strong, #e2e8f0);
    color: var(--info, #3b82f6);
}

/* Incoming Webhook Panel Styles */
.af-wh-card {
    background: var(--bg-surface, #ffffff);
    border: 1px solid var(--border-color, #e2e8f0);
    border-radius: 10px;
    padding: 16px;
    margin-bottom: 16px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
}

.af-wh-hdr {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
}

.af-wh-title {
    font-size: 13px;
    font-weight: 700;
    color: var(--text-primary, #0f172a);
    margin: 0;
}

.af-wh-link {
    font-size: 11px;
    color: var(--active-text, #2563eb);
    text-decoration: none;
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    transition: opacity 0.15s ease;
}

.af-wh-link:hover {
    opacity: 0.8;
}

.af-wh-box {
    background: var(--bg-hover, #f8fafc);
    border: 1px solid var(--border-color, #e2e8f0);
    border-radius: 8px;
    padding: 14px;
    margin-top: 12px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.af-wh-box-hdr {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
}

.af-wh-name-row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.af-wh-name {
    font-size: 14px;
    font-weight: 700;
    color: var(--text-primary, #0f172a);
}

.af-wh-logs {
    font-size: 11px;
    color: var(--text-muted, #64748b);
    margin-top: 2px;
}

.af-wh-secret-badge {
    font-size: 11px;
    color: var(--text-muted, #64748b);
    display: flex;
    align-items: center;
    gap: 4px;
}

.af-wh-url-wrap {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.af-wh-label {
    font-size: 11px;
    font-weight: 600;
    color: var(--text-secondary, #475569);
}

.af-wh-url-input-group {
    display: flex;
    gap: 6px;
}

.af-wh-url-input {
    background: var(--bg-surface, #ffffff);
    font-family: var(--font-mono, monospace);
    font-size: 11px;
    flex: 1;
}

.af-wh-copy-btn {
    padding: 0 12px;
    font-size: 11px;
    white-space: nowrap;
}

.af-wh-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px 12px;
    padding-top: 8px;
    border-top: 1px dashed var(--border-color, #e2e8f0);
}

.af-wh-grid-item {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.af-wh-grid-label {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted, #94a3b8);
}

.af-wh-grid-val {
    font-size: 12px;
    font-weight: 600;
    color: var(--text-primary, #0f172a);
    text-transform: capitalize;
}

.af-wh-chips-wrap {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding-top: 8px;
    border-top: 1px dashed var(--border-color, #e2e8f0);
}

.af-wh-chips-row {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}

.af-wh-footer-stats {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 11px;
    color: var(--text-muted, #64748b);
    padding-top: 8px;
    border-top: 1px solid var(--border-color, #e2e8f0);
}

.af-wh-stat-bold {
    color: var(--text-primary, #0f172a);
}

.af-wh-desc {
    font-size: 11px;
    color: var(--text-secondary, #475569);
    line-height: 1.4;
    margin: 0 0 10px 0;
}

.af-wh-vars-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.af-wh-var-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 6px 8px;
    background: var(--bg-hover, #f8fafc);
    border: 1px solid var(--border-color, #e2e8f0);
    border-radius: 6px;
}

.af-wh-var-info {
    display: flex;
    align-items: center;
    gap: 8px;
}

.af-wh-var-code {
    font-family: var(--font-mono, monospace);
    font-size: 11px;
    font-weight: 600;
    color: var(--active-text, #2563eb);
    background: rgba(37, 99, 235, 0.08);
    padding: 2px 6px;
    border-radius: 4px;
}

.af-wh-var-label {
    font-size: 11px;
    color: var(--text-muted, #64748b);
}

.af-wh-var-copy {
    padding: 2px 8px;
    font-size: 10px;
    height: auto;
}

.af-wh-filter-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px dashed var(--border-color, #e2e8f0);
}

.af-wh-multi-section {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding-top: 10px;
    border-top: 1px dashed var(--border-color, #e2e8f0);
}

.af-wh-section-hdr {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.af-wh-add-inline-btn {
    font-size: 11px;
    font-weight: 600;
    color: var(--active-text, #2563eb);
    background: transparent;
    border: none;
    cursor: pointer;
    padding: 0;
    transition: opacity 0.15s ease;
}

.af-wh-add-inline-btn:hover {
    opacity: 0.8;
}

.af-wh-inline-form {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px;
    background: var(--bg-surface, #ffffff);
    border: 1px solid var(--border-color, #e2e8f0);
    border-radius: 6px;
    margin-bottom: 4px;
}

.af-wh-inline-input {
    height: 28px;
    font-size: 11px;
    flex: 1;
}

.af-wh-color-picker {
    width: 28px;
    height: 28px;
    padding: 0;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    background: transparent;
}

.af-wh-select-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 10px;
    border-radius: 16px;
    font-size: 11px;
    font-weight: 600;
    border: 1px solid var(--border-color, #e2e8f0);
    cursor: pointer;
    user-select: none;
    transition: all 0.15s ease;
}

.af-wh-select-chip:hover {
    transform: translateY(-1px);
    box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}

.af-wh-chip-check {
    font-size: 10px;
    font-weight: 700;
}

.af-wh-empty-hint {
    font-size: 11px;
    color: var(--text-muted, #94a3b8);
    font-style: italic;
}

.af-wh-editor-box {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 10px;
    background: var(--bg-surface, #ffffff);
    border: 1px solid var(--border-color, #e2e8f0);
    border-radius: 8px;
    margin-top: 4px;
}

.af-wh-editor-sub {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.af-wh-select-row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.af-wh-active-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border-radius: 16px;
    font-size: 11px;
    font-weight: 600;
}

.af-wh-chip-remove {
    background: transparent;
    border: none;
    cursor: pointer;
    font-size: 14px;
    line-height: 1;
    color: currentColor;
    opacity: 0.7;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: opacity 0.15s ease;
}

.af-wh-chip-remove:hover {
    opacity: 1;
}
</style>
