const vscode = require('vscode');
const fs = require('fs');
const path = require('path');

/**
 * Live UI Preview Panel
 * 
 * Shows a visual preview of HTML/CSS/JS projects that users build.
 * Renders the actual UI in an iframe within VS Code.
 * 
 * Features:
 * - Live rendering of HTML/CSS/JS in a webview panel
 * - Device simulation (desktop, tablet, mobile)
 * - Auto-refresh on file changes
 * - Fullscreen mode
 * - Screenshot capture
 */
class LiveUIPreview {
    constructor(context) {
        this._context = context;
        this._panel = null;
        this._currentProject = null;
        this._deviceMode = 'desktop';
        this._fileWatcher = null;
    }

    /**
     * Show live UI preview for a project
     * @param {string} htmlFilePath - Path to the main HTML file
     * @param {string} workspacePath - Root workspace path
     * @param {object} projectFiles - Optional: {html, css, js} content directly
     */
    async showPreview(htmlFilePath, workspacePath, projectFiles = null) {
        console.log('🖼️ Opening Live UI Preview for:', htmlFilePath || 'inline content');

        // Create or reveal the panel
        if (this._panel) {
            this._panel.reveal(vscode.ViewColumn.Beside);
        } else {
            this._panel = vscode.window.createWebviewPanel(
                'vigthoria-live-preview',
                '🖼️ Live UI Preview',
                vscode.ViewColumn.Beside,
                {
                    enableScripts: true,
                    retainContextWhenHidden: true,
                    localResourceRoots: workspacePath 
                        ? [vscode.Uri.file(workspacePath)]
                        : []
                }
            );

            // Handle panel disposal
            this._panel.onDidDispose(() => {
                this._panel = null;
                if (this._fileWatcher) {
                    this._fileWatcher.dispose();
                    this._fileWatcher = null;
                }
            });

            // Handle messages from the preview panel
            this._panel.webview.onDidReceiveMessage(async (message) => {
                switch (message.type) {
                    case 'setDevice':
                        this._deviceMode = message.device;
                        break;
                    case 'refresh':
                        await this.refreshPreview();
                        break;
                    case 'openExternal':
                        if (htmlFilePath) {
                            vscode.env.openExternal(vscode.Uri.file(htmlFilePath));
                        }
                        break;
                    case 'fullscreen':
                        this.toggleFullscreen();
                        break;
                }
            });
        }

        this._currentProject = {
            htmlFilePath,
            workspacePath,
            projectFiles
        };

        // Set up file watcher for auto-refresh
        if (htmlFilePath && workspacePath) {
            this.setupFileWatcher(workspacePath);
        }

        // Generate and set HTML content
        await this.updatePreviewContent();
    }

    /**
     * Generate preview content from project files or inline content
     */
    async updatePreviewContent() {
        let htmlContent = '';
        let cssContent = '';
        let jsContent = '';

        if (this._currentProject.projectFiles) {
            // Use inline content directly
            htmlContent = this._currentProject.projectFiles.html || '';
            cssContent = this._currentProject.projectFiles.css || '';
            jsContent = this._currentProject.projectFiles.js || '';
        } else if (this._currentProject.htmlFilePath) {
            // Read from file
            try {
                htmlContent = fs.readFileSync(this._currentProject.htmlFilePath, 'utf8');
                
                // Try to find associated CSS and JS files
                const dir = path.dirname(this._currentProject.htmlFilePath);
                const baseName = path.basename(this._currentProject.htmlFilePath, '.html');
                
                const cssPath = path.join(dir, 'style.css');
                const cssPath2 = path.join(dir, `${baseName}.css`);
                const jsPath = path.join(dir, 'script.js');
                const jsPath2 = path.join(dir, `${baseName}.js`);
                const jsPath3 = path.join(dir, 'calculator.js');
                const jsPath4 = path.join(dir, 'app.js');
                
                if (fs.existsSync(cssPath)) cssContent = fs.readFileSync(cssPath, 'utf8');
                else if (fs.existsSync(cssPath2)) cssContent = fs.readFileSync(cssPath2, 'utf8');
                
                if (fs.existsSync(jsPath)) jsContent = fs.readFileSync(jsPath, 'utf8');
                else if (fs.existsSync(jsPath2)) jsContent = fs.readFileSync(jsPath2, 'utf8');
                else if (fs.existsSync(jsPath3)) jsContent = fs.readFileSync(jsPath3, 'utf8');
                else if (fs.existsSync(jsPath4)) jsContent = fs.readFileSync(jsPath4, 'utf8');
                
            } catch (error) {
                console.error('Error reading project files:', error);
                htmlContent = `<h1>Error loading preview</h1><p>${error.message}</p>`;
            }
        }

        // Build the preview HTML
        const previewHtml = this.buildPreviewHtml(htmlContent, cssContent, jsContent);
        this._panel.webview.html = previewHtml;
    }

