// ===================================
// Flutter AI Assistant - Main Script
// ===================================

// Configuration
const API_ENDPOINT = 'api/chat.php';

// DOM Elements
const chatForm = document.getElementById('chatForm');
const userInput = document.getElementById('userInput');
const sendBtn = document.getElementById('sendBtn');
const messagesContainer = document.getElementById('messagesContainer');

// Conversation History
let conversationHistory = [];

// Track if current query is about Flutter installation
let isFlutterInstallationQuery = false;

// Image injection configuration for Flutter Installation
const FLUTTER_INSTALLATION_IMAGES = {
    downloadPage: {
        keyword: ['click download button'],
        image: 'images/flutter_download.png',
        alt: 'Flutter Download Page'
    },
    envVariables: {
        keyword: ['double click on path'],
        image: 'images/java_home_setup.png',
        alt: 'Environment Variables Window'
    },
    pathSetup: {
        keyword: ['click ok on all windows'],
        image: 'images/path_setup.png',
        alt: 'Adding Flutter to Path'
    },
    cmdlineTools: {
        keyword: ['commandlinetools-win'],
        image: 'images/cmdline_tools.png',
        alt: 'Android Command Line Tools Download'
    }
};

// Keywords that trigger Flutter installation mode
const FLUTTER_INSTALL_TRIGGERS = [
    'install flutter',
    'flutter installation',
    'flutter and android sdk',
    'flutter sdk installation',
    'setup flutter',
    'flutter & sdk installation',
    'how to install flutter'
];

// Initialize
document.addEventListener('DOMContentLoaded', () => {
    chatForm.addEventListener('submit', handleSubmit);
    userInput.addEventListener('keydown', handleKeyPress);

    // Focus input on load
    userInput.focus();
});

// Handle form submission
async function handleSubmit(e) {
    e.preventDefault();

    const message = userInput.value.trim();
    if (!message) return;

    // Clear input
    userInput.value = '';

    // Check if this is a Flutter installation query
    isFlutterInstallationQuery = checkIfFlutterInstallationQuery(message);

    // Remove welcome message if exists
    const welcomeMsg = document.querySelector('.welcome-message');
    if (welcomeMsg) {
        welcomeMsg.remove();
    }

    // Add user message to UI
    addMessage(message, 'user');

    // Disable input while processing
    setLoading(true);

    // Add typing indicator
    const typingIndicator = addTypingIndicator();

    try {
        // Create a placeholder for streaming response
        let streamingMessage = null;
        let streamingContent = '';
        let lastRenderTime = 0;
        const RENDER_THROTTLE = 50; // Render at most every 50ms for smooth performance

        // Send to API with streaming
        const response = await sendMessageToAPI(message, (chunk) => {

            // Remove typing indicator on first chunk
            if (!streamingMessage) {
                typingIndicator.remove();
                streamingMessage = addMessage('', 'ai');
            }

            // Append chunk to streaming content
            streamingContent += chunk;

            // Throttle rendering for smooth performance
            const now = Date.now();
            if (now - lastRenderTime >= RENDER_THROTTLE) {
                lastRenderTime = now;

                // Update message content
                const contentDiv = streamingMessage.querySelector('.message-content');
                if (contentDiv) {
                    contentDiv.innerHTML = formatMessage(streamingContent);
                }

                // Scroll to bottom
                scrollToBottom();
            }
        });

        // Final render with image injection ONLY at the end
        if (streamingMessage) {
            const contentDiv = streamingMessage.querySelector('.message-content');
            if (contentDiv) {
                let finalContent = streamingContent;
                if (isFlutterInstallationQuery) {
                    finalContent = injectFlutterImages(streamingContent);
                }
                contentDiv.innerHTML = formatMessage(finalContent);
            }
        }

        // If no streaming message was created (fallback mode), add the complete message
        if (!streamingMessage) {
            typingIndicator.remove();
            let finalResponse = response;
            if (isFlutterInstallationQuery) {
                finalResponse = injectFlutterImages(response);
            }
            addMessage(finalResponse, 'ai');
        }

        // Update conversation history (keep all messages)
        conversationHistory.push(
            { role: 'user', content: message },
            { role: 'assistant', content: response || streamingContent }
        );

    } catch (error) {
        // Remove typing indicator
        typingIndicator.remove();

        // Show error message
        addErrorMessage(error.message);
    } finally {
        // Re-enable input
        setLoading(false);
        userInput.focus();
        // Reset Flutter installation flag
        isFlutterInstallationQuery = false;
    }
}

