/**
 * Main javascript file for GLANCE Developer Platform
 */

// Global variables
let editor; // CodeMirror editor instance
let errorTimeout;

document.addEventListener('DOMContentLoaded', function() {
    
    // Handle session management first (before initializing other components)
    handleSessionManagement();
 
    // Initialize canvas with proper config
    const canvasConfig = {
        enableGrid: true,            // Enable grid by default
        enableTooltips: true,        // Enable coordinate tooltips
        enableControls: true,        // Enable zoom/pan controls
        initialZoom: 1,              // Initial zoom level
        gridColor: 'rgba(255, 255, 255, 0.1)'  // Grid line color
    };
    
    const canvas = new CanvasHandler('preview-canvas', canvasConfig);
    window.canvas = canvas; // Make it globally accessible for the compiler

    // Initialize features
    initCodeEditor();
    
    // Set up resizable editor/preview
    setupResizableEditorPreview();
    
    // Handle grid toggle
    const showGridCheckbox = document.getElementById('show-grid');
    if (showGridCheckbox) {
        showGridCheckbox.checked = true; // Grid is on by default
        showGridCheckbox.addEventListener('change', function() {
            if (canvas) {
                canvas.toggleGrid();
            }
        });
    }
    
    // Store editor content before navigation
    document.querySelectorAll('.btn-group a').forEach(link => {
        link.addEventListener('click', function(e) {
            // Save editor content to localStorage if editor exists
            if (editor) {
                localStorage.setItem('editorContent', editor.getValue());
            }
        });
    });
    
    // Toggle help sections
    document.querySelectorAll('.help-header').forEach(header => {
        header.addEventListener('click', function() {
            const content = this.nextElementSibling;
            const arrow = this.querySelector('.arrow');
            
            content.style.display = content.style.display === 'block' ? 'none' : 'block';
            arrow.textContent = content.style.display === 'block' ? '▲' : '▼';
        });
    });
    
    // Tab switching
    document.querySelectorAll('.tab').forEach(tab => {
        tab.addEventListener('click', function() {
            // Remove active class from all tabs
            document.querySelectorAll('.tab').forEach(t => {
                t.classList.remove('active');
            });
            
            // Add active class to clicked tab
            this.classList.add('active');
            
            // Hide all tab contents
            document.querySelectorAll('.tab-content').forEach(content => {
                content.style.display = 'none';
                content.classList.remove('active');
            });
            
            // Show content for active tab
            const tabId = this.getAttribute('data-tab');
            const tabContent = document.getElementById(tabId + '-tab');
            if (tabContent) {
                tabContent.style.display = 'block';
                tabContent.classList.add('active');
            }
        });
    });

    // Handle copy buttons in help section
    document.querySelectorAll('.copy-btn').forEach(button => {
        button.addEventListener('click', handleCopyClick);
    });
        
    // Preview button
    // Preview button
    const previewBtn = document.getElementById('preview-btn');
    if (previewBtn) {
        previewBtn.addEventListener('click', function() {
            // Show loading animation with shorter timeout
            toggleLoader(true);
            setTimeout(() => toggleLoader(false), 800); // Shorter display for preview
            
            // Get current canvas size
            const canvasSize = document.body.getAttribute('data-canvas-size');
            let width = 64, height = 32;
            
            if (canvasSize) {
                const sizeParts = canvasSize.split('x');
                width = parseInt(sizeParts[0]) || 64;
                height = parseInt(sizeParts[1]) || 32;
            }
            
            // Update canvas dimensions if needed
            if (window.canvas && (window.canvas.width !== width || window.canvas.height !== height)) {
                window.canvas.updateCanvasDimensions(width, height);
            }
            
            // Check if we're in low-code or no-code mode
            const mode = document.body.getAttribute('data-mode');
            
            if (mode === 'low-code') {
                // Get code from CodeMirror editor
                const code = window.getCode ? window.getCode() : '';
                
                // Client-side preview for rapid testing
                try {
                    canvas.clear();
                    window.compiler.setCanvas(canvas);
                    window.compiler.parseCode(code);
                    showToast('Preview generated!', 'success');
                } catch (error) {
                    console.error('Preview error:', error);
                    showToast('Error generating preview: ' + error.message, 'error');
                }
                
                // Send to server for official preview
                fetch('api/preview.php?size=' + canvasSize, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || ''
                    },
                    body: JSON.stringify({ code: code })
                })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        canvas.updateFromData(data.pixelData);
                    } else {
                        showToast('Server error: ' + data.error, 'error');
                    }
                })
                .catch(error => {
                    console.error('Error:', error);
                    showToast('Connection error: ' + error.message, 'error');
                });
            } else {
                // No-code mode preview
                // ...
            }
        });
    }
    
    // Submit button
    // Submit button
    const submitBtn = document.getElementById('submit-btn');
    if (submitBtn) {
        submitBtn.addEventListener('click', function() {
            const appTitle = document.getElementById('app-title');
            if (appTitle && !appTitle.value.trim()) {
                showToast('Please enter an application title', 'error');
                appTitle.focus();
                return;
            }
            
            // Show loading animation
            toggleLoader(true);
            
            // Additionally update button state as a backup UI indicator
            this.disabled = true;
            this.innerHTML = '<svg class="spinner" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" fill="none" stroke="currentColor" stroke-width="4"></circle></svg> Publishing...';
            
            const mode = document.body.getAttribute('data-mode');
            let data = {
                title: appTitle ? appTitle.value : 'Untitled App',
                mode: mode,
                executionTime: document.getElementById('execution-time')?.value || '5',
                visibility: document.getElementById('visibility')?.value || 'public',
                canvasSize: document.body.getAttribute('data-canvas-size') || '64x32'
            };
            
            if (mode === 'low-code') {
                // Get code from CodeMirror editor
                data.code = window.getCode ? window.getCode() : '';
            } else {
                // Collect no-code inputs
                data.inputs = {
                    input1: document.getElementById('input-1')?.value || '',
                    input2: document.getElementById('input-2')?.value || '',
                    input3: document.getElementById('input-3')?.value || '',
                    input4: document.getElementById('input-4')?.value || ''
                };
            }
            
            // Send to server
            fetch('api/save.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || ''
                },
                body: JSON.stringify(data)
            })
            .then(response => response.json())
            .then(data => {
                // Hide loader
                toggleLoader(false);
                
                if (data.success) {
                    showToast('Application published successfully!', 'success');
                    
                    // Reset submit button
                    submitBtn.disabled = false;
                    submitBtn.innerHTML = 'Publish Application';
                    
                    // Show success confirmation
                    showPublishSuccess(data.fileName);
                } else {
                    showToast('Error: ' + data.error, 'error');
                    submitBtn.disabled = false;
                    submitBtn.innerHTML = 'Publish Application';
                }
            })
            .catch(error => {
                // Hide loader
                toggleLoader(false);
                
                console.error('Error:', error);
                showToast('Connection error: ' + error.message, 'error');
                submitBtn.disabled = false;
                submitBtn.innerHTML = 'Publish Application';
            });
        });
    }
    
    // No-code block handling
    document.querySelectorAll('.block').forEach(block => {
        block.addEventListener('click', function() {
            const blockType = this.getAttribute('data-block-type');
            showBlockDialog(blockType);
        });
    });
    
    // Create toast notification system
    createToastContainer();
    
    // Add this to your DOMContentLoaded event listener
    const docsSearch = document.getElementById('docs-search');
    if (docsSearch) {
        docsSearch.addEventListener('input', function(e) {
            const searchTerm = e.target.value.toLowerCase();
            const helpItems = document.querySelectorAll('.help-item');
            
            helpItems.forEach(item => {
                const text = item.textContent.toLowerCase();
                if (text.includes(searchTerm)) {
                    item.style.display = 'block';
                } else {
                    item.style.display = 'none';
                }
            });
        });
    }
    
    // Add a "Show Grid" checkbox to the preview controls
    addGridControlToPreview();
});

