/**
 * Vigthoria Inline Completion Provider (Ghost Text / Tab Completion)
 * 
 * This is the #1 killer feature — like Cursor Tab / Copilot Ghost Text.
 * Provides real-time AI-powered code suggestions as the user types.
 * 
 * Architecture:
 * - Uses VS Code's InlineCompletionItemProvider API
 * - Debounced requests to avoid flooding the API
 * - Caches completions for fast re-display
 * - Context-aware: reads surrounding code, imports, file type
 * - Multi-line completions with smart truncation
 */

const vscode = require('vscode');
const { CONFIG } = require('../utils/config');

class VigthoriInlineCompletionProvider {
    constructor() {
        this.apiUrl = CONFIG.server.modelRouterUrl || 'https://coder.vigthoria.io/api/model-router';
        this.debounceTimer = null;
        this.debounceMs = 300;
        this.cache = new Map();
        this.cacheMaxSize = 200;
        this.cacheTTL = 60000; // 1 minute
        this.enabled = true;
        this.lastRequestId = 0;
        this.pendingRequest = null;
        this.statusBarItem = null;
        this.totalCompletions = 0;
        this.totalAccepted = 0;
        this._triggerCharacters = null;
        
        // FIM (Fill-in-the-Middle) support
        this.fimEnabled = true;
        
        console.log('[INLINE-COMPLETION] ✨ Provider created');
    }

    /**
     * Register with VS Code
     */
    register(context) {
        // Register the inline completion provider for ALL languages
        const provider = vscode.languages.registerInlineCompletionItemProvider(
            { pattern: '**' },  // All files
            this
        );
        context.subscriptions.push(provider);

        // Status bar indicator
        this.statusBarItem = vscode.window.createStatusBarItem(
            vscode.StatusBarAlignment.Right, 99
        );
        this.statusBarItem.text = '$(sparkle) Vigthoria';
        this.statusBarItem.tooltip = 'Vigthoria AI Completion Active';
        this.statusBarItem.command = 'vigthoria.toggleInlineCompletion';
        this.statusBarItem.show();
        context.subscriptions.push(this.statusBarItem);

        // Toggle command
        context.subscriptions.push(
            vscode.commands.registerCommand('vigthoria.toggleInlineCompletion', () => {
                this.enabled = !this.enabled;
                this.statusBarItem.text = this.enabled 
                    ? '$(sparkle) Vigthoria' 
                    : '$(circle-slash) Vigthoria';
                this.statusBarItem.tooltip = this.enabled
                    ? 'Vigthoria AI Completion Active (click to disable)'
                    : 'Vigthoria AI Completion Disabled (click to enable)';
                vscode.window.showInformationMessage(
                    `Vigthoria AI Completion ${this.enabled ? 'enabled' : 'disabled'}`
                );
            })
        );

        // Track accepted completions
        context.subscriptions.push(
            vscode.commands.registerCommand('vigthoria.acceptedCompletion', () => {
                this.totalAccepted++;
            })
        );

        console.log('[INLINE-COMPLETION] ✅ Registered for all languages');
    }

    /**
     * Main provider method — called by VS Code when it wants completions
     */
    async provideInlineCompletionItems(document, position, context, token) {
        if (!this.enabled) return [];

        // Don't complete in comments or strings for performance
        // (can be made configurable later)
        
        const requestId = ++this.lastRequestId;
        
        try {
            // Build context from the document
            const completionContext = this._buildContext(document, position);
            
            // Skip if line is empty and we're at start (no context)
            if (completionContext.prefix.trim().length < 2 && 
                completionContext.lineBefore.trim().length === 0) {
                return [];
            }

            // Check cache first
            const cacheKey = this._getCacheKey(completionContext);
            const cached = this._getFromCache(cacheKey);
            if (cached) {
                return this._createCompletionItems(cached, position, document);
            }

            // Cancel any pending request
            if (this.pendingRequest) {
                this.pendingRequest.cancel = true;
            }

            // Debounce: wait for user to stop typing
            const completion = await this._debouncedRequest(
                completionContext, requestId, token
            );

            if (!completion || token.isCancellationRequested || requestId !== this.lastRequestId) {
                return [];
            }

            // Cache the result
            this._addToCache(cacheKey, completion);

            return this._createCompletionItems(completion, position, document);

        } catch (error) {
            if (error.name !== 'AbortError') {
                console.warn('[INLINE-COMPLETION] Error:', error.message);
            }
            return [];
        }
    }

