<x-filament-panels::page>
    <link rel="stylesheet" href="{{ asset('vendor/drawflow/drawflow.min.css') }}">
    <script src="{{ asset('vendor/drawflow/drawflow.min.js') }}"></script>

    <div class="guide-flow-page space-y-4">
        {{-- Header actions --}}
        <div class="flex gap-2">
            {{ $this->createPageAction }}
        </div>

        {{-- Drawflow canvas --}}
        <div class="guide-flow-canvas fi-section rounded-xl bg-white shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10 overflow-hidden">
            <div id="drawflow" wire:ignore></div>
        </div>
    </div>

    <x-filament-actions::modals />

    <style>
        .guide-flow-page { width: 100%; }
        .guide-flow-canvas { width: 100%; }

        #drawflow {
            width: 100%;
            height: max(680px, calc(100vh - 14rem));
            background-color: #f8fafc;
            background-image: radial-gradient(circle, #e2e8f0 1px, transparent 1px);
            background-size: 20px 20px;
        }

        @media (max-width: 1024px) { #drawflow { height: max(560px, calc(100vh - 16rem)); } }
        @media (max-width: 640px)  { #drawflow { height: max(480px, 70vh); } }

        /* ── Node ── */
        .drawflow .drawflow-node {
            border-radius: 8px;
            border: 1px solid #e5e7eb;
            background: white;
            min-width: 160px;
            max-width: 180px;
            padding: 0;
            box-shadow: 0 1px 3px rgba(0,0,0,.06);
        }
        .drawflow .drawflow-node.selected {
            border-color: #f59e0b;
            box-shadow: 0 0 0 2px rgba(245,158,11,.3);
        }
        .drawflow .drawflow-node.entry-node {
            border: 2px solid #f59e0b;
        }
        .drawflow .drawflow-node .drawflow_content_node { padding: 0; }

        /* ── Node content ── */
        .df-node-content { padding: 8px 10px; }

        .df-node-header {
            font-weight: 600;
            font-size: 12px;
            color: #1f2937;
            line-height: 1.3;
            word-break: break-all;
        }

        .df-node-badge {
            display: inline-block;
            font-size: 9px;
            background: #fef3c7;
            color: #b45309;
            padding: 1px 5px;
            border-radius: 3px;
            margin-top: 3px;
            font-weight: 500;
        }

        .df-node-actions {
            margin-top: 5px;
            display: flex;
            gap: 6px;
            border-top: 1px solid #f3f4f6;
            padding-top: 5px;
        }
        .df-node-actions button,
        .df-node-actions a {
            font-size: 10px;
            color: #6b7280;
            cursor: pointer;
            background: none;
            border: none;
            padding: 1px 0;
            text-decoration: none;
            transition: color .15s;
        }
        .df-node-actions button:hover, .df-node-actions a:hover { color: #3b82f6; }
        .df-node-actions button.btn-danger:hover { color: #ef4444; }

        /* ── Connections ── */
        .drawflow .connection .main-path {
            stroke: #64748b;
            stroke-width: 2px;
            fill: none;
            marker-end: url(#arrowhead);
        }
        .drawflow .connection .main-path:hover {
            stroke: #ef4444;
            stroke-width: 2.5px;
            cursor: pointer;
        }

        /* Edge label */
        .drawflow .connection .connection-label {
            font-size: 10px;
            fill: #1e40af;
            font-weight: 500;
            pointer-events: none;
        }
        .drawflow .connection .connection-label-bg {
            fill: #dbeafe;
            rx: 3;
            pointer-events: none;
        }

        /* ── Ports ── */
        .drawflow .drawflow-node .inputs {
            position: absolute;
            left: -6px; top: 0; bottom: 0;
            width: auto !important; height: auto !important;
            display: flex; flex-direction: column; justify-content: center;
        }
        .drawflow .drawflow-node .outputs {
            position: absolute;
            right: -6px; top: 0; bottom: 0;
            width: auto !important; height: auto !important;
            display: flex; flex-direction: column;
            justify-content: space-evenly;
            gap: 16px; padding: 16px 0;
        }
        .drawflow .drawflow-node .input  { left: 0 !important; top: 0 !important; margin: 0; }
        .drawflow .drawflow-node .output { right: 0 !important; top: 0 !important; margin: 0; }

        .drawflow .drawflow-node .input,
        .drawflow .drawflow-node .output {
            width: 11px; height: 11px;
            border: 2px solid #94a3b8;
            background: white;
            position: relative;
        }
        .drawflow .drawflow-node .input:hover,
        .drawflow .drawflow-node .output:hover {
            background: #3b82f6; border-color: #3b82f6;
        }

        /* Output port option label */
        .drawflow .drawflow-node .output[data-label]::after {
            content: attr(data-label);
            position: absolute;
            left: 13px; top: 50%;
            transform: translateY(-50%);
            font-size: 9px;
            white-space: nowrap;
            color: #1e40af;
            background: #dbeafe;
            padding: 0 4px;
            border-radius: 3px;
            font-weight: 500;
            pointer-events: none;
            line-height: 1.6;
        }

        /* ── Dark mode ── */
        .dark #drawflow {
            background-color: #111827;
            background-image: radial-gradient(circle, #1f2937 1px, transparent 1px);
        }
        .dark .drawflow .drawflow-node { background: #1f2937; border-color: #374151; }
        .dark .df-node-header { color: #e5e7eb; }
        .dark .df-node-actions { border-top-color: #374151; }
        .dark .drawflow .connection .main-path { stroke: #6b7280; }
        .dark .drawflow .drawflow-node .input,
        .dark .drawflow .drawflow-node .output { border-color: #6b7280; background: #1f2937; }
        .dark .drawflow .drawflow-node .output[data-label]::after { color: #93c5fd; background: #1e3a5f; }
    </style>

    <script>
    (function () {
        const componentId = @js($this->getId());

        function escHtml(str) {
            return String(str)
                .replace(/&/g,'&amp;').replace(/</g,'&lt;')
                .replace(/>/g,'&gt;').replace(/"/g,'&quot;');
        }

        function ensureArrowMarker() {
            if (document.getElementById('df-arrow-defs')) return;
            const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
            svg.setAttribute('id', 'df-arrow-defs');
            svg.style.cssText = 'position:absolute;width:0;height:0;overflow:hidden';
            svg.innerHTML = `<defs>
                <marker id="arrowhead" markerWidth="8" markerHeight="6"
                        refX="7" refY="3" orient="auto" markerUnits="strokeWidth">
                    <polygon points="0 0, 8 3, 0 6" fill="#64748b"/>
                </marker></defs>`;
            document.body.appendChild(svg);
        }

        // ── Build / rebuild the Drawflow graph ───────────────────────────────
        function buildGraph(nodes, edges) {
            const container = document.getElementById('drawflow');
            if (!container) return;

            // 销毁旧实例
            if (window._dfEditor) {
                try { window._dfEditor.clear(); } catch(e) {}
                window._dfEditor = null;
            }
            container.innerHTML = '';

            ensureArrowMarker();

            const editor = new Drawflow(container);
            editor.reroute = false;
            editor.curvature = 0.5;
            editor.start();

            // 水平贝塞尔曲线
            editor.createCurvature = function(sx, sy, ex, ey, curvature) {
                const ox = Math.max(Math.abs(ex - sx) * curvature, 30);
                return `M ${sx} ${sy} C ${sx+ox} ${sy} ${ex-ox} ${ey} ${ex} ${ey}`;
            };

            window._dfEditor = editor;

            const pageIdToNodeId = {};

            // 添加节点
            nodes.forEach(node => {
                const numOutputs = (node.options && node.options.length > 0) ? node.options.length : 1;
                const html = `<div class="df-node-content">
                    <div class="df-node-header">${escHtml(node.title)}</div>
                    ${node.is_entry ? '<div><span class="df-node-badge">入口</span></div>' : ''}
                    <div class="df-node-actions">
                        <button onclick="event.stopPropagation();Livewire.find('${componentId}').mountAction('editPage',{id:${node.id}})">编辑</button>
                        <button class="btn-danger" onclick="event.stopPropagation();Livewire.find('${componentId}').mountAction('deletePage',{id:${node.id}})">删除</button>
                        <a href="${escHtml(node.uri)}" target="_blank" rel="noopener" onclick="event.stopPropagation()">预览</a>
                    </div></div>`;

                const nodeId = editor.addNode(
                    'page', 1, numOutputs,
                    node.x, node.y,
                    node.is_entry ? 'entry-node' : '',
                    { pageId: node.id, options: node.options || [] },
                    html
                );
                pageIdToNodeId[node.id] = nodeId;

                // 给输出端口加选项标签
                if (node.options && node.options.length > 0) {
                    requestAnimationFrame(() => {
                        const nodeEl = container.querySelector(`#node-${nodeId}`);
                        if (!nodeEl) return;
                        nodeEl.querySelectorAll('.output').forEach((el, i) => {
                            if (node.options[i]) {
                                el.setAttribute('data-label', node.options[i]);
                                el.title = node.options[i];
                            }
                        });
                    });
                }
            });

            // 添加连线
            edges.forEach(edge => {
                const fromNodeId = pageIdToNodeId[edge.from];
                const toNodeId   = pageIdToNodeId[edge.to];
                if (!fromNodeId || !toNodeId) return;

                const fromNode = nodes.find(n => n.id === edge.from);
                let outputClass = 'output_1';
                if (fromNode && fromNode.options && fromNode.options.length > 0 && edge.label) {
                    const idx = fromNode.options.indexOf(edge.label);
                    if (idx >= 0) outputClass = `output_${idx + 1}`;
                }
                try { editor.addConnection(fromNodeId, toNodeId, outputClass, 'input_1'); } catch(e) {}
            });

            // Drawflow 事件 → Livewire（只在本次 editor 实例上绑定）
            editor.on('connectionCreated', info => {
                const from = editor.getNodeFromId(info.output_id);
                const to   = editor.getNodeFromId(info.input_id);
                if (from && to) {
                    Livewire.find(componentId).call('addEdge', from.data.pageId, to.data.pageId, info.output_class);
                }
            });

            editor.on('connectionRemoved', info => {
                const from = editor.getNodeFromId(info.output_id);
                const to   = editor.getNodeFromId(info.input_id);
                if (from && to) {
                    Livewire.find(componentId).call('removeEdge', from.data.pageId, to.data.pageId);
                }
            });
        }

        // ── Livewire 事件监听（只注册一次，在外层）────────────────────────────
        function registerLivewireListener() {
            Livewire.on('graphUpdated', (payload) => {
                // Livewire 3 dispatch 带命名参数时，payload 是 { nodes: [...], edges: [...] }
                // 也兼容数组包裹的格式
                let data = payload;
                if (Array.isArray(payload)) data = payload[0] ?? {};
                const nodes = data.nodes ?? null;
                const edges = data.edges ?? null;
                if (nodes !== null && edges !== null) {
                    buildGraph(nodes, edges);
                }
            });
        }

        // ── 初始化 ────────────────────────────────────────────────────────────
        function init() {
            buildGraph(
                @js($this->nodes),
                @js($this->edges)
            );
        }

        document.addEventListener('DOMContentLoaded', () => {
            setTimeout(() => {
                registerLivewireListener();
                init();
            }, 50);
        });
        document.addEventListener('livewire:navigated', () => {
            setTimeout(init, 50);
        });
    })();
    </script>
</x-filament-panels::page>
