import { Component, Input, ViewChild, ChangeDetectionStrategy } from '@angular/core';
import { Subject, combineLatest } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { UUIDsEqual } from '@memberjunction/global';
import * as i0 from "@angular/core";
import * as i1 from "angular-split";
import * as i2 from "./ai-agent-run-step-detail.component";
const _c0 = ["svgContainer"];
function AIAgentRunVisualizationComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 2);
    i0.ɵɵelement(1, "i", 4);
    i0.ɵɵelementStart(2, "span");
    i0.ɵɵtext(3);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const ctx_r0 = i0.ɵɵnextContext();
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate(ctx_r0.error);
} }
function AIAgentRunVisualizationComponent_Conditional_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 18);
    i0.ɵɵelement(1, "i", 20);
    i0.ɵɵelementStart(2, "span");
    i0.ɵɵtext(3, "Loading visualization...");
    i0.ɵɵelementEnd()();
} }
function AIAgentRunVisualizationComponent_Conditional_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
    const _r3 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "as-split-area", 19)(1, "mj-ai-agent-run-step-detail", 21);
    i0.ɵɵlistener("closePanel", function AIAgentRunVisualizationComponent_Conditional_2_Conditional_18_Template_mj_ai_agent_run_step_detail_closePanel_1_listener() { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.closeDetailPane()); })("navigateToActionLog", function AIAgentRunVisualizationComponent_Conditional_2_Conditional_18_Template_mj_ai_agent_run_step_detail_navigateToActionLog_1_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.navigateToActionLog($event)); })("copyToClipboard", function AIAgentRunVisualizationComponent_Conditional_2_Conditional_18_Template_mj_ai_agent_run_step_detail_copyToClipboard_1_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.copyToClipboard($event)); });
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const ctx_r0 = i0.ɵɵnextContext(2);
    i0.ɵɵproperty("size", 30)("minSize", 20)("maxSize", 50);
    i0.ɵɵadvance();
    i0.ɵɵproperty("selectedTimelineItem", ctx_r0.selectedItem);
} }
function AIAgentRunVisualizationComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
    const _r2 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "as-split", 3)(1, "as-split-area", 5)(2, "div", 6, 0)(4, "div", 7)(5, "div", 8);
    i0.ɵɵelement(6, "i", 9);
    i0.ɵɵtext(7, " Agent Execution Flow ");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(8, "div", 10)(9, "button", 11);
    i0.ɵɵlistener("click", function AIAgentRunVisualizationComponent_Conditional_2_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.zoomIn()); });
    i0.ɵɵelement(10, "i", 12);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(11, "button", 13);
    i0.ɵɵlistener("click", function AIAgentRunVisualizationComponent_Conditional_2_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.zoomOut()); });
    i0.ɵɵelement(12, "i", 14);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(13, "button", 15);
    i0.ɵɵlistener("click", function AIAgentRunVisualizationComponent_Conditional_2_Template_button_click_13_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.resetZoom()); });
    i0.ɵɵelement(14, "i", 16);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(15, "span", 17);
    i0.ɵɵtext(16);
    i0.ɵɵelementEnd()()();
    i0.ɵɵconditionalCreate(17, AIAgentRunVisualizationComponent_Conditional_2_Conditional_17_Template, 4, 0, "div", 18);
    i0.ɵɵelementEnd()();
    i0.ɵɵconditionalCreate(18, AIAgentRunVisualizationComponent_Conditional_2_Conditional_18_Template, 2, 4, "as-split-area", 19);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r0 = i0.ɵɵnextContext();
    i0.ɵɵadvance();
    i0.ɵɵproperty("size", ctx_r0.selectedItem ? 70 : 100);
    i0.ɵɵadvance(15);
    i0.ɵɵtextInterpolate1("", (ctx_r0.panZoom.scale * 100).toFixed(0), "%");
    i0.ɵɵadvance();
    i0.ɵɵconditional(ctx_r0.loading ? 17 : -1);
    i0.ɵɵadvance();
    i0.ɵɵconditional(ctx_r0.selectedItem ? 18 : -1);
} }
export class AIAgentRunVisualizationComponent {
    /** Remove timeout from tracking array */
    removeTimeoutFromTracking(timeoutId) {
        const index = this.activeTimeouts.indexOf(timeoutId);
        if (index > -1) {
            this.activeTimeouts.splice(index, 1);
        }
    }
    constructor(cdr) {
        this.cdr = cdr;
        this.destroy$ = new Subject();
        this.viewInitialized = false;
        /** Track active timeouts for cleanup */
        this.activeTimeouts = [];
        this.pendingData = null;
        this.loading = false; // Start with false so the container renders
        this.error = null;
        this.dataLoading = false; // Track data loading state from service
        this.selectedItem = null;
        // Node management
        this.nodes = new Map();
        this.scopes = new Map();
        this.connections = [];
        // Pan and zoom state
        this.panZoom = {
            scale: 1,
            translateX: 0,
            translateY: 0,
            isPanning: false,
            startX: 0,
            startY: 0
        };
        // Drag state
        this.dragState = {
            isDragging: false,
            element: null,
            nodeId: null,
            startX: 0,
            startY: 0,
            startTransform: { x: 0, y: 0 }
        };
        // Pan state
        this.panState = {
            isPanning: false,
            startX: 0,
            startY: 0,
            initialTranslateX: 0,
            initialTranslateY: 0
        };
        // Animation frame ID for cleanup
        this.animationFrameId = null;
        // Bound event handlers for proper cleanup
        this.boundOnWheel = this.onWheel.bind(this);
        this.boundOnSvgMouseDown = this.onSvgMouseDown.bind(this);
        this.boundOnSvgMouseMove = this.onSvgMouseMove.bind(this);
        this.boundOnSvgMouseUp = this.onSvgMouseUp.bind(this);
        this.onMouseMove = (event) => {
            if (!this.dragState.isDragging || !this.dragState.element)
                return;
            const svg = this.dragState.element.ownerSVGElement;
            if (!svg)
                return;
            const pt = svg.createSVGPoint();
            pt.x = event.clientX;
            pt.y = event.clientY;
            const svgP = pt.matrixTransform(svg.getScreenCTM()?.inverse());
            const dx = svgP.x - this.dragState.startX;
            const dy = svgP.y - this.dragState.startY;
            const newX = this.dragState.startTransform.x + dx;
            const newY = this.dragState.startTransform.y + dy;
            // Update element position
            this.dragState.element.setAttribute('transform', `translate(${newX}, ${newY})`);
            // Update node data
            const node = this.nodes.get(this.dragState.nodeId);
            if (node) {
                node.x = newX;
                node.y = newY;
            }
            // Update connections
            this.drawConnections();
        };
        this.onMouseUp = (event) => {
            if (!this.dragState.isDragging || !this.dragState.element)
                return;
            this.dragState.element.classList.remove('dragging');
            // Clean up
            this.dragState = {
                isDragging: false,
                element: null,
                nodeId: null,
                startX: 0,
                startY: 0,
                startTransform: { x: 0, y: 0 }
            };
            document.removeEventListener('mousemove', this.onMouseMove);
            document.removeEventListener('mouseup', this.onMouseUp);
        };
    }
    ngOnInit() {
        if (this.aiAgentRunId) {
            // Subscribe to data from helper
            combineLatest([
                this.dataHelper.steps$,
                this.dataHelper.subRuns$,
                this.dataHelper.actionLogs$,
                this.dataHelper.promptRuns$,
                this.dataHelper.loading$
            ]).pipe(takeUntil(this.destroy$)).subscribe(([steps, subRuns, actionLogs, promptRuns, loading]) => {
                this.dataLoading = loading;
                if (!loading && steps && steps.length > 0) {
                    console.log('Visualization: Received data from service', {
                        steps: steps.length,
                        subRuns: subRuns.length,
                        viewInitialized: this.viewInitialized
                    });
                    if (this.viewInitialized && this.svgContainer?.nativeElement) {
                        // View is ready, build immediately
                        this.buildVisualization(steps, subRuns, actionLogs, promptRuns);
                    }
                    else {
                        // Store data for when view is ready
                        console.log('View not ready, storing data for later');
                        this.pendingData = { steps, subRuns, actionLogs, promptRuns };
                    }
                }
                else if (!loading && (!steps || steps.length === 0)) {
                    console.log('Visualization: No steps available');
                    this.error = null;
                }
            });
            // Subscribe to error state
            this.dataHelper.error$.pipe(takeUntil(this.destroy$)).subscribe((error) => {
                if (error) {
                    this.error = error;
                    this.loading = false;
                }
            });
        }
        else {
            console.error('Visualization: No agent run ID provided');
            this.error = 'No agent run ID provided';
        }
    }
    ngAfterViewInit() {
        console.log('Visualization ngAfterViewInit');
        this.viewInitialized = true;
        // Initialize SVG
        if (this.svgContainer && this.svgContainer.nativeElement) {
            this.initializeSVG();
            // If we have pending data, process it now
            if (this.pendingData) {
                console.log('Processing pending data after view init');
                this.buildVisualization(this.pendingData.steps, this.pendingData.subRuns, this.pendingData.actionLogs, this.pendingData.promptRuns);
                this.pendingData = null;
            }
            this.cdr.detectChanges();
        }
        else {
            console.error('SVG container not found in ngAfterViewInit');
        }
    }
    ngOnDestroy() {
        // Signal all subscriptions to complete
        this.destroy$.next();
        this.destroy$.complete();
        // Clear all active timeouts
        this.activeTimeouts.forEach(timeoutId => {
            clearTimeout(timeoutId);
        });
        this.activeTimeouts.length = 0;
        // Clean up document-level event listeners
        document.removeEventListener('mousemove', this.onMouseMove);
        document.removeEventListener('mouseup', this.onMouseUp);
        // Clean up SVG and all its event listeners
        if (this.svgContainer?.nativeElement) {
            const svg = this.svgContainer.nativeElement.querySelector('svg');
            if (svg) {
                // Remove all SVG event listeners with bound handlers
                svg.removeEventListener('wheel', this.boundOnWheel);
                svg.removeEventListener('mousedown', this.boundOnSvgMouseDown);
                svg.removeEventListener('mousemove', this.boundOnSvgMouseMove);
                svg.removeEventListener('mouseup', this.boundOnSvgMouseUp);
                // Remove all node and scope event listeners
                // We can't remove specific listeners if we don't have references to them
                // The best approach is to clone and replace the elements, which removes all listeners
                svg.querySelectorAll('g[id^="node-"], g[id^="scope-"]').forEach(element => {
                    const clone = element.cloneNode(true);
                    element.parentNode?.replaceChild(clone, element);
                });
                // Remove expand button listeners
                svg.querySelectorAll('.expand-button').forEach(button => {
                    const clone = button.cloneNode(true);
                    button.parentNode?.replaceChild(clone, button);
                });
                // Clear all SVG content
                while (svg.firstChild) {
                    svg.removeChild(svg.firstChild);
                }
            }
        }
        // Clear data structures
        this.nodes.clear();
        this.scopes.clear();
        this.connections = [];
        // Clear any pending animation frames
        if (this.animationFrameId) {
            cancelAnimationFrame(this.animationFrameId);
            this.animationFrameId = null;
        }
        // Reset state
        this.dragState = {
            isDragging: false,
            element: null,
            nodeId: null,
            startX: 0,
            startY: 0,
            startTransform: { x: 0, y: 0 }
        };
        this.panState = {
            isPanning: false,
            startX: 0,
            startY: 0,
            initialTranslateX: 0,
            initialTranslateY: 0
        };
    }
    initializeSVG() {
        const container = this.svgContainer?.nativeElement;
        if (!container) {
            console.error('SVG container element not found');
            return;
        }
        // Create SVG element if it doesn't exist
        let svg = container.querySelector('svg');
        if (!svg) {
            svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
            svg.setAttribute('class', 'visualization-svg');
            svg.setAttribute('width', '100%');
            svg.setAttribute('height', '100%');
            // Add event listeners with bound handlers
            svg.addEventListener('wheel', this.boundOnWheel);
            svg.addEventListener('mousedown', this.boundOnSvgMouseDown);
            svg.addEventListener('mousemove', this.boundOnSvgMouseMove);
            svg.addEventListener('mouseup', this.boundOnSvgMouseUp);
            container.appendChild(svg);
        }
        // Add arrow marker definition
        const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
        const marker = document.createElementNS('http://www.w3.org/2000/svg', 'marker');
        marker.setAttribute('id', 'arrowhead-viz');
        marker.setAttribute('markerWidth', '10');
        marker.setAttribute('markerHeight', '7');
        marker.setAttribute('refX', '9');
        marker.setAttribute('refY', '3.5');
        marker.setAttribute('orient', 'auto');
        const polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
        polygon.setAttribute('points', '0 0, 10 3.5, 0 7');
        polygon.setAttribute('class', 'arrowhead-polygon');
        marker.appendChild(polygon);
        defs.appendChild(marker);
        svg.appendChild(defs);
        console.log('SVG initialized successfully');
    }
    async buildVisualization(steps, subRuns, actionLogs, promptRuns) {
        console.log('buildVisualization called', {
            steps: steps?.length || 0,
            hasContainer: !!this.svgContainer,
            containerElement: this.svgContainer?.nativeElement
        });
        if (!this.svgContainer || !this.svgContainer.nativeElement) {
            console.error('SVG container not available');
            this.loading = false;
            this.error = 'Visualization container not ready';
            return;
        }
        // If no steps, show empty state
        if (!steps || steps.length === 0) {
            console.log('No steps to visualize');
            this.loading = false;
            this.error = null;
            return;
        }
        this.loading = true;
        this.error = null;
        try {
            // Wait a tick for the view to be fully ready
            await new Promise(resolve => {
                const timeoutId = setTimeout(() => {
                    this.removeTimeoutFromTracking(timeoutId);
                    resolve(undefined);
                }, 0);
                this.activeTimeouts.push(timeoutId);
            });
            // Clear existing elements
            this.clearVisualization();
            // Build nodes and scopes
            await this.buildNodesAndScopes(steps, subRuns, promptRuns);
            // Arrange layout
            this.arrangeLayout();
            // Draw connections
            this.drawConnections();
            // Fit to view
            this.fitToView();
            this.loading = false;
            console.log('Visualization built successfully');
            // Trigger change detection since we're using OnPush
            this.cdr.markForCheck();
        }
        catch (error) {
            this.error = 'Failed to build visualization';
            console.error('Visualization error:', error);
            this.loading = false;
            // Trigger change detection since we're using OnPush
            this.cdr.markForCheck();
        }
    }
    clearVisualization() {
        const svg = this.svgContainer?.nativeElement?.querySelector('svg');
        if (!svg)
            return;
        const mainGroup = svg.querySelector('.main-group');
        if (mainGroup) {
            // Remove all child elements except defs
            while (mainGroup.firstChild) {
                mainGroup.removeChild(mainGroup.firstChild);
            }
        }
        this.nodes.clear();
        this.scopes.clear();
        this.connections = [];
    }
    async buildNodesAndScopes(steps, subRuns, promptRuns) {
        const svg = this.svgContainer?.nativeElement?.querySelector('svg');
        if (!svg)
            return;
        let mainGroup = svg.querySelector('.main-group');
        if (!mainGroup) {
            mainGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');
            mainGroup.setAttribute('class', 'main-group');
            svg.appendChild(mainGroup);
        }
        // Create nodes for each step
        for (let i = 0; i < steps.length; i++) {
            const step = steps[i];
            if (step.StepType === 'Sub-Agent' && step.TargetLogID) {
                // Create a scope for sub-agent
                const subRun = subRuns.find(sr => UUIDsEqual(sr.ID, step.TargetLogID));
                const scopeElement = await this.createScopeElement(step, subRun);
                mainGroup.appendChild(scopeElement);
                const scope = {
                    id: step.ID,
                    name: subRun?.Agent || 'Sub-Agent',
                    x: 0,
                    y: 0,
                    width: 300,
                    height: 200,
                    expanded: false,
                    nodes: [],
                    element: scopeElement
                };
                this.scopes.set(step.ID, scope);
            }
            else {
                // Create regular node
                const nodeElement = this.createNodeElement(step, promptRuns);
                mainGroup.appendChild(nodeElement);
                const nodeData = {
                    step: step,
                    x: 0,
                    y: 0,
                    width: 180,
                    height: 80,
                    element: nodeElement
                };
                this.nodes.set(step.ID, nodeData);
            }
            // Add connection info
            if (i > 0) {
                this.connections.push({
                    from: steps[i - 1].ID,
                    to: step.ID
                });
            }
        }
    }
    createNodeElement(step, promptRuns) {
        const g = document.createElementNS('http://www.w3.org/2000/svg', 'g');
        g.setAttribute('class', 'step-node');
        g.setAttribute('data-step-id', step.ID);
        g.setAttribute('data-type', this.getStepDataType(step.StepType));
        // Add event handlers
        g.addEventListener('click', (e) => this.onNodeClick(e, step));
        g.addEventListener('mousedown', (e) => this.onNodeMouseDown(e, step.ID));
        g.style.cursor = 'pointer';
        const nodeWidth = 180;
        const nodeHeight = 80;
        // Background rectangle
        const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
        rect.setAttribute('width', nodeWidth.toString());
        rect.setAttribute('height', nodeHeight.toString());
        rect.setAttribute('rx', '8');
        rect.setAttribute('class', 'node-bg');
        rect.setAttribute('stroke', this.getStepColor(step));
        rect.setAttribute('stroke-width', '2');
        g.appendChild(rect);
        // Status indicator
        const statusCircle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
        statusCircle.setAttribute('cx', '12');
        statusCircle.setAttribute('cy', '12');
        statusCircle.setAttribute('r', '6');
        statusCircle.setAttribute('fill', this.getStatusColor(step.Status));
        g.appendChild(statusCircle);
        // Icon
        const icon = document.createElementNS('http://www.w3.org/2000/svg', 'text');
        icon.setAttribute('x', '35');
        icon.setAttribute('y', '20');
        icon.setAttribute('font-size', '18');
        icon.setAttribute('fill', this.getStepColor(step));
        icon.textContent = this.getStepEmoji(step.StepType);
        g.appendChild(icon);
        // Title
        const title = document.createElementNS('http://www.w3.org/2000/svg', 'text');
        title.setAttribute('x', '60');
        title.setAttribute('y', '20');
        title.setAttribute('font-size', '14');
        title.setAttribute('font-weight', '600');
        title.setAttribute('class', 'node-title');
        title.textContent = this.truncateText(step.StepName || `Step ${step.StepNumber}`, 15);
        g.appendChild(title);
        // Step type
        const type = document.createElementNS('http://www.w3.org/2000/svg', 'text');
        type.setAttribute('x', '12');
        type.setAttribute('y', '40');
        type.setAttribute('font-size', '12');
        type.setAttribute('class', 'node-subtitle');
        type.textContent = step.StepType;
        g.appendChild(type);
        // Model info for prompts
        if (step.StepType === 'Prompt' && step.TargetLogID && promptRuns) {
            const promptRun = promptRuns.find(pr => UUIDsEqual(pr.ID, step.TargetLogID));
            if (promptRun) {
                const model = document.createElementNS('http://www.w3.org/2000/svg', 'text');
                model.setAttribute('x', '12');
                model.setAttribute('y', '55');
                model.setAttribute('font-size', '11');
                model.setAttribute('class', 'node-meta');
                model.textContent = `${promptRun.Model || 'Unknown'}`;
                g.appendChild(model);
            }
        }
        // Duration
        if (step.CompletedAt) {
            const duration = this.calculateDuration(step.StartedAt, step.CompletedAt);
            const durationText = document.createElementNS('http://www.w3.org/2000/svg', 'text');
            durationText.setAttribute('x', '12');
            durationText.setAttribute('y', '70');
            durationText.setAttribute('font-size', '11');
            durationText.setAttribute('class', 'node-meta');
            durationText.textContent = `⏱️ ${duration}`;
            g.appendChild(durationText);
        }
        return g;
    }
    async createScopeElement(step, subRun) {
        const g = document.createElementNS('http://www.w3.org/2000/svg', 'g');
        g.setAttribute('class', 'scope-container');
        g.setAttribute('data-scope-id', step.ID);
        const scopeWidth = 300;
        const scopeHeight = 200;
        const headerHeight = 40;
        // Background
        const bg = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
        bg.setAttribute('width', scopeWidth.toString());
        bg.setAttribute('height', scopeHeight.toString());
        bg.setAttribute('rx', '12');
        bg.setAttribute('class', 'scope-bg');
        bg.setAttribute('stroke-width', '2');
        bg.setAttribute('stroke-dasharray', '5,5');
        g.appendChild(bg);
        // Header background
        const headerBg = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
        headerBg.setAttribute('width', scopeWidth.toString());
        headerBg.setAttribute('height', headerHeight.toString());
        headerBg.setAttribute('rx', '12');
        headerBg.setAttribute('class', 'scope-header');
        g.appendChild(headerBg);
        // Fix bottom corners
        const headerFix = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
        headerFix.setAttribute('y', (headerHeight - 12).toString());
        headerFix.setAttribute('width', scopeWidth.toString());
        headerFix.setAttribute('height', '12');
        headerFix.setAttribute('class', 'scope-header');
        g.appendChild(headerFix);
        // Robot icon
        const icon = document.createElementNS('http://www.w3.org/2000/svg', 'text');
        icon.setAttribute('x', '12');
        icon.setAttribute('y', '26');
        icon.setAttribute('font-size', '20');
        icon.textContent = '🤖';
        g.appendChild(icon);
        // Title
        const title = document.createElementNS('http://www.w3.org/2000/svg', 'text');
        title.setAttribute('x', '40');
        title.setAttribute('y', '26');
        title.setAttribute('font-size', '14');
        title.setAttribute('font-weight', '600');
        title.setAttribute('class', 'scope-title');
        title.textContent = subRun?.Agent || 'Sub-Agent';
        g.appendChild(title);
        // Expand/collapse button
        const expandBtn = document.createElementNS('http://www.w3.org/2000/svg', 'g');
        expandBtn.setAttribute('class', 'expand-button');
        expandBtn.style.cursor = 'pointer';
        expandBtn.setAttribute('transform', `translate(${scopeWidth - 30}, 10)`);
        const expandBg = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
        expandBg.setAttribute('cx', '10');
        expandBg.setAttribute('cy', '10');
        expandBg.setAttribute('r', '10');
        expandBg.setAttribute('class', 'expand-bg');
        expandBtn.appendChild(expandBg);
        const expandIcon = document.createElementNS('http://www.w3.org/2000/svg', 'text');
        expandIcon.setAttribute('x', '10');
        expandIcon.setAttribute('y', '15');
        expandIcon.setAttribute('text-anchor', 'middle');
        expandIcon.setAttribute('font-size', '12');
        expandIcon.setAttribute('class', 'expand-icon');
        expandIcon.textContent = '+';
        expandBtn.appendChild(expandIcon);
        expandBtn.addEventListener('click', (e) => this.onScopeExpandClick(e, step.ID));
        g.appendChild(expandBtn);
        // Click handler for scope
        g.addEventListener('click', (e) => {
            if (!e.target.closest('.expand-button')) {
                this.onNodeClick(e, step);
            }
        });
        return g;
    }
    arrangeLayout() {
        const nodeSpacingX = 250;
        const nodeSpacingY = 120;
        const startX = 50;
        const startY = 50;
        let currentY = startY;
        let index = 0;
        // Arrange nodes and scopes sequentially
        const allItems = [...this.nodes.values(), ...Array.from(this.scopes.values()).map(s => ({
                step: { ID: s.id },
                x: 0,
                y: 0,
                width: s.width,
                height: s.height
            }))];
        // Sort by step number if available
        allItems.sort((a, b) => {
            const aStep = a.step;
            const bStep = b.step;
            return (aStep.StepNumber || 0) - (bStep.StepNumber || 0);
        });
        for (const item of allItems) {
            const nodeData = this.nodes.get(item.step.ID);
            const scopeData = this.scopes.get(item.step.ID);
            if (nodeData) {
                nodeData.x = startX;
                nodeData.y = currentY;
                if (nodeData.element) {
                    nodeData.element.setAttribute('transform', `translate(${nodeData.x}, ${nodeData.y})`);
                }
                currentY += nodeSpacingY;
            }
            else if (scopeData) {
                scopeData.x = startX;
                scopeData.y = currentY;
                if (scopeData.element) {
                    scopeData.element.setAttribute('transform', `translate(${scopeData.x}, ${scopeData.y})`);
                }
                currentY += scopeData.height + nodeSpacingY;
            }
        }
    }
    drawConnections() {
        const svg = this.svgContainer?.nativeElement?.querySelector('svg');
        if (!svg)
            return;
        const mainGroup = svg.querySelector('.main-group');
        if (!mainGroup)
            return;
        // Create connections group if not exists
        let connectionsGroup = mainGroup.querySelector('.connections-group');
        if (!connectionsGroup) {
            connectionsGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');
            connectionsGroup.setAttribute('class', 'connections-group');
            mainGroup.insertBefore(connectionsGroup, mainGroup.firstChild);
        }
        // Clear existing connections
        while (connectionsGroup.firstChild) {
            connectionsGroup.removeChild(connectionsGroup.firstChild);
        }
        // Draw each connection
        for (const conn of this.connections) {
            const fromNode = this.nodes.get(conn.from);
            const fromScope = this.scopes.get(conn.from);
            const toNode = this.nodes.get(conn.to);
            const toScope = this.scopes.get(conn.to);
            let fromX = 0, fromY = 0, toX = 0, toY = 0;
            if (fromNode) {
                fromX = fromNode.x + fromNode.width / 2;
                fromY = fromNode.y + fromNode.height;
            }
            else if (fromScope) {
                fromX = fromScope.x + fromScope.width / 2;
                fromY = fromScope.y + fromScope.height;
            }
            if (toNode) {
                toX = toNode.x + toNode.width / 2;
                toY = toNode.y;
            }
            else if (toScope) {
                toX = toScope.x + toScope.width / 2;
                toY = toScope.y;
            }
            if (fromX && fromY && toX && toY) {
                const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
                const d = `M ${fromX} ${fromY} L ${toX} ${toY}`;
                path.setAttribute('d', d);
                path.setAttribute('fill', 'none');
                path.setAttribute('class', 'connection-line');
                path.setAttribute('stroke-width', '2');
                path.setAttribute('marker-end', 'url(#arrowhead-viz)');
                connectionsGroup.appendChild(path);
                conn.path = path;
            }
        }
    }
    fitToView() {
        const svg = this.svgContainer?.nativeElement?.querySelector('svg');
        const mainGroup = svg?.querySelector('.main-group');
        if (!svg || !mainGroup)
            return;
        const bbox = mainGroup.getBBox();
        const padding = 50;
        const viewBox = `${bbox.x - padding} ${bbox.y - padding} ${bbox.width + 2 * padding} ${bbox.height + 2 * padding}`;
        svg.setAttribute('viewBox', viewBox);
    }
    getStepColor(step) {
        const colorMap = {
            'Prompt': '#2196f3',
            'Actions': '#4caf50',
            'Sub-Agent': '#ff9800',
            'Tool': '#9c27b0',
            'Decision': '#f44336'
        };
        return colorMap[step.StepType] || '#757575';
    }
    getStepEmoji(stepType) {
        const emojiMap = {
            'Prompt': '💬',
            'Actions': '⚙️',
            'Sub-Agent': '🤖',
            'Tool': '🔧',
            'Decision': '🔀',
            'ForEach': '🔁',
            'While': '🔄'
        };
        return emojiMap[stepType] || '⚪';
    }
    getStatusColor(status) {
        const colorMap = {
            'Running': '#1976d2',
            'Completed': '#388e3c',
            'Failed': '#d32f2f',
            'Cancelled': '#f57c00',
            'Paused': '#757575'
        };
        return colorMap[status] || '#9e9e9e';
    }
    getStepDataType(stepType) {
        const typeMap = {
            'Prompt': 'prompt',
            'Actions': 'action',
            'Sub-Agent': 'subagent',
            'Tool': 'tool',
            'Decision': 'decision',
            'ForEach': 'foreach',
            'While': 'while'
        };
        return typeMap[stepType] || 'default';
    }
    truncateText(text, maxLength) {
        if (text.length <= maxLength)
            return text;
        return text.substring(0, maxLength - 3) + '...';
    }
    calculateDuration(start, end) {
        if (!end)
            return 'Running...';
        const ms = new Date(end).getTime() - new Date(start).getTime();
        if (ms < 1000)
            return `${ms}ms`;
        if (ms < 60000)
            return `${(ms / 1000).toFixed(1)}s`;
        if (ms < 3600000)
            return `${Math.floor(ms / 60000)}m ${Math.floor((ms % 60000) / 1000)}s`;
        return `${Math.floor(ms / 3600000)}h ${Math.floor((ms % 3600000) / 60000)}m`;
    }
    // Event handlers
    onNodeClick(event, step) {
        event.stopPropagation();
        // Create timeline item from step
        const item = {
            id: step.ID,
            type: 'step',
            title: step.StepName || `Step ${step.StepNumber}`,
            subtitle: `Type: ${step.StepType}`,
            status: step.Status,
            startTime: step.StartedAt,
            endTime: step.CompletedAt || undefined,
            duration: this.calculateDuration(step.StartedAt, step.CompletedAt),
            icon: this.getStepIcon(step.StepType),
            color: this.getStatusColorName(step.Status),
            data: step,
            level: 0
        };
        this.selectedItem = item;
        this.cdr.detectChanges();
    }
    getStepIcon(stepType) {
        const iconMap = {
            'Prompt': 'fa-microchip',
            'Tool': 'fa-tools',
            'Sub-Agent': 'fa-robot',
            'Decision': 'fa-code-branch',
            'Actions': 'fa-cog',
            'ForEach': 'fa-repeat',
            'While': 'fa-rotate'
        };
        return iconMap[stepType] || 'fa-circle';
    }
    getStatusColorName(status) {
        const colorMap = {
            'Running': 'info',
            'Completed': 'success',
            'Failed': 'error',
            'Cancelled': 'warning',
            'Paused': 'secondary'
        };
        return colorMap[status] || 'secondary';
    }
    async onScopeExpandClick(event, scopeId) {
        event.stopPropagation();
        const scope = this.scopes.get(scopeId);
        if (!scope)
            return;
        scope.expanded = !scope.expanded;
        if (scope.expanded) {
            // Load sub-agent steps
            await this.loadScopeContents(scopeId);
        }
        // Update UI
        this.updateScopeVisual(scope);
        this.arrangeLayout();
        this.drawConnections();
    }
    async loadScopeContents(scopeId) {
        const scope = this.scopes.get(scopeId);
        if (!scope)
            return;
        // Find the step
        const step = Array.from(this.nodes.values()).find(n => UUIDsEqual(n.step.ID, scopeId))?.step
            || Array.from(this.scopes.values()).find(s => s.id === scopeId);
        if (!step || !step.TargetLogID)
            return;
        const targetLogId = step.TargetLogID;
        try {
            // Load sub-agent data through service
            const data = await this.dataHelper.loadSubAgentData(targetLogId);
            if (data.steps && data.steps.length > 0) {
                // Create nodes from data
                this.createScopeNodes(scope, data.steps, data.promptRuns);
            }
        }
        catch (error) {
            console.error('Failed to load scope contents:', error);
        }
    }
    createScopeNodes(scope, steps, promptRuns) {
        const svg = this.svgContainer?.nativeElement?.querySelector('svg');
        if (!svg)
            return;
        const mainGroup = svg.querySelector('.main-group');
        if (!mainGroup || !scope.element)
            return;
        // Create nodes inside scope
        const nodeSpacingY = 60;
        const startX = 20;
        const startY = 60;
        for (let i = 0; i < steps.length; i++) {
            const step = steps[i];
            const nodeElement = this.createNodeElement(step, promptRuns);
            // Add node to scope group
            scope.element.appendChild(nodeElement);
            const nodeData = {
                step: step,
                x: startX,
                y: startY + i * nodeSpacingY,
                width: 160,
                height: 60,
                element: nodeElement
            };
            nodeElement.setAttribute('transform', `translate(${nodeData.x}, ${nodeData.y})`);
            scope.nodes.push(nodeData);
            this.nodes.set(step.ID, nodeData);
        }
        // Update scope height
        scope.height = Math.max(200, startY + steps.length * nodeSpacingY + 20);
    }
    updateScopeVisual(scope) {
        if (!scope.element)
            return;
        // Update background height
        const bg = scope.element.querySelector('rect');
        if (bg) {
            bg.setAttribute('height', scope.height.toString());
        }
        // Update expand button
        const expandIcon = scope.element.querySelector('.expand-button text');
        if (expandIcon) {
            expandIcon.textContent = scope.expanded ? '−' : '+';
        }
    }
    // Drag handling
    onNodeMouseDown(event, nodeId) {
        event.preventDefault();
        event.stopPropagation();
        const node = this.nodes.get(nodeId);
        if (!node || !node.element)
            return;
        // Get current transform
        const transform = node.element.getAttribute('transform');
        const match = transform?.match(/translate\(([-\d.]+),\s*([-\d.]+)\)/);
        if (!match)
            return;
        // Get SVG coordinates
        const svg = node.element.ownerSVGElement;
        if (!svg)
            return;
        const pt = svg.createSVGPoint();
        pt.x = event.clientX;
        pt.y = event.clientY;
        const svgP = pt.matrixTransform(svg.getScreenCTM()?.inverse());
        this.dragState = {
            isDragging: true,
            element: node.element,
            nodeId: nodeId,
            startX: svgP.x,
            startY: svgP.y,
            startTransform: {
                x: parseFloat(match[1]),
                y: parseFloat(match[2])
            }
        };
        node.element.classList.add('dragging');
        // Add document-level event listeners
        document.addEventListener('mousemove', this.onMouseMove);
        document.addEventListener('mouseup', this.onMouseUp);
    }
    // Pan and zoom
    onWheel(event) {
        event.preventDefault();
        const delta = event.deltaY > 0 ? 0.9 : 1.1;
        this.panZoom.scale = Math.max(0.3, Math.min(3, this.panZoom.scale * delta));
        this.updateTransform();
    }
    onSvgMouseDown(event) {
        if (event.button === 0 && event.target === event.currentTarget) {
            this.panZoom.isPanning = true;
            this.panZoom.startX = event.clientX - this.panZoom.translateX;
            this.panZoom.startY = event.clientY - this.panZoom.translateY;
            event.preventDefault();
        }
    }
    onSvgMouseMove(event) {
        if (this.panZoom.isPanning) {
            this.panZoom.translateX = event.clientX - this.panZoom.startX;
            this.panZoom.translateY = event.clientY - this.panZoom.startY;
            this.updateTransform();
        }
    }
    onSvgMouseUp(event) {
        this.panZoom.isPanning = false;
    }
    updateTransform() {
        const svg = this.svgContainer?.nativeElement?.querySelector('svg');
        if (svg) {
            const mainGroup = svg.querySelector('.main-group');
            if (mainGroup) {
                mainGroup.setAttribute('transform', `translate(${this.panZoom.translateX}, ${this.panZoom.translateY}) scale(${this.panZoom.scale})`);
            }
        }
    }
    // Toolbar actions
    zoomIn() {
        this.panZoom.scale = Math.min(this.panZoom.scale * 1.2, 3);
        this.updateTransform();
    }
    zoomOut() {
        this.panZoom.scale = Math.max(this.panZoom.scale / 1.2, 0.3);
        this.updateTransform();
    }
    resetZoom() {
        this.panZoom.scale = 1;
        this.panZoom.translateX = 0;
        this.panZoom.translateY = 0;
        this.updateTransform();
    }
    // Detail pane handlers
    closeDetailPane() {
        this.selectedItem = null;
        this.cdr.detectChanges();
    }
    navigateToActionLog(logId) {
        // Emit event to parent component
        // Parent will handle navigation
    }
    async copyToClipboard(text) {
        try {
            await navigator.clipboard.writeText(text);
        }
        catch (err) {
            console.error('Failed to copy to clipboard:', err);
        }
    }
    static { this.ɵfac = function AIAgentRunVisualizationComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || AIAgentRunVisualizationComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); }; }
    static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: AIAgentRunVisualizationComponent, selectors: [["mj-ai-agent-run-visualization"]], viewQuery: function AIAgentRunVisualizationComponent_Query(rf, ctx) { if (rf & 1) {
            i0.ɵɵviewQuery(_c0, 5);
        } if (rf & 2) {
            let _t;
            i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.svgContainer = _t.first);
        } }, inputs: { aiAgentRunId: "aiAgentRunId", dataHelper: "dataHelper" }, standalone: false, decls: 3, vars: 1, consts: [["svgContainer", ""], [1, "visualization-container"], [1, "error-state"], ["direction", "horizontal", 2, "height", "100%"], [1, "fa-solid", "fa-exclamation-triangle"], [3, "size"], [1, "diagram-container"], [1, "diagram-toolbar"], [1, "toolbar-title"], [1, "fa-solid", "fa-diagram-project"], [1, "zoom-controls"], ["title", "Zoom in", 3, "click"], [1, "fa-solid", "fa-search-plus"], ["title", "Zoom out", 3, "click"], [1, "fa-solid", "fa-search-minus"], ["title", "Reset zoom", 3, "click"], [1, "fa-solid", "fa-compress"], [1, "zoom-level"], [1, "loading-overlay"], [3, "size", "minSize", "maxSize"], [1, "fa-solid", "fa-spinner", "fa-spin"], [3, "closePanel", "navigateToActionLog", "copyToClipboard", "selectedTimelineItem"]], template: function AIAgentRunVisualizationComponent_Template(rf, ctx) { if (rf & 1) {
            i0.ɵɵelementStart(0, "div", 1);
            i0.ɵɵconditionalCreate(1, AIAgentRunVisualizationComponent_Conditional_1_Template, 4, 1, "div", 2)(2, AIAgentRunVisualizationComponent_Conditional_2_Template, 19, 4, "as-split", 3);
            i0.ɵɵelementEnd();
        } if (rf & 2) {
            i0.ɵɵadvance();
            i0.ɵɵconditional(ctx.error ? 1 : 2);
        } }, dependencies: [i1.SplitComponent, i1.SplitAreaComponent, i2.AIAgentRunStepDetailComponent], styles: [".visualization-container[_ngcontent-%COMP%] {\n  width: 100%;\n  height: 100%;\n  position: relative;\n  background: var(--mj-bg-surface-sunken);\n  border: 1px solid var(--mj-border-default);\n  border-radius: 4px;\n  overflow: hidden;\n}\n\n.loading-state[_ngcontent-%COMP%], .error-state[_ngcontent-%COMP%], .empty-state[_ngcontent-%COMP%] {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  height: 100%;\n  gap: 0.5rem;\n  color: var(--mj-text-muted);\n}\n\n.error-state[_ngcontent-%COMP%] {\n  color: var(--mj-status-error);\n}\n\n.empty-state[_ngcontent-%COMP%] {\n  flex-direction: column;\n  gap: 1rem;\n}\n\n.empty-state[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n  font-size: 2rem;\n  opacity: 0.5;\n}\n\n.loading-overlay[_ngcontent-%COMP%] {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  display: flex;\n  align-items: center;\n  gap: 0.5rem;\n  background: color-mix(in srgb, var(--mj-bg-surface) 90%, transparent);\n  padding: 1rem 2rem;\n  border-radius: 4px;\n  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n  z-index: 10;\n}\n\n.diagram-container[_ngcontent-%COMP%] {\n  width: 100%;\n  height: 100%;\n  position: relative;\n  overflow: hidden;\n  background: var(--mj-bg-surface-sunken);\n}\n\n.diagram-toolbar[_ngcontent-%COMP%] {\n  position: absolute;\n  top: 10px;\n  right: 10px;\n  left: 10px;\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  background: var(--mj-bg-surface);\n  padding: 8px 12px;\n  border-radius: 4px;\n  box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n  z-index: 10;\n}\n\n.toolbar-title[_ngcontent-%COMP%] {\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  font-size: 14px;\n  font-weight: 600;\n  color: var(--mj-text-primary);\n}\n\n.zoom-controls[_ngcontent-%COMP%] {\n  display: flex;\n  gap: 4px;\n  align-items: center;\n}\n\n.zoom-controls[_ngcontent-%COMP%]   button[_ngcontent-%COMP%] {\n  padding: 6px 10px;\n  border: 1px solid var(--mj-border-default);\n  background: var(--mj-bg-surface);\n  border-radius: 3px;\n  cursor: pointer;\n  font-size: 12px;\n  display: flex;\n  align-items: center;\n  transition: all 0.2s;\n}\n\n.zoom-controls[_ngcontent-%COMP%]   button[_ngcontent-%COMP%]:hover {\n  background: var(--mj-bg-surface-sunken);\n  border-color: var(--mj-brand-primary);\n}\n\n.zoom-level[_ngcontent-%COMP%] {\n  font-size: 12px;\n  color: var(--mj-text-muted);\n  margin-left: 8px;\n  font-family: monospace;\n}\n\n.visualization-svg[_ngcontent-%COMP%] {\n  width: 100%;\n  height: 100%;\n  cursor: grab;\n}\n\n.visualization-svg[_ngcontent-%COMP%]:active {\n  cursor: grabbing;\n}\n\n\n\n[_nghost-%COMP%]     .step-node {\n  cursor: pointer;\n}\n\n[_nghost-%COMP%]     .step-node.dragging {\n  opacity: 0.8;\n  cursor: move;\n}\n\n[_nghost-%COMP%]     .step-node rect {\n  filter: drop-shadow(0 2px 4px rgba(0,0,0,0.1));\n}\n\n[_nghost-%COMP%]     .step-node:hover rect {\n  filter: drop-shadow(0 4px 8px rgba(0,0,0,0.15));\n}\n\n\n\n[_nghost-%COMP%]     .node-bg {\n  fill: var(--mj-bg-surface-card);\n}\n\n[_nghost-%COMP%]     .node-title {\n  fill: var(--mj-text-primary);\n}\n\n[_nghost-%COMP%]     .node-subtitle {\n  fill: var(--mj-text-secondary);\n}\n\n[_nghost-%COMP%]     .node-meta {\n  fill: var(--mj-text-muted);\n}\n\n[_nghost-%COMP%]     .connection-line {\n  stroke: var(--mj-text-secondary);\n  opacity: 0.5;\n}\n\n[_nghost-%COMP%]     .arrowhead-polygon {\n  fill: var(--mj-text-secondary);\n}\n\n[_nghost-%COMP%]     .scope-bg {\n  fill: var(--mj-bg-surface-sunken);\n  stroke: var(--mj-brand-primary);\n}\n\n[_nghost-%COMP%]     .scope-header {\n  fill: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n[_nghost-%COMP%]     .scope-title {\n  fill: var(--mj-brand-primary);\n}\n\n[_nghost-%COMP%]     .expand-button .expand-bg {\n  fill: var(--mj-bg-surface-card);\n  stroke: var(--mj-brand-primary);\n}\n\n[_nghost-%COMP%]     .expand-button .expand-icon {\n  fill: var(--mj-brand-primary);\n}\n\n[_nghost-%COMP%]     .scope-container {\n  cursor: pointer;\n}\n\n[_nghost-%COMP%]     .scope-container rect {\n  filter: drop-shadow(0 2px 4px rgba(0,0,0,0.1));\n}\n\n[_nghost-%COMP%]     .expand-button:hover circle {\n  fill: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n[_nghost-%COMP%]     .connections-group path {\n  transition: stroke-width 0.2s;\n}\n\n[_nghost-%COMP%]     .connections-group path:hover {\n  stroke-width: 3;\n}\n\n\n\n[_nghost-%COMP%]     .k-splitter {\n  border: none;\n}\n\n[_nghost-%COMP%]     .k-splitter-pane {\n  overflow: visible;\n}\n\n[_nghost-%COMP%]     .k-splitbar {\n  background: var(--mj-border-default);\n  width: 4px;\n}\n\n[_nghost-%COMP%]     .k-splitbar:hover {\n  background: var(--mj-border-strong);\n}\n\n[_nghost-%COMP%]     .k-splitbar-draggable-horizontal {\n  cursor: col-resize;\n}\n\n\n\n[_nghost-%COMP%]     .step-node[data-type=\"prompt\"] rect {\n  fill: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n[_nghost-%COMP%]     .step-node[data-type=\"action\"] rect {\n  fill: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n}\n\n[_nghost-%COMP%]     .step-node[data-type=\"subagent\"] rect {\n  fill: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n}\n\n[_nghost-%COMP%]     .step-node[data-type=\"tool\"] rect {\n  fill: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n[_nghost-%COMP%]     .step-node[data-type=\"decision\"] rect {\n  fill: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n}"], changeDetection: 0 }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AIAgentRunVisualizationComponent, [{
        type: Component,
        args: [{ standalone: false, selector: 'mj-ai-agent-run-visualization', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"visualization-container\">\n  @if (error) {\n    <div class=\"error-state\">\n      <i class=\"fa-solid fa-exclamation-triangle\"></i>\n      <span>{{ error }}</span>\n    </div>\n  } @else {\n    <as-split direction=\"horizontal\" style=\"height: 100%;\">\n      <!-- Diagram Pane -->\n      <as-split-area [size]=\"selectedItem ? 70 : 100\">\n        <div class=\"diagram-container\" #svgContainer>\n          <div class=\"diagram-toolbar\">\n            <div class=\"toolbar-title\">\n              <i class=\"fa-solid fa-diagram-project\"></i>\n              Agent Execution Flow\n            </div>\n            <div class=\"zoom-controls\">\n              <button (click)=\"zoomIn()\" title=\"Zoom in\">\n                <i class=\"fa-solid fa-search-plus\"></i>\n              </button>\n              <button (click)=\"zoomOut()\" title=\"Zoom out\">\n                <i class=\"fa-solid fa-search-minus\"></i>\n              </button>\n              <button (click)=\"resetZoom()\" title=\"Reset zoom\">\n                <i class=\"fa-solid fa-compress\"></i>\n              </button>\n              <span class=\"zoom-level\">{{ (panZoom.scale * 100).toFixed(0) }}%</span>\n            </div>\n          </div>\n          @if (loading) {\n            <div class=\"loading-overlay\">\n              <i class=\"fa-solid fa-spinner fa-spin\"></i>\n              <span>Loading visualization...</span>\n            </div>\n          }\n        </div>\n      </as-split-area>\n\n      <!-- Detail Pane -->\n      @if (selectedItem) {\n        <as-split-area [size]=\"30\" [minSize]=\"20\" [maxSize]=\"50\">\n          <mj-ai-agent-run-step-detail\n            [selectedTimelineItem]=\"selectedItem\"\n            (closePanel)=\"closeDetailPane()\"\n            (navigateToActionLog)=\"navigateToActionLog($event)\"\n            (copyToClipboard)=\"copyToClipboard($event)\">\n          </mj-ai-agent-run-step-detail>\n        </as-split-area>\n      }\n    </as-split>\n  }\n</div>", styles: [".visualization-container {\n  width: 100%;\n  height: 100%;\n  position: relative;\n  background: var(--mj-bg-surface-sunken);\n  border: 1px solid var(--mj-border-default);\n  border-radius: 4px;\n  overflow: hidden;\n}\n\n.loading-state, .error-state, .empty-state {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  height: 100%;\n  gap: 0.5rem;\n  color: var(--mj-text-muted);\n}\n\n.error-state {\n  color: var(--mj-status-error);\n}\n\n.empty-state {\n  flex-direction: column;\n  gap: 1rem;\n}\n\n.empty-state i {\n  font-size: 2rem;\n  opacity: 0.5;\n}\n\n.loading-overlay {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  display: flex;\n  align-items: center;\n  gap: 0.5rem;\n  background: color-mix(in srgb, var(--mj-bg-surface) 90%, transparent);\n  padding: 1rem 2rem;\n  border-radius: 4px;\n  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n  z-index: 10;\n}\n\n.diagram-container {\n  width: 100%;\n  height: 100%;\n  position: relative;\n  overflow: hidden;\n  background: var(--mj-bg-surface-sunken);\n}\n\n.diagram-toolbar {\n  position: absolute;\n  top: 10px;\n  right: 10px;\n  left: 10px;\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  background: var(--mj-bg-surface);\n  padding: 8px 12px;\n  border-radius: 4px;\n  box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n  z-index: 10;\n}\n\n.toolbar-title {\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  font-size: 14px;\n  font-weight: 600;\n  color: var(--mj-text-primary);\n}\n\n.zoom-controls {\n  display: flex;\n  gap: 4px;\n  align-items: center;\n}\n\n.zoom-controls button {\n  padding: 6px 10px;\n  border: 1px solid var(--mj-border-default);\n  background: var(--mj-bg-surface);\n  border-radius: 3px;\n  cursor: pointer;\n  font-size: 12px;\n  display: flex;\n  align-items: center;\n  transition: all 0.2s;\n}\n\n.zoom-controls button:hover {\n  background: var(--mj-bg-surface-sunken);\n  border-color: var(--mj-brand-primary);\n}\n\n.zoom-level {\n  font-size: 12px;\n  color: var(--mj-text-muted);\n  margin-left: 8px;\n  font-family: monospace;\n}\n\n.visualization-svg {\n  width: 100%;\n  height: 100%;\n  cursor: grab;\n}\n\n.visualization-svg:active {\n  cursor: grabbing;\n}\n\n/* SVG Styles */\n:host ::ng-deep .step-node {\n  cursor: pointer;\n}\n\n:host ::ng-deep .step-node.dragging {\n  opacity: 0.8;\n  cursor: move;\n}\n\n:host ::ng-deep .step-node rect {\n  filter: drop-shadow(0 2px 4px rgba(0,0,0,0.1));\n}\n\n:host ::ng-deep .step-node:hover rect {\n  filter: drop-shadow(0 4px 8px rgba(0,0,0,0.15));\n}\n\n/* SVG structural colors \u2014 adapt to light/dark theme via CSS classes */\n:host ::ng-deep .node-bg {\n  fill: var(--mj-bg-surface-card);\n}\n\n:host ::ng-deep .node-title {\n  fill: var(--mj-text-primary);\n}\n\n:host ::ng-deep .node-subtitle {\n  fill: var(--mj-text-secondary);\n}\n\n:host ::ng-deep .node-meta {\n  fill: var(--mj-text-muted);\n}\n\n:host ::ng-deep .connection-line {\n  stroke: var(--mj-text-secondary);\n  opacity: 0.5;\n}\n\n:host ::ng-deep .arrowhead-polygon {\n  fill: var(--mj-text-secondary);\n}\n\n:host ::ng-deep .scope-bg {\n  fill: var(--mj-bg-surface-sunken);\n  stroke: var(--mj-brand-primary);\n}\n\n:host ::ng-deep .scope-header {\n  fill: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n:host ::ng-deep .scope-title {\n  fill: var(--mj-brand-primary);\n}\n\n:host ::ng-deep .expand-button .expand-bg {\n  fill: var(--mj-bg-surface-card);\n  stroke: var(--mj-brand-primary);\n}\n\n:host ::ng-deep .expand-button .expand-icon {\n  fill: var(--mj-brand-primary);\n}\n\n:host ::ng-deep .scope-container {\n  cursor: pointer;\n}\n\n:host ::ng-deep .scope-container rect {\n  filter: drop-shadow(0 2px 4px rgba(0,0,0,0.1));\n}\n\n:host ::ng-deep .expand-button:hover circle {\n  fill: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n:host ::ng-deep .connections-group path {\n  transition: stroke-width 0.2s;\n}\n\n:host ::ng-deep .connections-group path:hover {\n  stroke-width: 3;\n}\n\n/* Splitter customization */\n:host ::ng-deep .k-splitter {\n  border: none;\n}\n\n:host ::ng-deep .k-splitter-pane {\n  overflow: visible;\n}\n\n:host ::ng-deep .k-splitbar {\n  background: var(--mj-border-default);\n  width: 4px;\n}\n\n:host ::ng-deep .k-splitbar:hover {\n  background: var(--mj-border-strong);\n}\n\n:host ::ng-deep .k-splitbar-draggable-horizontal {\n  cursor: col-resize;\n}\n\n/* Node type colors */\n:host ::ng-deep .step-node[data-type=\"prompt\"] rect {\n  fill: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n:host ::ng-deep .step-node[data-type=\"action\"] rect {\n  fill: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n}\n\n:host ::ng-deep .step-node[data-type=\"subagent\"] rect {\n  fill: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n}\n\n:host ::ng-deep .step-node[data-type=\"tool\"] rect {\n  fill: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n:host ::ng-deep .step-node[data-type=\"decision\"] rect {\n  fill: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n}"] }]
    }], () => [{ type: i0.ChangeDetectorRef }], { svgContainer: [{
            type: ViewChild,
            args: ['svgContainer', { static: false }]
        }], aiAgentRunId: [{
            type: Input
        }], dataHelper: [{
            type: Input
        }] }); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AIAgentRunVisualizationComponent, { className: "AIAgentRunVisualizationComponent", filePath: "src/lib/custom/ai-agent-run/ai-agent-run-visualization.component.ts", lineNumber: 37 }); })();
//# sourceMappingURL=ai-agent-run-visualization.component.js.map