import { CodeCell } from '@jupyterlab/cells';
import { IDisposable } from '@lumino/disposable';

/**
 * ExecutionTimer manages timing display for cell execution
 * Shows execution indicator and backend elapsed time on the right side of cells
 */
export class ExecutionTimer implements IDisposable {
    private timerElements: Map<CodeCell, HTMLElement> = new Map();
    private cellMessageIds: Map<string, string> = new Map();

    constructor() {
        // ExecutionTimer initialized
    }

    /**
     * Start showing execution indicator for a cell
     */
    public startTimer(cell: CodeCell, msgId?: string): void {
        const cellId = cell.model.id;
        
        console.log("⏱️ Starting execution indicator for cell:", cellId);

        // Clean up any existing timer state for this cell
        this.forceCleanupCell(cell);

        // Create timer element showing "running" state
        this.createTimerElement(cell);
        
        if (msgId) {
            this.cellMessageIds.set(cellId, msgId);
        }
        
        console.log("✅ Execution indicator shown");
    }

    /**
     * Stop execution and show backend elapsed time
     */
    public stopTimer(cell: CodeCell, elapsedTimeMs?: number): void {
        const cellId = cell.model.id;
        
        console.log("⏹️ Stopping execution indicator for cell:", cellId, "elapsedTimeMs:", elapsedTimeMs);

        // Display the backend elapsed time if available
        if (elapsedTimeMs !== undefined) {
            const elapsed_seconds = (elapsedTimeMs / 1000).toFixed(2);
            this.updateTimerElement(cell, `${elapsed_seconds}s`, true);
        } else {
            // No backend time available, just mark as completed
            this.updateTimerElement(cell, 'completed', true);
        }

        // Clean up state
        this.cellMessageIds.delete(cellId);
        
        console.log("✅ Execution completed:", elapsedTimeMs, "ms");
    }

    /**
     * Stop timer by message ID (for kernel message handling)
     */
    public stopTimerByMsgId(msgId: string): void {
        for (const [cellId, storedMsgId] of this.cellMessageIds.entries()) {
            if (storedMsgId === msgId) {
                // Find the cell by ID
                for (const [cell] of this.timerElements.entries()) {
                    if (cell.model.id === cellId) {
                        this.stopTimer(cell);
                        break;
                    }
                }
                break;
            }
        }
    }

    /**
     * Force stop timer (for manual interruptions like stop button)
     */
    public forceStopTimer(cell: CodeCell): void {
        const cellId = cell.model.id;
        
        console.log("🛑 Force stopping execution for cell:", cellId);

        // Update the display to show stopped state
        this.updateTimerElement(cell, 'stopped', false);

        // Clear state but keep timer element visible
        this.cellMessageIds.delete(cellId);
        
        console.log("✅ Execution stopped");
    }

    /**
     * Force cleanup all timer state for a cell
     */
    private forceCleanupCell(cell: CodeCell): void {
        const cellId = cell.model.id;

        // Remove timer element
        this.removeTimerElement(cell);

        // Clear all state
        this.cellMessageIds.delete(cellId);
        
        console.log("🧹 Cleaned up all state for cell:", cellId);
    }

    /**
     * Check if a cell is currently showing execution indicator
     */
    public isTimingCell(cell: CodeCell): boolean {
        return this.timerElements.has(cell);
    }

    /**
     * Create timer element on the right side of the cell
     */
    private createTimerElement(cell: CodeCell): void {
        
        // Remove any existing timer element
        this.removeTimerElement(cell);

        const cellNode = (cell as any).node;
        
        console.log("📝 Creating execution indicator on right side");
        
        // Create a visible timer element on the right side
        const timerElement = document.createElement('div');
        timerElement.className = 'vadalog-timer-display';
        timerElement.style.cssText = `
            position: absolute;
            top: 4px;
            right: 8px;
            font-size: 0.85em;
            color: var(--jp-ui-font-color2);
            font-weight: 500;
            opacity: 0.8;
            font-style: italic;
            background: var(--jp-layout-color1);
            padding: 2px 8px;
            border-radius: 3px;
            border: 1px solid var(--jp-border-color2);
            z-index: 100;
            pointer-events: none;
        `;
        timerElement.textContent = '⏱️ running...';
        
        // Make sure cell has relative positioning
        cellNode.style.position = 'relative';
        
        cellNode.appendChild(timerElement);
        this.timerElements.set(cell, timerElement);
        
        console.log("✅ Execution indicator created");
    }

    /**
     * Update the timer element with new time or status
     */
    private updateTimerElement(cell: CodeCell, timeText: string, isCompleted: boolean): void {
        const timerElement = this.timerElements.get(cell);
        if (!timerElement) return;

        // Update the timer display
        if (isCompleted) {
            // Completed execution - show in green
            timerElement.textContent = `✓ ${timeText}`;
            timerElement.style.color = 'var(--jp-success-color1)';
            timerElement.style.fontWeight = '600';
            timerElement.style.borderColor = 'var(--jp-success-color1)';
        } else if (timeText.includes('stopped')) {
            // Stopped execution - show in red
            timerElement.textContent = `⏹ ${timeText}`;
            timerElement.style.color = 'var(--jp-error-color1)';
            timerElement.style.fontWeight = '600';
            timerElement.style.borderColor = 'var(--jp-error-color1)';
        } else {
            // Running - show with clock icon
            timerElement.textContent = `⏱️ ${timeText}`;
        }
    }

    /**
     * Remove timer element for a cell
     */
    private removeTimerElement(cell: CodeCell): void {
        const timerElement = this.timerElements.get(cell);
        if (timerElement) {
            // Simply remove the timer element from the DOM
            timerElement.remove();
            this.timerElements.delete(cell);
        }
    }

    /**
     * Dispose of all timers and clean up
     */
    public dispose(): void {
        // Remove all timer elements
        this.timerElements.forEach((timerElement, cell) => {
            this.removeTimerElement(cell);
        });

        // Clear all maps
        this.cellMessageIds.clear();
    }

    public get isDisposed(): boolean {
        return this.timerElements.size === 0;
    }
}
