// workflows.js

function workflowsComponent() {
    return {
        selectedExecutions: [],
        currentExecutionId: null,
        currentExecution: null,
        loading: false,
        filterWorkflow: '',
        allExecutions: window.workflowsData.allExecutions,
        pollInterval: null,
        expandedState: {}, // Track expansion state of steps

        resumeModal: {
            open: false,
            workflowName: '',
            stepName: '',
            inputs: '',
            error: null
        },

        init() {
            // Wait for Alpine to finish rendering before selecting execution
            this.$nextTick(() => {
                const hash = window.location.hash.slice(1);
                if (hash) {
                    this.selectExecution(hash);
                } else {
                    const firstExecution = this.$el.querySelector('[data-execution-id]');
                    if (firstExecution) {
                        this.selectExecution(firstExecution.dataset.executionId);
                    }
                }
            });

            // Start polling for updates
            if (!document.hidden) {
                this.startPolling();
            }

            // Pause polling when tab is hidden to save resources
            document.addEventListener('visibilitychange', () => {
                if (document.hidden) {
                    this.stopPolling();
                } else {
                    this.startPolling();
                }
            });
        },
        
        toggle(stepId) {
            // If undefined, default is expanded (true), so toggle to false
            if (this.expandedState[stepId] === undefined) {
                this.expandedState[stepId] = false;
            } else {
                this.expandedState[stepId] = !this.expandedState[stepId];
            }
        },
        
        isExpanded(stepId) {
            // Default to true if not set
            return this.expandedState[stepId] !== false;
        },

        startPolling() {
            this.stopPolling();

            // Poll immediately
            this.fetchExecutions();

            // Then poll every 0.5 seconds
            this.pollInterval = setInterval(() => {
                this.fetchExecutions();
            }, 500);
        },

        stopPolling() {
            if (this.pollInterval) {
                clearInterval(this.pollInterval);
                this.pollInterval = null;
            }
        },

        async fetchExecutions() {
            try {
                const response = await fetch('/api/executions?limit=100');
                if (!response.ok) return;

                const executions = await response.json();
                this.allExecutions = executions;

                // Refresh current execution details if one is selected
                if (this.currentExecutionId) {
                    const currentExists = executions.find(
                        ex => ex.execution_id === this.currentExecutionId
                    );
                    if (currentExists) {
                        // Refresh details view
                        this.selectExecution(this.currentExecutionId);
                    } else {
                        this.currentExecutionId = null;
                        this.currentExecution = null;
                        window.location.hash = '';
                    }
                }
            } catch (error) {
                // Silently fail - will retry on next poll
                console.error('Poll error:', error);
            }
        },

        get uniqueWorkflowNames() {
            const names = [...new Set(this.allExecutions.map(ex => ex.workflow_name))];
            return names.sort();
        },

        get filteredExecutions() {
            if (!this.filterWorkflow) {
                return this.allExecutions;
            }
            return this.allExecutions.filter(ex => ex.workflow_name === this.filterWorkflow);
        },

        get hasSelectedExecutions() {
            return this.selectedExecutions.length > 0;
        },

        get allSelected() {
            return this.selectedExecutions.length === this.filteredExecutions.length;
        },

        get totalRunTokens() {
            if (!this.currentExecution || !this.currentExecution.step_executions) return 0;
            return this.currentExecution.step_executions.reduce((total, step) => {
                if (step.outputs && step.outputs.usage && step.outputs.usage.total_tokens) {
                    return total + step.outputs.usage.total_tokens;
                }
                return total;
            }, 0);
        },

        get flattenedSteps() {
            if (!this.currentExecution || !this.currentExecution.step_executions) {
                return [];
            }
            
            const steps = this.currentExecution.step_executions;
            const stepMap = {};
            const rootSteps = [];

            // First pass: Create map
            steps.forEach(step => {
                const id = step.checkpoint_id || step.step_name + '_' + step.timestamp;
                stepMap[id] = { ...step, children: [], id: id };
            });

            // Second pass: Build Tree
            steps.forEach(step => {
                const id = step.checkpoint_id || step.step_name + '_' + step.timestamp;
                const treeNode = stepMap[id];
                
                if (step.parent_checkpoint_id && stepMap[step.parent_checkpoint_id]) {
                    stepMap[step.parent_checkpoint_id].children.push(treeNode);
                } else {
                    rootSteps.push(treeNode);
                }
            });

            // Sort roots by sequence/timestamp
            rootSteps.sort((a, b) => new Date(a.timestamp) - new Date(b.timestamp));

            // Third pass: Flatten tree depth-first
            const flatList = [];
            const self = this; // Capture 'this' for use in traverse
            
            function traverse(nodes, depth) {
                nodes.forEach(node => {
                    // Add depth info
                    node.depth = depth;
                    node.hasChildren = node.children.length > 0; // Flag for UI
                    node.isExpanded = self.isExpanded(node.id); // Bake state into object for UI
                    flatList.push(node);
                    
                    // Only traverse children if expanded
                    if (node.children.length > 0 && self.isExpanded(node.id)) {
                        traverse(node.children, depth + 1);
                    }
                });
            }
            
            traverse(rootSteps, 0);
            return flatList;
        },

        toggleSelectAll() {
            if (this.allSelected) {
                this.selectedExecutions = [];
            } else {
                this.selectedExecutions = this.filteredExecutions.map(ex => ex.execution_id);
            }
        },

        async selectExecution(executionId) {
            if (this.currentExecutionId === executionId) return;

            this.currentExecutionId = executionId;
            this.loading = true;

            // Update URL hash
            window.location.hash = executionId;

            try {
                const response = await fetch(`/api/executions/${executionId}`);
                if (!response.ok) throw new Error('Failed to fetch execution');

                this.currentExecution = await response.json();
            } catch (error) {
                console.error('Error loading execution:', error);
                this.currentExecution = { error: error.message };
            } finally {
                this.loading = false;
            }
        },

        timeTravel(workflowName, stepName, inputs) {
            this.resumeModal.workflowName = workflowName;
            this.resumeModal.stepName = stepName;
            this.resumeModal.inputs = JSON.stringify(inputs, null, 2);
            this.resumeModal.error = null;
            this.resumeModal.open = true;
        },

        async confirmResume() {
            try {
                // Validate JSON
                let parsedInputs;
                try {
                    parsedInputs = JSON.parse(this.resumeModal.inputs);
                } catch (e) {
                    this.resumeModal.error = "Invalid JSON: " + e.message;
                    return;
                }

                const workflowName = this.resumeModal.workflowName;
                const stepName = this.resumeModal.stepName;

                const response = await fetch(`/workflows/${workflowName}/resume?step_name=${stepName}`, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify(parsedInputs)
                });

                if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);

                const data = await response.json();

                // Close modal
                this.resumeModal.open = false;

                // Instead of alerting, select the new execution and scroll to it
                this.selectExecution(data.execution_id);
                
                // Update the list immediately
                await this.fetchExecutions();

            } catch (error) {
                this.resumeModal.error = `Time travel failed: ${error.message}`;
            }
        },

        async deleteSelected() {
            if (this.selectedExecutions.length === 0) return;

            const confirmed = confirm(`Are you sure you want to delete ${this.selectedExecutions.length} execution(s)? This cannot be undone.`);
            if (!confirmed) return;

            try {
                const response = await fetch('/api/executions', {
                    method: 'DELETE',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify(this.selectedExecutions)
                });

                if (response.ok) {
                    const result = await response.json();
                    alert(result.message);
                    this.selectedExecutions = [];
                    this.fetchExecutions();
                } else {
                    const error = await response.json();
                    alert('Error: ' + error.detail);
                }
            } catch (error) {
                alert('Failed to delete executions: ' + error);
            }
        },

        handleKeydown(e) {
            if (['ArrowUp', 'ArrowDown'].includes(e.key)) {
                e.preventDefault();
                const currentIdx = this.filteredExecutions.findIndex(ex => ex.execution_id === this.currentExecutionId);
                let newIdx = -1;

                if (e.key === 'ArrowUp') {
                    newIdx = currentIdx > 0 ? currentIdx - 1 : this.filteredExecutions.length - 1;
                } else {
                    newIdx = currentIdx < this.filteredExecutions.length - 1 ? currentIdx + 1 : 0;
                }

                if (newIdx !== -1) {
                    const nextId = this.filteredExecutions[newIdx].execution_id;
                    this.selectExecution(nextId);

                    // Scroll into view
                    this.$nextTick(() => {
                        const el = document.querySelector(`[data-execution-id='${nextId}']`);
                        if (el) el.scrollIntoView({ block: 'nearest' });
                    });
                }
            }
        },

        copyToClipboard(text) {
            navigator.clipboard.writeText(JSON.stringify(text, null, 2));
        },

        async rerunWorkflow(workflowName, inputs) {
            if (!confirm('Run this workflow again with the same inputs?')) return;
            
            this.loading = true;
            try {
                const response = await fetch(`/api/workflows/${workflowName}/rerun`, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify(inputs)
                });

                if (!response.ok) {
                    const errorData = await response.json();
                    throw new Error(errorData.detail || 'Failed to execute workflow');
                }

                const result = await response.json();
                
                // Fetch executions to get the new ID
                await this.fetchExecutions();
                
                // Select the new execution (it will be the most recent one)
                if (result && result.execution_id) {
                    this.selectExecution(result.execution_id);
                } else {
                    // Fallback: Select the first execution in the list (most recent)
                    if (this.allExecutions.length > 0) {
                        this.selectExecution(this.allExecutions[0].execution_id);
                    }
                }
                
            } catch (error) {
                let errorMessage = error.message;
                if (errorMessage === '[object Object]') {
                    try {
                        errorMessage = JSON.stringify(error);
                    } catch (e) {}
                }
                alert(`Failed to rerun workflow: ${errorMessage}`);
            } finally {
                this.loading = false;
            }
        }
    }
}