/**
 * Adds a grid control checkbox directly to the preview controls
 */
function addGridControlToPreview() {
    const previewControls = document.querySelector('.preview-controls');
    if (!previewControls) return;
    
    // Create container div for grid control
    const gridControl = document.createElement('div');
    gridControl.className = 'grid-control';
    
    // Create checkbox
    const gridCheckbox = document.createElement('input');
    gridCheckbox.type = 'checkbox';
    gridCheckbox.id = 'show-grid';
    gridCheckbox.checked = true;
    
    // Create label
    const gridLabel = document.createElement('label');
    gridLabel.htmlFor = 'show-grid';
    gridLabel.textContent = 'Grid';
    gridLabel.style.fontSize = '12px';
    gridLabel.style.color = 'var(--text-muted)';

    
    // Add event listener
    gridCheckbox.addEventListener('change', function() {
        if (window.canvas) {
            window.canvas.toggleGrid();
        }
    });
}

/**
 * Handle copy button clicks for code snippets
 */
function handleCopyClick(e) {
    const button = e.currentTarget;
    const code = button.dataset.code;
    
    if (editor && code) {
        // Get current cursor position
        const cursor = editor.getCursor();
        // Insert code at cursor position
        editor.replaceRange(code + '\n', cursor);
        // Focus back on editor
        editor.focus();
        
        // Visual feedback
        button.innerHTML = `
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M20 6L9 17L4 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
            Copied!
        `;
        
        setTimeout(() => {
            button.innerHTML = `
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                    <path d="M8 3H5C3.89543 3 3 3.89543 3 5V19C3 20.1046 3.89543 21 5 21H19C20.1046 21 21 20.1046 21 19V16M21 9V3C21 1.89543 20.1046 1 19 1H13C11.8954 1 11 1.89543 11 3V9C11 10.1046 11.8954 11 13 11H19C20.1046 11 21 10.1046 21 9Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                </svg>
                Copy
            `;
        }, 2000);
    }
}

/**
 * Show a toast notification
 */