    /**
     * Build rich context from the document
     */
    _buildContext(document, position) {
        const line = document.lineAt(position.line);
        const linesBefore = Math.min(position.line, 50);
        const linesAfter = Math.min(document.lineCount - position.line - 1, 20);
        
        // Get prefix (text before cursor in the file)
        const prefixLines = [];
        for (let i = Math.max(0, position.line - linesBefore); i <= position.line; i++) {
            if (i === position.line) {
                prefixLines.push(document.lineAt(i).text.substring(0, position.character));
            } else {
                prefixLines.push(document.lineAt(i).text);
            }
        }
        
        // Get suffix (text after cursor for FIM)
        const suffixLines = [];
        for (let i = position.line; i <= Math.min(document.lineCount - 1, position.line + linesAfter); i++) {
            if (i === position.line) {
                suffixLines.push(document.lineAt(i).text.substring(position.character));
            } else {
                suffixLines.push(document.lineAt(i).text);
            }
        }

        return {
            prefix: prefixLines.join('\n'),
            suffix: suffixLines.join('\n'),
            lineBefore: line.text.substring(0, position.character),
            lineAfter: line.text.substring(position.character),
            language: document.languageId,
            fileName: document.fileName,
            lineNumber: position.line,
            character: position.character,
            indentation: line.text.match(/^\s*/)[0],
        };
    }

    /**
     * Debounced API request
     */
    _debouncedRequest(context, requestId, token) {
        return new Promise((resolve) => {
            if (this.debounceTimer) {
                clearTimeout(this.debounceTimer);
            }

            const request = { cancel: false };
            this.pendingRequest = request;

            this.debounceTimer = setTimeout(async () => {
                if (request.cancel || token.isCancellationRequested || requestId !== this.lastRequestId) {
                    resolve(null);
                    return;
                }

                try {
                    this._updateStatusBar('loading');
                    const result = await this._callCompletionAPI(context, token);
                    this._updateStatusBar('ready');
                    resolve(result);
                } catch (error) {
                    this._updateStatusBar('error');
                    resolve(null);
                }
            }, this.debounceMs);
        });
    }

    /**
     * Call the AI API for completion
     */
    async _callCompletionAPI(context, token) {
        const controller = new AbortController();
        
        // Cancel on VS Code cancellation
        const cancelHandler = token.onCancellationRequested(() => {
            controller.abort();
        });

        try {
            // Strategy: Use FIM (Fill-in-the-Middle) if available, else prefix-only
            const prompt = this.fimEnabled 
                ? this._buildFIMPrompt(context)
                : this._buildPrefixPrompt(context);

            const routerUrl = CONFIG.server.modelRouterUrl || 'https://coder.vigthoria.io/api/model-router';
            
            const response = await fetch(`${routerUrl}/route`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-VS-Extension-Auth': 'vigthoria-vscode-extension-key-2025'
                },
                body: JSON.stringify({
                    prompt: prompt,
                    model: 'qwen2.5-coder:7b',  // Fast code model for completions
                    taskType: 'completion',
                    service: 'smart',
                    options: {
                        temperature: 0.2,   // Low temp for predictable completions
                        maxTokens: 256,     // Short completions
                        stream: false,
                        stop: ['\n\n\n', '```', '// ---', '# ---']  // Stop tokens
                    }
                }),
                signal: controller.signal
            });

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

            const data = await response.json();
            let completionText = data.response || data.content || '';
            
            // Clean and validate the completion
            completionText = this._cleanCompletion(completionText, context);
            
            if (!completionText || completionText.trim().length === 0) {
                return null;
            }

            this.totalCompletions++;
            