// Check if user is asking about Flutter installation
function checkIfFlutterInstallationQuery(message) {
    const lowerMessage = message.toLowerCase();
    return FLUTTER_INSTALL_TRIGGERS.some(trigger => lowerMessage.includes(trigger));
}

// Inject Flutter installation images into response
function injectFlutterImages(text) {
    let result = text;
    const lowerText = text.toLowerCase();
    const injectedImages = new Set();

    // Check each image configuration
    for (const [key, config] of Object.entries(FLUTTER_INSTALLATION_IMAGES)) {
        // Check if any keyword matches and image not already injected
        const hasKeyword = config.keyword.some(kw => lowerText.includes(kw.toLowerCase()));

        if (hasKeyword && !injectedImages.has(key)) {
            // Find the best position to inject the image (after the matching section)
            for (const keyword of config.keyword) {
                const keywordLower = keyword.toLowerCase();
                const index = lowerText.indexOf(keywordLower);

                if (index !== -1) {
                    // Find end of line or paragraph after this keyword
                    let insertPos = text.indexOf('\n', index);
                    if (insertPos === -1) insertPos = text.length;

                    // Skip a couple lines to insert after the step
                    let nextNewline = text.indexOf('\n', insertPos + 1);
                    if (nextNewline !== -1) insertPos = nextNewline;

                    // Create image markdown
                    const imageMarkdown = `\n\n![${config.alt}](${config.image})\n`;

                    // Insert image
                    result = result.slice(0, insertPos) + imageMarkdown + result.slice(insertPos);
                    injectedImages.add(key);
                    break;
                }
            }
        }
    }

    return result;
}

// Send message to API with streaming support
async function sendMessageToAPI(message, onChunk = null) {
    const useStreaming = true; // Re-enabled streaming

    if (useStreaming && onChunk) {
        // Use fetch with streaming
        try {
            // Add timeout using AbortController
            const controller = new AbortController();
            const timeoutId = setTimeout(() => controller.abort(), 120000); // 2 minute timeout

            const response = await fetch(API_ENDPOINT + '?stream=true', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    message: message,
                    history: conversationHistory.slice(-10)
                }),
                signal: controller.signal
            });

            clearTimeout(timeoutId);

            if (!response.ok) {
                const errorText = await response.text();
                console.error('Server response:', errorText);
                throw new Error(`Server error: ${response.status}`);
            }

            const reader = response.body.getReader();
            const decoder = new TextDecoder();
            let fullResponse = '';
            let buffer = '';

            while (true) {
                const { done, value } = await reader.read();

                if (done) break;

                // Decode the chunk
                buffer += decoder.decode(value, { stream: true });

                // Process complete SSE messages
                const lines = buffer.split('\n');
                buffer = lines.pop() || ''; // Keep incomplete line in buffer

                for (const line of lines) {
                    if (line.startsWith('data: ')) {
                        const data = line.slice(6);

                        if (data === '[DONE]') {
                            return fullResponse;
                        }

                        try {
                            const parsed = JSON.parse(data);
                            if (parsed.error) {
                                throw new Error(parsed.error);
                            }
                            if (parsed.content) {
                                fullResponse += parsed.content;
                                onChunk(parsed.content);
                            }
                        } catch (e) {
                            // Skip invalid JSON
                            console.warn('Parse error:', e);
                        }
                    }
                }
            }

            return fullResponse;

        } catch (error) {
            console.error('Streaming error:', error);
            throw error;
        }
    } else {
        // Fallback to non-streaming
        try {
            const response = await fetch(API_ENDPOINT, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    message: message,
                    history: conversationHistory.slice(-10)
                })
            });

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

            const data = await response.json();

            if (data.error) {
                throw new Error(data.error);
            }

            return data.response;

        } catch (error) {
            console.error('API Error:', error);
            throw new Error('Failed to get response. Please check your connection and try again.');
        }
    }
}