function showToast(message, type = 'info') {
    const container = document.getElementById('toast-container');
    if (!container) return;
    
    const toast = document.createElement('div');
    toast.className = `toast toast-${type}`;
    toast.textContent = message;
    
    container.appendChild(toast);
    
    // Trigger animation
    setTimeout(() => {
        toast.classList.add('show');
    }, 10);
    
    // Remove after delay
    setTimeout(() => {
        toast.classList.remove('show');
        setTimeout(() => {
            container.removeChild(toast);
        }, 300);
    }, 3000);
}

/**
 * Create toast notification container
 */
function createToastContainer() {
    if (document.getElementById('toast-container')) return;
    
    const container = document.createElement('div');
    container.id = 'toast-container';
    container.style.position = 'fixed';
    container.style.bottom = '20px';
    container.style.right = '20px';
    container.style.zIndex = '9999';
    document.body.appendChild(container);
    
    // Add styles
    const style = document.createElement('style');
    style.textContent = `
        .toast {
            padding: 12px 16px;
            border-radius: 6px;
            margin-top: 10px;
            color: white;
            display: flex;
            align-items: center;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
            transition: transform 0.3s ease, opacity 0.3s ease;
            transform: translateX(100%);
            opacity: 0;
        }
        .toast.show {
            transform: translateX(0);
            opacity: 1;
        }
        .toast-success {
            background: linear-gradient(to right, #10B981, #34D399);
        }
        .toast-error {
            background: linear-gradient(to right, #EF4444, #F87171);
        }
        .toast-info {
            background: linear-gradient(to right, #3B82F6, #60A5FA);
        }
        .spinner {
            animation: spin 1s linear infinite;
            width: 16px;
            height: 16px;
            margin-right: 8px;
        }
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
        .spinner circle {
            stroke-dasharray: 60, 200;
            stroke-dashoffset: 0;
            animation: dash 1.5s ease-in-out infinite;
        }
        @keyframes dash {
            0% { stroke-dasharray: 1, 200; stroke-dashoffset: 0; }
            50% { stroke-dasharray: 89, 200; stroke-dashoffset: -35px; }
            100% { stroke-dasharray: 89, 200; stroke-dashoffset: -124px; }
        }
    `;
    document.head.appendChild(style);
}

/**
 * Function to show/hide the loading animation
 */
function toggleLoader(show) {
    const loader = document.getElementById('app-loader');
    if (!loader) return;
    
    if (show) {
        loader.style.display = 'flex';
        // Reset animations by cloning the SVG
        const svg = document.getElementById('led-panel-loader');
        if (svg) {
            const newSvg = svg.cloneNode(true);
            svg.parentNode.replaceChild(newSvg, svg);
        }
    } else {
        // Hide the loader with a fade out effect
        loader.style.opacity = '1';
        loader.style.transition = 'opacity 0.5s ease';
        loader.style.opacity = '0';
        setTimeout(() => {
            loader.style.display = 'none';
            loader.style.opacity = '1';
        }, 500);
    }
}

/**
 * Handle session management
 */
function handleSessionManagement() {
    // Generate a unique session ID for this instance of the application
    function generateSessionId() {
        return 'sess_' + Math.random().toString(36).substr(2, 9) + '_' + Date.now();
    }
    
    // Get the current server session ID (from PHP)
    const serverSessionId = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '';
    
    // Get the stored client session ID
    const storedClientSessionId = localStorage.getItem('clientSessionId');
    const storedServerSessionId = localStorage.getItem('serverSessionId');
    
    // If there's no stored session ID or the server session ID has changed,
    // we're in a new session and should clear the stored code
    if (!storedClientSessionId || !storedServerSessionId || storedServerSessionId !== serverSessionId) {
        console.log('New session detected, clearing stored code');
        
        // Generate and store a new client session ID
        const newClientSessionId = generateSessionId();
        localStorage.setItem('clientSessionId', newClientSessionId);
        localStorage.setItem('serverSessionId', serverSessionId);
        
        // Clear any previously stored editor content
        localStorage.removeItem('editorContent');
    }
}

/**
 * Show block configuration dialog (for no-code mode)
 */
function showBlockDialog(blockType) {
    // For now, just show a toast with the block type
    showToast(`${blockType} block added`, 'info');
    
    // In a real implementation, this would open a modal dialog
    // for configuring the block parameters
}

/**
 * Show success modal after publishing
 */