    /**
     * Build the complete preview panel HTML with controls and iframe
     */
    buildPreviewHtml(htmlContent, cssContent, jsContent) {
        // Prepare the iframe content by combining HTML, CSS, JS
        // If HTML doesn't include style/script tags, inject them
        let combinedHtml = htmlContent;
        
        // Check if we need to inject CSS
        if (cssContent && !htmlContent.includes('<style') && !htmlContent.includes(`href="style.css"`)) {
            combinedHtml = combinedHtml.replace('</head>', `<style>\n${cssContent}\n</style>\n</head>`);
        }
        
        // Check if we need to inject JS
        if (jsContent && !htmlContent.includes('<script') && !htmlContent.includes(`src="script.js"`) && !htmlContent.includes(`src="calculator.js"`)) {
            combinedHtml = combinedHtml.replace('</body>', `<script>\n${jsContent}\n</script>\n</body>`);
        }

        // Escape the combined HTML for embedding in srcdoc
        const escapedHtml = combinedHtml
            .replace(/&/g, '&amp;')
            .replace(/"/g, '&quot;');

        const deviceWidths = {
            mobile: '375px',
            tablet: '768px',
            desktop: '100%'
        };

        return `<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Live UI Preview - Vigthoria</title>
    <style>
        * { box-sizing: border-box; margin: 0; padding: 0; }
        
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: #1e1e1e;
            color: #fff;
            height: 100vh;
            display: flex;
            flex-direction: column;
            overflow: hidden;
        }
        
        .preview-toolbar {
            background: #2d2d2d;
            border-bottom: 1px solid #404040;
            padding: 8px 16px;
            display: flex;
            align-items: center;
            gap: 12px;
            flex-shrink: 0;
        }
        
        .toolbar-title {
            font-size: 14px;
            font-weight: 600;
            color: #3b82f6;
            display: flex;
            align-items: center;
            gap: 8px;
        }
        
        .toolbar-title span {
            font-size: 18px;
        }
        
        .device-selector {
            display: flex;
            gap: 4px;
            margin-left: auto;
        }
        
        .device-btn {
            background: transparent;
            border: 1px solid #404040;
            border-radius: 6px;
            padding: 6px 12px;
            color: #888;
            cursor: pointer;
            font-size: 12px;
            transition: all 0.2s;
        }
        
        .device-btn:hover {
            border-color: #3b82f6;
            color: #3b82f6;
        }
        
        .device-btn.active {
            background: #3b82f6;
            border-color: #3b82f6;
            color: #fff;
        }
        
        .toolbar-actions {
            display: flex;
            gap: 8px;
        }
        
        .action-btn {
            background: #404040;
            border: none;
            border-radius: 6px;
            padding: 6px 12px;
            color: #fff;
            cursor: pointer;
            font-size: 12px;
            transition: all 0.2s;
            display: flex;
            align-items: center;
            gap: 6px;
        }
        
        .action-btn:hover {
            background: #505050;
        }
        
        .action-btn.primary {
            background: #3b82f6;
        }
        
        .action-btn.primary:hover {
            background: #2563eb;
        }
        
        .preview-container {
            flex: 1;
            display: flex;
            justify-content: center;
            align-items: flex-start;
            padding: 20px;
            background: #121212;
            overflow: auto;
        }
        
        .preview-frame-wrapper {
            background: #fff;
            border-radius: 8px;
            box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
            overflow: hidden;
            transition: width 0.3s ease;
        }
        
        .preview-frame-wrapper.mobile {
            width: 375px;
            border-radius: 20px;
            border: 8px solid #1a1a1a;
        }
        
        .preview-frame-wrapper.tablet {
            width: 768px;
            border-radius: 12px;
            border: 6px solid #1a1a1a;
        }
        
        .preview-frame-wrapper.desktop {
            width: 100%;
            max-width: calc(100vw - 80px);
            border-radius: 8px;
        }
        
        .preview-iframe {
            width: 100%;
            height: calc(100vh - 140px);
            border: none;
            background: #fff;
        }
        
        .preview-status {
            background: #252526;
            border-top: 1px solid #404040;
            padding: 6px 16px;
            font-size: 11px;
            color: #888;
            display: flex;
            justify-content: space-between;
            flex-shrink: 0;
        }
        
        .status-item {
            display: flex;
            align-items: center;
            gap: 6px;
        }
        
        .status-dot {
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background: #22c55e;
        }
        
        .empty-state {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 100%;
            color: #666;
            text-align: center;
            padding: 40px;
        }
        
        .empty-state h2 {
            font-size: 24px;
            margin-bottom: 12px;
            color: #888;
        }
        
        .empty-state p {
            font-size: 14px;
            max-width: 400px;
            line-height: 1.6;
        }
    </style>
</head>
<body>
    <div class="preview-toolbar">
        <div class="toolbar-title">
            <span>🖼️</span>
            Live UI Preview
        </div>
        
        <div class="device-selector">
            <button class="device-btn ${this._deviceMode === 'mobile' ? 'active' : ''}" onclick="setDevice('mobile')">
                📱 Mobile
            </button>
            <button class="device-btn ${this._deviceMode === 'tablet' ? 'active' : ''}" onclick="setDevice('tablet')">
                📟 Tablet
            </button>
            <button class="device-btn ${this._deviceMode === 'desktop' ? 'active' : ''}" onclick="setDevice('desktop')">
                🖥️ Desktop
            </button>
        </div>
        
        <div class="toolbar-actions">
            <button class="action-btn" onclick="refreshPreview()">
                🔄 Refresh
            </button>
            <button class="action-btn" onclick="openExternal()">
                🌐 Open in Browser
            </button>
        </div>
    </div>
    
    <div class="preview-container">
        <div class="preview-frame-wrapper ${this._deviceMode}" id="frameWrapper">
            ${htmlContent ? `
                <iframe 
                    class="preview-iframe" 
                    id="previewFrame"
                    sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-modals"
                    srcdoc="${escapedHtml}"
                ></iframe>
            ` : `
                <div class="empty-state">
                    <h2>🖼️ No Preview Available</h2>
                    <p>Build a project using BUILD mode to see a live preview of your HTML, CSS, and JavaScript here.</p>
                </div>
            `}
        </div>
    </div>
    
    <div class="preview-status">
        <div class="status-item">
            <span class="status-dot"></span>
            Live Preview Active
        </div>
        <div class="status-item">
            Device: ${this._deviceMode.charAt(0).toUpperCase() + this._deviceMode.slice(1)} | 
            ${this._currentProject?.htmlFilePath ? path.basename(this._currentProject.htmlFilePath) : 'Inline Preview'}
        </div>
    </div>
    
    <script>
        const vscode = acquireVsCodeApi();
        
        function setDevice(device) {
            // Update button states
            document.querySelectorAll('.device-btn').forEach(btn => {
                btn.classList.remove('active');
            });
            event.target.classList.add('active');
            
            // Update frame wrapper class
            const wrapper = document.getElementById('frameWrapper');
            wrapper.className = 'preview-frame-wrapper ' + device;
            
            // Notify extension
            vscode.postMessage({ type: 'setDevice', device: device });
        }
        
        function refreshPreview() {
            vscode.postMessage({ type: 'refresh' });
        }
        
        function openExternal() {
            vscode.postMessage({ type: 'openExternal' });
        }
        
        // Handle iframe errors
        const iframe = document.getElementById('previewFrame');
        if (iframe) {
            iframe.onerror = function() {
                console.error('Iframe loading error');
            };
        }
    </script>
</body>
</html>`;
    }

    /**
     * Set up file watcher for auto-refresh
     */
    setupFileWatcher(workspacePath) {
        if (this._fileWatcher) {
            this._fileWatcher.dispose();
        }

        const pattern = new vscode.RelativePattern(
            vscode.Uri.file(workspacePath),
            '**/*.{html,css,js}'
        );

        this._fileWatcher = vscode.workspace.createFileSystemWatcher(pattern);
        
        this._fileWatcher.onDidChange(() => {
            console.log('📁 File changed, refreshing preview...');
            this.refreshPreview();
        });

        this._fileWatcher.onDidCreate(() => {
            console.log('📁 File created, refreshing preview...');
            this.refreshPreview();
        });
    }

    /**
     * Refresh the preview
     */
    async refreshPreview() {
        if (this._panel && this._currentProject) {
            await this.updatePreviewContent();
            console.log('🔄 Preview refreshed');
        }
    }

    /**
     * Show preview directly from HTML/CSS/JS content (no files)
     */
    async showInlinePreview(html, css, js, title = 'Generated Project') {
        await this.showPreview(null, null, { html, css, js });
        if (this._panel) {
            this._panel.title = `🖼️ ${title}`;
        }
    }

    /**
     * Dispose the preview panel
     */
    dispose() {
        if (this._panel) {
            this._panel.dispose();
            this._panel = null;
        }
        if (this._fileWatcher) {
            this._fileWatcher.dispose();
            this._fileWatcher = null;
        }
    }
}

// Singleton instance
let previewInstance = null;

/**
 * Get or create the Live UI Preview instance
 */
function getLiveUIPreview(context) {
    if (!previewInstance) {
        previewInstance = new LiveUIPreview(context);
    }
    return previewInstance;
}

module.exports = {
    LiveUIPreview,
    getLiveUIPreview
};