            return {
                text: completionText,
                language: context.language,
                timestamp: Date.now()
            };

        } finally {
            cancelHandler.dispose();
        }
    }

    /**
     * Build FIM (Fill-in-the-Middle) prompt
     * Uses the <|fim_prefix|> <|fim_suffix|> <|fim_middle|> format
     */
    _buildFIMPrompt(context) {
        // Universal FIM format that most code models understand
        return `<|fim_prefix|>${context.prefix}<|fim_suffix|>${context.suffix}<|fim_middle|>`;
    }

    /**
     * Build prefix-only completion prompt
     */
    _buildPrefixPrompt(context) {
        const languageComment = this._getLanguageComment(context.language);
        return `${languageComment} File: ${context.fileName}\n${context.prefix}`;
    }

    /**
     * Clean and validate AI completion output
     */
    _cleanCompletion(text, context) {
        if (!text) return '';

        // Remove any FIM tokens from output
        text = text.replace(/<\|fim_\w+\|>/g, '');
        text = text.replace(/<\|endoftext\|>/g, '');
        text = text.replace(/<\|end\|>/g, '');
        
        // Remove markdown code block markers
        text = text.replace(/^```\w*\n?/gm, '');
        text = text.replace(/\n?```$/gm, '');
        
        // Don't repeat what's already typed on the current line
        if (context.lineBefore && text.startsWith(context.lineBefore.trimStart())) {
            text = text.substring(context.lineBefore.trimStart().length);
        }

        // Limit to reasonable length (max ~10 lines for inline)
        const lines = text.split('\n');
        if (lines.length > 12) {
            text = lines.slice(0, 10).join('\n');
        }

        // Remove trailing whitespace-only lines
        text = text.replace(/\n\s*$/, '');

        return text;
    }

    /**
     * Create VS Code InlineCompletionItems from our completion
     */
    _createCompletionItems(completion, position, document) {
        if (!completion || !completion.text) return [];

        const item = new vscode.InlineCompletionItem(
            completion.text,
            new vscode.Range(position, position)
        );

        // Set the command to track acceptance
        item.command = {
            command: 'vigthoria.acceptedCompletion',
            title: 'Vigthoria Completion Accepted'
        };

        return [item];
    }

    /**
     * Cache management
     */
    _getCacheKey(context) {
        // Use last 100 chars of prefix + language as cache key
        const prefix = context.prefix.slice(-100);
        return `${context.language}:${prefix}`;
    }

    _getFromCache(key) {
        const entry = this.cache.get(key);
        if (!entry) return null;
        
        if (Date.now() - entry.timestamp > this.cacheTTL) {
            this.cache.delete(key);
            return null;
        }
        return entry;
    }

    _addToCache(key, completion) {
        // Evict old entries if cache is full
        if (this.cache.size >= this.cacheMaxSize) {
            const oldest = this.cache.keys().next().value;
            this.cache.delete(oldest);
        }
        this.cache.set(key, completion);
    }

    /**
     * Status bar updates
     */
    _updateStatusBar(state) {
        if (!this.statusBarItem) return;
        
        switch (state) {
            case 'loading':
                this.statusBarItem.text = '$(loading~spin) Vigthoria';
                this.statusBarItem.tooltip = 'Generating completion...';
                break;
            case 'ready':
                this.statusBarItem.text = '$(sparkle) Vigthoria';
                this.statusBarItem.tooltip = `Vigthoria AI Completion Active\n${this.totalCompletions} generated, ${this.totalAccepted} accepted`;
                break;
            case 'error':
                this.statusBarItem.text = '$(warning) Vigthoria';
                this.statusBarItem.tooltip = 'Vigthoria: Completion API unavailable';
                setTimeout(() => this._updateStatusBar('ready'), 3000);
                break;
        }
    }

    _getLanguageComment(language) {
        const comments = {
            javascript: '//', typescript: '//', python: '#', ruby: '#',
            java: '//', cpp: '//', c: '//', csharp: '//', go: '//',
            rust: '//', php: '//', swift: '//', kotlin: '//', scala: '//',
            r: '#', shell: '#', bash: '#', powershell: '#',
            html: '<!--', css: '/*', sql: '--', lua: '--',
        };
        return comments[language] || '//';
    }

    dispose() {
        if (this.debounceTimer) clearTimeout(this.debounceTimer);
        if (this.statusBarItem) this.statusBarItem.dispose();
        this.cache.clear();
    }
}

module.exports = { VigthoriInlineCompletionProvider };