function showPublishSuccess(fileName) {
    // Create a modal to show the success
    const modal = document.createElement('div');
    modal.style.position = 'fixed';
    modal.style.top = '0';
    modal.style.left = '0';
    modal.style.right = '0';
    modal.style.bottom = '0';
    modal.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
    modal.style.display = 'flex';
    modal.style.justifyContent = 'center';
    modal.style.alignItems = 'center';
    modal.style.zIndex = '9999';
    
    const content = document.createElement('div');
    content.style.backgroundColor = 'var(--bg-medium)';
    content.style.borderRadius = 'var(--radius-md)';
    content.style.padding = '2rem';
    content.style.maxWidth = '500px';
    content.style.textAlign = 'center';
    
    const icon = document.createElement('div');
    icon.innerHTML = `<svg width="64" height="64" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
        <circle cx="12" cy="12" r="10" stroke="#10B981" stroke-width="2"/>
        <path d="M8 12L11 15L16 9" stroke="#10B981" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
    </svg>`;
    
    const title = document.createElement('h2');
    title.textContent = 'Application Published!';
    title.style.margin = '1rem 0';
    
    const message = document.createElement('p');
    message.textContent = `Your application has been successfully published as ${fileName}. It will now be available for selection on your LED panel device.`;
    message.style.marginBottom = '1.5rem';
    message.style.color = 'var(--text-muted)';
    
    const closeButton = document.createElement('button');
    closeButton.textContent = 'Close';
    closeButton.className = 'btn btn-primary';
    closeButton.style.minWidth = '120px';
    closeButton.addEventListener('click', () => {
        document.body.removeChild(modal);
    });
    
    content.appendChild(icon);
    content.appendChild(title);
    content.appendChild(message);
    content.appendChild(closeButton);
    modal.appendChild(content);
    
    document.body.appendChild(modal);
}

function initCodeEditor() {
    console.log("Initializing CodeMirror...");
    
    // Check if we're in no-code mode and skip editor initialization if true
    if (document.body.getAttribute('data-mode') === 'no-code') {
        console.log("Skipping CodeMirror initialization in no-code mode");
        return;
    }

    const phpCodeTextarea = document.getElementById('php-code');
    if (!phpCodeTextarea) {
        console.error("❌ Textarea with ID 'php-code' not found!");
        return;
    }

    // Set default template code if no stored content
    const defaultCode = `
// This is your LED Panel App
// Write code to draw on the LED panel

// Example: Display text
drawText(0, 0, "Hello World!", "#10B981", "bitmap_5x7", "left");

// Example: Display dynamic data
// $data = getData('https://api.example.com/data', 'your-api-key');
// drawText(0, 12, $data, "#FFFFFF", "bitmap_5x7", "left");

// Example: Set individual pixels
// setPixel(10, 20, "#FF0000");
`;

    // Restore content from localStorage if available
    const savedContent = localStorage.getItem('editorContent');
    if (savedContent) {
        phpCodeTextarea.value = savedContent;
    } else {
        phpCodeTextarea.value = defaultCode;
    }

    try {
        // Initialize CodeMirror with simplified options
        editor = CodeMirror.fromTextArea(phpCodeTextarea, {
            mode: "text/x-php",  // Changed from application/x-httpd-php
            theme: "monokai",
            lineNumbers: true,
            matchBrackets: true,
            indentUnit: 4,
            tabSize: 4,
            indentWithTabs: false,
            lineWrapping: false,
            scrollbarStyle: "native",
            extraKeys: {
                "Tab": function(cm) {
                    const spaces = Array(cm.getOption("indentUnit") + 1).join(" ");
                    cm.replaceSelection(spaces);
                },
                "Enter": function(cm) {
                    cm.replaceSelection("\n");
                },
                "Ctrl-/": "toggleComment",  // Comment/uncomment with Ctrl+/
                "Cmd-/": "toggleComment",   // For Mac users
                "Ctrl-Z": "undo",
                "Cmd-Z": "undo",
                "Ctrl-Y": "redo",
                "Cmd-Y": "redo",
                "Cmd-S": function(cm) {     // Save functionality for Cmd+S (Mac)
                    // You could trigger preview or save here
                    document.getElementById('preview-btn').click();
                    return false;  // Prevent default browser save dialog
                },
                "Ctrl-S": function(cm) {    // Save functionality for Ctrl+S (Windows/Linux)
                    document.getElementById('preview-btn').click();
                    return false;  // Prevent default browser save dialog
                }
            }
        });

        console.log("✅ CodeMirror initialized successfully!");
    } catch (error) {
        console.error("❌ CodeMirror initialization failed:", error);
    }

    // Set editor height and ensure refresh
    editor.setSize(null, "100%");
    setTimeout(() => {
        editor.refresh();
    }, 100);

    // Save content to localStorage on changes
    editor.on("change", function() {
        localStorage.setItem('editorContent', editor.getValue());
        // validateSyntax(editor);
    });

    // Only initialize validator if it exists
    if (typeof initPHPValidator === 'function') {
        initPHPValidator(editor); // After initializing the CodeMirror editor
    }

    // Return the code when needed
    window.getCode = function() {
        return editor.getValue();
    };
}

/**
 * Setup resizable editor and preview
 * Allows users to dynamically adjust the ratio between code editor and preview
 * Maintains proper aspect ratio for the canvas during resize operations
 */