// Add message to chat
function addMessage(text, type) {
    const messageDiv = document.createElement('div');
    messageDiv.className = `message ${type}`;

    const avatar = document.createElement('div');
    avatar.className = 'message-avatar';
    avatar.textContent = type === 'user' ? '👤' : '🤖';

    const content = document.createElement('div');
    content.className = 'message-content';

    // Format message with enhanced markdown support
    content.innerHTML = formatMessage(text);

    messageDiv.appendChild(avatar);
    messageDiv.appendChild(content);

    messagesContainer.appendChild(messageDiv);

    // Smooth scroll to bottom
    scrollToBottom();

    return messageDiv;
}

// Format message with enhanced markdown syntax
function formatMessage(text) {
    // Escape HTML first
    let formatted = text
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;');

    // Code blocks with language detection (```language\ncode```)
    formatted = formatted.replace(/```(\w+)?\n?([\s\S]*?)```/g, function (match, language, code) {
        const lang = language || 'code';
        const codeId = 'code-' + Math.random().toString(36).substr(2, 9);
        return `<pre><div class="code-header"><span class="code-language">${lang}</span><button class="copy-btn" onclick="copyCode('${codeId}')">Copy</button></div><code id="${codeId}">${applySyntaxHighlight(code.trim(), lang)}</code></pre>`;
    });

    // Inline code (`code`) - must come after code blocks
    formatted = formatted.replace(/`([^`]+)`/g, '<code>$1</code>');

    // Headings (### Heading, ## Heading, # Heading)
    formatted = formatted.replace(/^### (.+)$/gm, '<h3>$1</h3>');
    formatted = formatted.replace(/^## (.+)$/gm, '<h2>$1</h2>');
    formatted = formatted.replace(/^# (.+)$/gm, '<h1>$1</h1>');

    // Blockquotes (> text)
    formatted = formatted.replace(/^&gt; (.+)$/gm, '<blockquote>$1</blockquote>');

    // Unordered lists (- item or * item)
    formatted = formatted.replace(/^[-*] (.+)$/gm, '<li>$1</li>');
    // Wrap consecutive <li> in <ul>
    formatted = formatted.replace(/(<li>.*?<\/li>\n?)+/gs, function (match) {
        return '<ul>' + match + '</ul>';
    });

    // Numbered lists (1. item)
    formatted = formatted.replace(/^\d+\. (.+)$/gm, '<li class="numbered">$1</li>');
    // Wrap numbered <li> in <ol>
    formatted = formatted.replace(/(<li class="numbered">.*?<\/li>\n?)+/gs, function (match) {
        return '<ol>' + match.replace(/ class="numbered"/g, '') + '</ol>';
    });

    // Bold (**text** or __text__)
    formatted = formatted.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>');
    formatted = formatted.replace(/__([^_]+)__/g, '<strong>$1</strong>');

    // Italic (*text*) - simple version to avoid conflicts
    formatted = formatted.replace(/\*([^\*\n]+)\*/g, '<em>$1</em>');

    // Horizontal rule (---)
    formatted = formatted.replace(/^---$/gm, '<hr>');

    // Images (![alt](url)) - must come before URL auto-linking
    formatted = formatted.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '<img src="$2" alt="$1" class="chat-image" loading="lazy">');

    // Auto-link URLs (but not ones already in img src or href)
    formatted = formatted.replace(/(?<!src="|href=")(https?:\/\/[^\s<]+)/g, '<a href="$1" target="_blank" rel="noopener noreferrer">$1</a>');

    // Line breaks (convert \n to <br>, but not inside block elements)
    formatted = formatted.replace(/\n(?!<\/?(h[1-3]|li|ul|ol|blockquote|hr))/g, '<br>');

    return formatted;
}

// Basic syntax highlighting
function applySyntaxHighlight(code, language) {
    // Keywords for different languages
    const keywords = {
        dart: ['class', 'void', 'return', 'if', 'else', 'for', 'while', 'import', 'extends', 'implements', 'final', 'const', 'var', 'String', 'int', 'double', 'bool', 'List', 'Map', 'Widget', 'StatelessWidget', 'StatefulWidget', 'State', 'BuildContext', 'async', 'await', 'Future'],
        javascript: ['function', 'const', 'let', 'var', 'return', 'if', 'else', 'for', 'while', 'class', 'extends', 'import', 'export', 'async', 'await', 'Promise'],
        python: ['def', 'class', 'return', 'if', 'else', 'elif', 'for', 'while', 'import', 'from', 'as', 'try', 'except', 'with', 'async', 'await'],
        php: ['function', 'class', 'return', 'if', 'else', 'foreach', 'while', 'public', 'private', 'protected', 'static', 'namespace', 'use']
    };

    let highlighted = code;
    const langKeywords = keywords[language.toLowerCase()] || keywords.dart;

    // Highlight strings
    highlighted = highlighted.replace(/(['"`])(.*?)\1/g, '<span class="string">$1$2$1</span>');

    // Highlight comments
    highlighted = highlighted.replace(/\/\/(.*?)$/gm, '<span class="comment">//$1</span>');
    highlighted = highlighted.replace(/\/\*([\s\S]*?)\*\//g, '<span class="comment">/*$1*/</span>');

    // Highlight keywords
    langKeywords.forEach(keyword => {
        const regex = new RegExp(`\\b(${keyword})\\b`, 'g');
        highlighted = highlighted.replace(regex, '<span class="keyword">$1</span>');
    });

    // Highlight numbers
    highlighted = highlighted.replace(/\b(\d+)\b/g, '<span class="number">$1</span>');

    return highlighted;
}