function setupResizableEditorPreview() {
    const editorContainer = document.querySelector('.editor-container');
    const previewSection = document.querySelector('.preview-section');
    const mainContent = document.querySelector('.main-content');
    
    if (!editorContainer || !previewSection || !mainContent) return;
    
    // Create resize handle
    const resizeHandle = document.createElement('div');
    resizeHandle.className = 'resize-handle';
    editorContainer.appendChild(resizeHandle);
    
    let isResizing = false;
    let startY = 0;
    let startEditorHeight = 0;
    let startPreviewHeight = 0;
    
    // Set initial heights based on 65/35 split (adjusted for better default view)
    const setInitialHeights = () => {
        const totalHeight = mainContent.offsetHeight;
        const editorHeight = Math.floor(totalHeight * 0.65); // 65% for editor
        const previewHeight = totalHeight - editorHeight; // Remaining for preview
        
        editorContainer.style.height = `${editorHeight}px`;
        previewSection.style.height = `${previewHeight}px`;
        
        // Refresh editor and canvas
        if (window.editor) {
            window.editor.refresh();
        }
        if (window.canvas) {
            window.canvas.handleResize();
        }
    };
    
    // Initial setup
    setInitialHeights();
    
    resizeHandle.addEventListener('mousedown', (e) => {
        isResizing = true;
        startY = e.clientY;
        startEditorHeight = editorContainer.offsetHeight;
        startPreviewHeight = previewSection.offsetHeight;
        document.body.style.cursor = 'ns-resize';
    });
    
    document.addEventListener('mousemove', (e) => {
        if (!isResizing) return;
        
        const totalHeight = mainContent.offsetHeight;
        const deltaY = e.clientY - startY;
        
        // Calculate new heights
        let newEditorHeight = startEditorHeight + deltaY;
        let newPreviewHeight = startPreviewHeight - deltaY;
        
        // Adjusted constraints
        const minPreviewHeight = Math.max(200, totalHeight * 0.25); // Minimum 200px or 25%
        const maxPreviewHeight = Math.min(totalHeight * 0.5, totalHeight - 300); // Max 50% and ensure editor has space
        const minEditorHeight = totalHeight - maxPreviewHeight;
        const maxEditorHeight = totalHeight - minPreviewHeight;
        
        // Apply constraints with buffer for bottom of screen
        if (newEditorHeight < minEditorHeight) {
            newEditorHeight = minEditorHeight;
            newPreviewHeight = totalHeight - newEditorHeight;
        } else if (newEditorHeight > maxEditorHeight) {
            newEditorHeight = maxEditorHeight;
            newPreviewHeight = totalHeight - newEditorHeight;
        }
        
        // Ensure preview controls are always visible
        const previewControlsHeight = 100; // Approximate height of preview controls
        if (newPreviewHeight < previewControlsHeight) {
            newPreviewHeight = previewControlsHeight;
            newEditorHeight = totalHeight - previewControlsHeight;
        }
        
        // Update heights
        editorContainer.style.height = `${newEditorHeight}px`;
        previewSection.style.height = `${newPreviewHeight}px`;
        
        // Refresh canvas to maintain proper scaling
        if (window.canvas) {
            window.canvas.handleResize();
        }
    });
    
    document.addEventListener('mouseup', () => {
        isResizing = false;
        document.body.style.cursor = '';
    });
    
    // Handle window resize
    window.addEventListener('resize', () => {
        setInitialHeights();
    });
}

/**
 * Simplified error validator for GLANCE LED Panel code
 * - Doesn't require PHP tags
 * - Focuses on key issues like missing semicolons, mismatched brackets, etc.
 * - Adds clear visual indicators for errors
 */
function validateSyntax(editor) {
    const value = editor.getValue();
    const errors = [];
    
    // Clear previous markers
    if (!editor.errorMarkers) {
        editor.errorMarkers = [];
    }
    
    editor.errorMarkers.forEach(marker => marker.clear());
    editor.errorMarkers = [];
    
    try {
        // Analyze code line by line
        const lines = value.split('\n');
        
        // Keep track of brackets
        let openBrackets = 0, closeBrackets = 0;
        let openCurly = 0, closeCurly = 0;
        let openParens = 0, closeParens = 0;
        
        // Analyze each line
        for (let i = 0; i < lines.length; i++) {
            const line = lines[i].trim();
            
            // Skip empty lines and comments
            if (!line || line.startsWith('//') || line.startsWith('#') || line.startsWith('/*')) {
                continue;
            }
            
            // Check for semicolons on statements (but not control structures)
            if (!line.endsWith(';') && 
                !line.endsWith('{') && 
                !line.endsWith('}') && 
                !line.endsWith(':') &&
                !line.match(/^(if|for|foreach|while|function|class|switch)\s*\(/) &&
                !line.match(/^else(\s*if\s*\(|\s*{)/) &&
                (line.includes('=') || line.match(/^\$[a-zA-Z0-9_]+/) || 
                 line.includes('echo') || line.includes('print') || 
                 line.includes('drawText') || line.includes('getData') || 
                 line.includes('setPixel') || line.includes('return'))) {
                
                // Create a marker for missing semicolon
                const marker = editor.markText(
                    {line: i, ch: 0},
                    {line: i, ch: lines[i].length},
                    {
                        className: "missing-semicolon",
                        title: "Missing semicolon (;) at end of line",
                        css: "background-color: rgba(239, 68, 68, 0.2); border-bottom: 2px solid #EF4444;"
                    }
                );
                
                editor.errorMarkers.push(marker);
                errors.push({
                    line: i, 
                    message: `Line ${i+1}: Missing semicolon (;)`
                });
            }
            
            // Check drawText function parameters
            if (line.includes('drawText(')) {
                const match = line.match(/drawText\s*\(([^)]*)\)/);
                if (match) {
                    const params = match[1].split(',').map(p => p.trim());
                    
                    // Check parameter count - drawText requires at least 3 parameters
                    if (params.length < 3 || (params.length === 1 && !params[0])) {
                        const marker = editor.markText(
                            {line: i, ch: line.indexOf('drawText')},
                            {line: i, ch: line.indexOf(')') + 1},
                            {
                                className: "parameter-error",
                                title: "drawText requires at least 3 parameters (x, y, text)",
                                css: "background-color: rgba(239, 68, 68, 0.2); text-decoration: wavy underline #EF4444;"
                            }
                        );
                        editor.errorMarkers.push(marker);
                        errors.push({
                            line: i, 
                            message: `Line ${i+1}: drawText requires at least 3 parameters (x, y, text)`
                        });
                    }
                    // Check if the required color parameter is missing
                    else if (params.length < 4) {
                        const marker = editor.markText(
                            {line: i, ch: line.indexOf('drawText')},
                            {line: i, ch: line.indexOf(')') + 1},
                            {
                                className: "parameter-error",
                                title: "Missing color parameter (should be 4th parameter)",
                                css: "background-color: rgba(239, 68, 68, 0.2); text-decoration: wavy underline #EF4444;"
                            }
                        );
                        editor.errorMarkers.push(marker);
                        errors.push({
                            line: i, 
                            message: `Line ${i+1}: Missing color parameter in drawText (should be 4th parameter)`
                        });
                    }
                    
                    // Check text parameter is quoted (3rd parameter)
                    if (params.length >= 3) {
                        const textParam = params[2];
                        if (!textParam.startsWith("'") && !textParam.startsWith('"') && !textParam.startsWith('$')) {
                            // Find position of third parameter
                            let pos = line.indexOf(',');
                            if (pos !== -1) {
                                pos = line.indexOf(',', pos + 1);
                                if (pos !== -1) {
                                    const paramStart = line.indexOf(textParam, pos);
                                    const paramEnd = paramStart + textParam.length;
                                    
                                    const marker = editor.markText(
                                        {line: i, ch: paramStart},
                                        {line: i, ch: paramEnd},
                                        {
                                            className: "string-error",
                                            title: "Text should be in quotes or a variable",
                                            css: "background-color: rgba(239, 68, 68, 0.2); border-bottom: 2px solid #EF4444;"
                                        }
                                    );
                                    editor.errorMarkers.push(marker);
                                    errors.push({
                                        line: i, 
                                        message: `Line ${i+1}: Text parameter should be in quotes or a variable`
                                    });
                                }
                            }
                        }
                    }
                }
            }
            
            // Check for imbalanced brackets/parentheses in the line
            let lineOpenParens = 0, lineCloseParens = 0;
            let lineOpenBrackets = 0, lineCloseBrackets = 0;
            let lineOpenCurly = 0, lineCloseCurly = 0;
            let inString = false, stringChar = '';
            
            for (let j = 0; j < line.length; j++) {
                const char = line.charAt(j);
                
                // Handle strings to ignore brackets within quotes
                if ((char === '"' || char === "'") && (j === 0 || line.charAt(j-1) !== '\\')) {
                    if (!inString) {
                        inString = true;
                        stringChar = char;
                    } else if (char === stringChar) {
                        inString = false;
                    }
                    continue;
                }
                
                if (inString) continue;
                
                // Count brackets
                switch(char) {
                    case '(': lineOpenParens++; openParens++; break;
                    case ')': lineCloseParens++; closeParens++; break;
                    case '[': lineOpenBrackets++; openBrackets++; break;
                    case ']': lineCloseBrackets++; closeBrackets++; break;
                    case '{': lineOpenCurly++; openCurly++; break;
                    case '}': lineCloseCurly++; closeCurly++; break;
                }
            }
            
            // Check for unmatched brackets in this line
            if (lineOpenParens < lineCloseParens) {
                const marker = editor.markText(
                    {line: i, ch: 0},
                    {line: i, ch: lines[i].length},
                    {
                        className: "bracket-error",
                        title: "Too many closing parentheses - check for missing opening parenthesis",
                        css: "background-color: rgba(239, 68, 68, 0.2); border-bottom: 2px solid #EF4444;"
                    }
                );
                editor.errorMarkers.push(marker);
                errors.push({
                    line: i, 
                    message: `Line ${i+1}: Too many closing parentheses`
                });
            }
            
            if (lineOpenBrackets < lineCloseBrackets) {
                const marker = editor.markText(
                    {line: i, ch: 0},
                    {line: i, ch: lines[i].length},
                    {
                        className: "bracket-error",
                        title: "Too many closing brackets - check for missing opening bracket",
                        css: "background-color: rgba(239, 68, 68, 0.2); border-bottom: 2px solid #EF4444;"
                    }
                );
                editor.errorMarkers.push(marker);
                errors.push({
                    line: i, 
                    message: `Line ${i+1}: Too many closing brackets`
                });
            }
            
            if (lineOpenCurly < lineCloseCurly) {
                const marker = editor.markText(
                    {line: i, ch: 0},
                    {line: i, ch: lines[i].length},
                    {
                        className: "bracket-error",
                        title: "Too many closing braces - check for missing opening brace",
                        css: "background-color: rgba(239, 68, 68, 0.2); border-bottom: 2px solid #EF4444;"
                    }
                );
                editor.errorMarkers.push(marker);
                errors.push({
                    line: i, 
                    message: `Line ${i+1}: Too many closing braces`
                });
            }
            
            // Check hex color format for color values in the line
            const colorRegex = /#[a-fA-F0-9]{6}|#[a-fA-F0-9]{3}/g;
            const colorMatches = line.match(colorRegex);
            
            if (colorMatches) {
                colorMatches.forEach(color => {
                    if (color.length !== 4 && color.length !== 7) {
                        const colorStart = line.indexOf(color);
                        const colorEnd = colorStart + color.length;
                        
                        const marker = editor.markText(
                            {line: i, ch: colorStart},
                            {line: i, ch: colorEnd},
                            {
                                className: "color-error",
                                title: "Invalid hex color format. Use #RGB or #RRGGBB",
                                css: "background-color: rgba(239, 68, 68, 0.2); border-bottom: 2px solid #EF4444;"
                            }
                        );
                        editor.errorMarkers.push(marker);
                        errors.push({
                            line: i, 
                            message: `Line ${i+1}: Invalid hex color format`
                        });
                    }
                });
            }
        }
        
        // Check for overall balance issues
        let hasBalanceErrors = false;
        
        if (openParens > closeParens) {
            hasBalanceErrors = true;
            errors.push({
                message: `Missing ${openParens - closeParens} closing parenthesis ")"`,
            });
        } else if (closeParens > openParens) {
            hasBalanceErrors = true;
            errors.push({
                message: `Too many closing parentheses - ${closeParens - openParens} extra ")"`,
            });
        }
        
        if (openBrackets > closeBrackets) {
            hasBalanceErrors = true;
            errors.push({
                message: `Missing ${openBrackets - closeBrackets} closing bracket "]"`,
            });
        } else if (closeBrackets > openBrackets) {
            hasBalanceErrors = true;
            errors.push({
                message: `Too many closing brackets - ${closeBrackets - openBrackets} extra "]"`,
            });
        }
        
        if (openCurly > closeCurly) {
            hasBalanceErrors = true;
            errors.push({
                message: `Missing ${openCurly - closeCurly} closing brace "}"`,
            });
        } else if (closeCurly > openCurly) {
            hasBalanceErrors = true;
            errors.push({
                message: `Too many closing braces - ${closeCurly - openCurly} extra "}"`,
            });
        }
        
        // Create an error badge for any errors
        if (errors.length > 0) {
            // Find or create error badge
            let errorBadge = document.querySelector('.error-badge');
            if (!errorBadge) {
                errorBadge = document.createElement('div');
                errorBadge.className = 'error-badge';
                errorBadge.innerHTML = '⚠️';
                errorBadge.style.position = 'absolute';
                errorBadge.style.top = '10px';
                errorBadge.style.right = '10px';
                errorBadge.style.backgroundColor = 'rgba(239, 68, 68, 0.9)';
                errorBadge.style.color = 'white';
                errorBadge.style.padding = '5px 10px';
                errorBadge.style.borderRadius = '4px';
                errorBadge.style.zIndex = '999';
                errorBadge.style.cursor = 'pointer';
                
                // Add to editor wrapper
                const editorWrapper = editor.getWrapperElement();
                editorWrapper.style.position = 'relative';
                editorWrapper.appendChild(errorBadge);
                
                // Create tooltip for the badge
                const tooltip = document.createElement('div');
                tooltip.className = 'error-tooltip';
                tooltip.style.position = 'absolute';
                tooltip.style.top = '40px';
                tooltip.style.right = '10px';
                tooltip.style.backgroundColor = 'rgba(30, 41, 59, 0.95)';
                tooltip.style.color = 'white';
                tooltip.style.padding = '10px';
                tooltip.style.borderRadius = '4px';
                tooltip.style.zIndex = '1000';
                tooltip.style.maxWidth = '300px';
                tooltip.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.3)';
                tooltip.style.fontSize = '12px';
                tooltip.style.display = 'none';
                
                editorWrapper.appendChild(tooltip);
                
                // Toggle tooltip on click
                errorBadge.addEventListener('click', () => {
                    tooltip.style.display = tooltip.style.display === 'none' ? 'block' : 'none';
                });
                
                // Hide tooltip when clicking elsewhere
                document.addEventListener('click', (e) => {
                    if (!errorBadge.contains(e.target) && !tooltip.contains(e.target)) {
                        tooltip.style.display = 'none';
                    }
                });
            }
            
            // Find or update tooltip
            const tooltip = document.querySelector('.error-tooltip');
            if (tooltip) {
                tooltip.innerHTML = `
                    <strong>Code Issues:</strong>
                    <ul style="margin-top: 5px; padding-left: 20px;">
                        ${errors.map(e => `<li>${e.message || e}</li>`).join('')}
                    </ul>
                `;
            }
        } else {
            // Remove error badge if no errors
            const errorBadge = document.querySelector('.error-badge');
            if (errorBadge) {
                errorBadge.remove();
            }
            
            const tooltip = document.querySelector('.error-tooltip');
            if (tooltip) {
                tooltip.remove();
            }
        }
        
    } catch (e) {
        console.error("Validation error:", e);
        errors.push({message: e.message});
    }
    
    // Display errors in the error panel if it exists
    const errorDisplay = document.getElementById('code-errors');
    if (errorDisplay) {
        errorDisplay.innerHTML = '';
        if (errors.length > 0) {
            errorDisplay.style.display = 'block';
            const ul = document.createElement('ul');
            errors.forEach(error => {
                const li = document.createElement('li');
                li.textContent = error.message || error;
                ul.appendChild(li);
            });
            errorDisplay.appendChild(ul);
        } else {
            errorDisplay.style.display = 'none';
        }
    }
    
    return errors.length === 0;
}

// Inject necessary styles for error highlighting
function injectErrorStyles() {
    // Check if styles already exist
    if (document.getElementById('syntax-validator-styles')) return;
    
    const styleEl = document.createElement('style');
    styleEl.id = 'syntax-validator-styles';
    styleEl.textContent = `
        .syntax-error {
            text-decoration: wavy underline #EF4444;
            position: relative;
        }
        
        .CodeMirror-gutters {
            background-color: var(--bg-medium) !important;
            border-right: 1px solid var(--border-color) !important;
        }
        
        .line-error-marker {
            color: #EF4444;
            font-weight: bold;
            cursor: pointer;
        }
        
        .syntax-error-tooltip {
            position: absolute;
            z-index: 1000;
            background-color: #1F2937;
            border: 1px solid #4B5563;
            border-radius: 4px;
            padding: 8px;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
            font-size: 12px;
            max-width: 280px;
            color: white;
        }
        
        .error-icon {
            display: inline-block;
            margin-right: 8px;
            vertical-align: middle;
        }
        
        .general-warning {
            cursor: pointer;
        }
        
        .error-messages ul {
            margin: 5px 0 0 0;
            padding-left: 20px;
        }
        
        /* Make tooltips appear faster on hover */
        .CodeMirror-line .syntax-error,
        .CodeMirror-line .parameter-error,
        .CodeMirror-line .string-error,
        .CodeMirror-line .bracket-error,
        .CodeMirror-line .color-error,
        .CodeMirror-line .missing-semicolon {
            position: relative;
        }
        
        .CodeMirror-line .syntax-error:hover::after,
        .CodeMirror-line .parameter-error:hover::after,
        .CodeMirror-line .string-error:hover::after,
        .CodeMirror-line .bracket-error:hover::after,
        .CodeMirror-line .color-error:hover::after,
        .CodeMirror-line .missing-semicolon:hover::after {
            content: attr(title);
            position: absolute;
            left: 0;
            top: 100%;
            z-index: 1000;
            background-color: rgba(30, 41, 59, 0.95);
            color: white;
            padding: 6px 10px;
            border-radius: 4px;
            font-family: 'Inter', -apple-system, sans-serif;
            font-size: 12px;
            white-space: nowrap;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
            pointer-events: none;
        }

        .CodeMirror-line:nth-last-child(-n+3) .syntax-error:hover::after,
        .CodeMirror-line:nth-last-child(-n+3) .parameter-error:hover::after,
        .CodeMirror-line:nth-last-child(-n+3) .string-error:hover::after,
        .CodeMirror-line:nth-last-child(-n+3) .bracket-error:hover::after,
        .CodeMirror-line:nth-last-child(-n+3) .color-error:hover::after,
        .CodeMirror-line:nth-last-child(-n+3) .missing-semicolon:hover::after {
            top: auto;
            bottom: 100%;
        }
    `;
    
    document.head.appendChild(styleEl);
}

// Initialize validator
function initPHPValidator(editor) {
    // Inject styles
    injectErrorStyles();
    
    // Initialize error markers array
    editor.errorMarkers = [];
    
    // Set up validation on change with debounce
    let validateTimeout;
    editor.on('change', function() {
        clearTimeout(validateTimeout);
        validateTimeout = setTimeout(() => {
            validateSyntax(editor);
        }, 500); // Wait 500ms after typing stops
    });
    
    // Initial validation
    validateSyntax(editor);
    
    return {
        validate: () => validateSyntax(editor)
    };
}