// Copy code to clipboard
function copyCode(codeId) {
    const codeElement = document.getElementById(codeId);
    if (!codeElement) return;

    // Get text content without HTML tags
    const code = codeElement.innerText || codeElement.textContent;

    // Copy to clipboard
    navigator.clipboard.writeText(code).then(() => {
        // Find the copy button
        const btn = codeElement.parentElement.querySelector('.copy-btn');
        if (btn) {
            const originalText = btn.textContent;
            btn.textContent = 'Copied!';
            btn.classList.add('copied');

            setTimeout(() => {
                btn.textContent = originalText;
                btn.classList.remove('copied');
            }, 2000);
        }
    }).catch(err => {
        console.error('Failed to copy:', err);
        alert('Failed to copy code');
    });
}

// Add typing indicator
function addTypingIndicator() {
    const messageDiv = document.createElement('div');
    messageDiv.className = 'message ai';

    const avatar = document.createElement('div');
    avatar.className = 'message-avatar';
    avatar.textContent = '🤖';

    const content = document.createElement('div');
    content.className = 'message-content';

    const typingDiv = document.createElement('div');
    typingDiv.className = 'typing-indicator active';
    typingDiv.innerHTML = '<span class="typing-dot"></span><span class="typing-dot"></span><span class="typing-dot"></span>';

    content.appendChild(typingDiv);
    messageDiv.appendChild(avatar);
    messageDiv.appendChild(content);

    messagesContainer.appendChild(messageDiv);
    scrollToBottom();

    return messageDiv;
}

// Add error message
function addErrorMessage(errorText) {
    const errorDiv = document.createElement('div');
    errorDiv.className = 'error-message';
    errorDiv.innerHTML = `<strong>⚠️ Error:</strong> ${errorText}`;

    messagesContainer.appendChild(errorDiv);
    scrollToBottom();

    // Auto-remove after 5 seconds
    setTimeout(() => {
        errorDiv.style.animation = 'fadeOut 0.3s ease';
        setTimeout(() => errorDiv.remove(), 300);
    }, 5000);
}

// Set loading state
function setLoading(isLoading) {
    sendBtn.disabled = isLoading;
    userInput.disabled = isLoading;

    if (isLoading) {
        sendBtn.textContent = 'Thinking... 🧠';
        chatForm.classList.add('loading');
    } else {
        sendBtn.textContent = 'Send 🚀';
        chatForm.classList.remove('loading');
    }
}

// Smooth scroll to bottom
function scrollToBottom() {
    messagesContainer.scrollTo({
        top: messagesContainer.scrollHeight,
        behavior: 'smooth'
    });
}

// Handle Enter key (Shift+Enter for new line)
function handleKeyPress(e) {
    if (e.key === 'Enter' && !e.shiftKey) {
        e.preventDefault();
        chatForm.dispatchEvent(new Event('submit'));
    }
}

// Send suggestion chip message
function sendSuggestion(text) {
    userInput.value = text;
    chatForm.dispatchEvent(new Event('submit'));
}

// Add fade out animation to CSS dynamically
const style = document.createElement('style');
style.textContent = `
    @keyframes fadeOut {
        from { opacity: 1; }
        to { opacity: 0; }
    }
`;
document.head.appendChild(style);
