/**
 * TypeDialog AI Configuration Assistant - Web UI
 * Handles interactive configuration generation with real-time streaming
 */

// ============================================================================
// Global State
// ============================================================================

const state = {
    conversationId: null,
    selectedSchema: null,
    ws: null,
    isConnected: false,
    isStreaming: false,
    generatedConfig: null,
    messageHistory: [],
    suggestions: [],
};

// ============================================================================
// DOM References
// ============================================================================

const elements = {
    // Sidebar
    schemaSelect: document.getElementById('schemaSelect'),
    startBtn: document.getElementById('startBtn'),
    copyBtn: document.getElementById('copyBtn'),
    conversationId: document.getElementById('conversationId'),
    requiredFields: document.getElementById('requiredFields'),
    suggestBtn: document.getElementById('suggestBtn'),
    generateBtn: document.getElementById('generateBtn'),
    clearBtn: document.getElementById('clearBtn'),

    // Chat
    chatContainer: document.getElementById('chatContainer'),
    messageInput: document.getElementById('messageInput'),
    sendBtn: document.getElementById('sendBtn'),

    // Suggestions
    suggestionsSection: document.getElementById('suggestionsSection'),
    suggestionsContainer: document.getElementById('suggestionsContainer'),

    // Config
    configSection: document.getElementById('configSection'),
    formatSelect: document.getElementById('formatSelect'),
    configPreview: document.getElementById('configPreview'),
    downloadBtn: document.getElementById('downloadBtn'),
    copyConfigBtn: document.getElementById('copyConfigBtn'),

    // Status
    statusText: document.getElementById('statusText'),
    connectionStatus: document.getElementById('connectionStatus'),
    loadingOverlay: document.getElementById('loadingOverlay'),
};

// ============================================================================
// Initialization
// ============================================================================

document.addEventListener('DOMContentLoaded', () => {
    setupEventListeners();
    updateUI();
});

function setupEventListeners() {
    elements.schemaSelect.addEventListener('change', onSchemaChange);
    elements.startBtn.addEventListener('click', onStartConversation);
    elements.copyBtn.addEventListener('click', onCopyConversationId);
    elements.sendBtn.addEventListener('click', onSendMessage);
    elements.messageInput.addEventListener('keypress', (e) => {
        if (e.key === 'Enter' && !e.shiftKey) {
            e.preventDefault();
            onSendMessage();
        }
    });
    elements.suggestBtn.addEventListener('click', onGetSuggestions);
    elements.generateBtn.addEventListener('click', onGenerateConfig);
    elements.downloadBtn.addEventListener('click', onDownloadConfig);
    elements.copyConfigBtn.addEventListener('click', onCopyConfig);
    elements.formatSelect.addEventListener('change', onFormatChange);
    elements.clearBtn.addEventListener('click', onClearConversation);
}

// ============================================================================
// Event Handlers
// ============================================================================

function onSchemaChange() {
    state.selectedSchema = elements.schemaSelect.value;
    updateUI();
    if (state.selectedSchema) {
        updateRequiredFields(state.selectedSchema);
    }
}

function onStartConversation() {
    if (!state.selectedSchema) {
        showStatus('Please select a schema', 'error');
        return;
    }

    // Generate a conversation ID
    state.conversationId = generateConversationId();
    elements.conversationId.textContent = state.conversationId;

    // Clear chat
    state.messageHistory = [];
    renderChat();

    // Connect WebSocket
    connectWebSocket();

    updateUI();
    showStatus(`Conversation started: ${state.conversationId}`);
}

function onSendMessage() {
    const message = elements.messageInput.value.trim();
    if (!message) return;
    if (!state.ws || !state.isConnected) {
        showStatus('Not connected', 'error');
        return;
    }

    // Add user message to history
    state.messageHistory.push({
        role: 'user',
        content: message,
        timestamp: new Date(),
    });

    // Clear input and render
    elements.messageInput.value = '';
    renderChat();

    // Send via WebSocket
    const wsMessage = {
        type: 'message',
        content: message,
    };
    state.ws.send(JSON.stringify(wsMessage));
    showStatus('Sending message...');
}

function onGetSuggestions() {
    if (!state.conversationId) {
        showStatus('Start a conversation first', 'error');
        return;
    }

    showLoading(true);
    showStatus('Fetching suggestions...');

    // Simulate suggestions (in production, would fetch from API)
    setTimeout(() => {
        state.suggestions = [
            {
                field: 'port',
                value: '8080',
                reasoning: 'Standard web server port',
                confidence: 0.92,
            },
            {
                field: 'host',
                value: 'localhost',
                reasoning: 'Development default',
                confidence: 0.85,
            },
            {
                field: 'timeout',
                value: '30',
                reasoning: 'Balanced responsiveness',
                confidence: 0.78,
            },
        ];
        renderSuggestions();
        showLoading(false);
        showStatus('Suggestions loaded');
    }, 500);
}

function onGenerateConfig() {
    if (!state.conversationId) {
        showStatus('Start a conversation first', 'error');
        return;
    }

    showLoading(true);
    showStatus('Generating configuration...');

    // Simulate config generation (in production, would call API)
    setTimeout(() => {
        const format = elements.formatSelect.value;
        state.generatedConfig = generateConfigPreview(format);
        renderConfigPreview();
        showLoading(false);
        showStatus('Configuration generated');
    }, 1000);
}

function onDownloadConfig() {
    if (!state.generatedConfig) {
        showStatus('Generate a configuration first', 'error');
        return;
    }

    const format = elements.formatSelect.value;
    const filename = `config.${format}`;
    const blob = new Blob([state.generatedConfig], { type: 'text/plain' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = filename;
    a.click();
    URL.revokeObjectURL(url);

    showStatus('Configuration downloaded');
}

function onCopyConfig() {
    if (!state.generatedConfig) {
        showStatus('Generate a configuration first', 'error');
        return;
    }

    navigator.clipboard.writeText(state.generatedConfig).then(() => {
        showStatus('Configuration copied to clipboard');
    });
}

function onCopyConversationId() {
    if (!state.conversationId) return;
    navigator.clipboard.writeText(state.conversationId).then(() => {
        showStatus('Conversation ID copied');
    });
}

function onFormatChange() {
    if (state.generatedConfig) {
        const format = elements.formatSelect.value;
        state.generatedConfig = generateConfigPreview(format);
        renderConfigPreview();
    }
}

function onClearConversation() {
    if (!confirm('Clear conversation history?')) return;
    state.conversationId = null;
    state.messageHistory = [];
    state.generatedConfig = null;
    state.suggestions = [];
    renderChat();
    updateUI();
    showStatus('Conversation cleared');
}

// ============================================================================
// WebSocket Management
// ============================================================================

function connectWebSocket() {
    const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
    const wsUrl = `${protocol}//${window.location.host}/ws/${state.conversationId}`;

    try {
        state.ws = new WebSocket(wsUrl);

        state.ws.onopen = () => {
            state.isConnected = true;
            updateUI();
            showStatus('Connected');
        };

        state.ws.onmessage = (event) => {
            try {
                const response = JSON.parse(event.data);
                handleWebSocketMessage(response);
            } catch (e) {
                console.error('Failed to parse WebSocket message:', e);
            }
        };

        state.ws.onerror = (error) => {
            console.error('WebSocket error:', error);
            showStatus('Connection error', 'error');
        };

        state.ws.onclose = () => {
            state.isConnected = false;
            updateUI();
            showStatus('Disconnected', 'error');
        };
    } catch (e) {
        showStatus('Failed to connect', 'error');
        console.error(e);
    }
}

function handleWebSocketMessage(response) {
    switch (response.type) {
        case 'start':
            state.isStreaming = true;
            state.messageHistory.push({
                role: 'assistant',
                content: '',
                timestamp: new Date(),
                isStreaming: true,
            });
            renderChat();
            break;

        case 'chunk':
            if (state.messageHistory.length > 0) {
                const lastMsg = state.messageHistory[state.messageHistory.length - 1];
                if (lastMsg.role === 'assistant') {
                    lastMsg.content += response.content;
                }
            }
            renderChat();
            break;

        case 'end':
            state.isStreaming = false;
            if (state.messageHistory.length > 0) {
                const lastMsg = state.messageHistory[state.messageHistory.length - 1];
                lastMsg.isStreaming = false;
            }
            renderChat();
            showStatus('Message received');
            break;

        case 'error':
            showStatus(`Error: ${response.content}`, 'error');
            break;

        case 'suggestions':
            try {
                state.suggestions = JSON.parse(response.content);
                renderSuggestions();
            } catch (e) {
                console.error('Failed to parse suggestions:', e);
            }
            break;

        default:
            console.warn('Unknown message type:', response.type);
    }
}

// ============================================================================
// Rendering Functions
// ============================================================================

function renderChat() {
    if (state.messageHistory.length === 0) {
        elements.chatContainer.innerHTML = `
            <div class="welcome-message">
                <p>👋 Welcome to TypeDialog AI Configuration Assistant</p>
                <p>Type a configuration question to begin</p>
            </div>
        `;
        return;
    }

    const messageHtml = state.messageHistory
        .map((msg) => {
            const timeStr = msg.timestamp.toLocaleTimeString();
            if (msg.isStreaming) {
                return `
                    <div class="message ${msg.role}">
                        <div class="message-bubble">
                            <div class="streaming">
                                <span></span>
                                <span></span>
                                <span></span>
                            </div>
                        </div>
                    </div>
                `;
            }
            return `
                <div class="message ${msg.role}">
                    <div class="message-bubble">${escapeHtml(msg.content)}</div>
                    <div class="message-time">${timeStr}</div>
                </div>
            `;
        })
        .join('');

    elements.chatContainer.innerHTML = messageHtml;
    elements.chatContainer.scrollTop = elements.chatContainer.scrollHeight;
}

function renderSuggestions() {
    if (state.suggestions.length === 0) {
        elements.suggestionsSection.style.display = 'none';
        return;
    }

    elements.suggestionsSection.style.display = 'block';
    const suggestionsHtml = state.suggestions
        .map((suggestion) => {
            const confidencePercent = (suggestion.confidence * 100).toFixed(0);
            return `
                <div class="suggestion-card" onclick="insertSuggestion('${escapeAttr(suggestion.field)}', '${escapeAttr(suggestion.value)}')">
                    <div class="suggestion-field">${escapeHtml(suggestion.field)}</div>
                    <div class="suggestion-value">${escapeHtml(suggestion.value)}</div>
                    <div class="suggestion-reasoning">${escapeHtml(suggestion.reasoning)}</div>
                    <div class="suggestion-confidence">
                        <span>${confidencePercent}%</span>
                        <div class="confidence-bar">
                            <div class="confidence-fill" style="width: ${confidencePercent}%"></div>
                        </div>
                    </div>
                </div>
            `;
        })
        .join('');

    elements.suggestionsContainer.innerHTML = suggestionsHtml;
}

function renderConfigPreview() {
    elements.configSection.style.display = 'block';
    const codeElement = elements.configPreview.querySelector('code');
    if (codeElement) {
        codeElement.textContent = state.generatedConfig;
    }
}

function updateUI() {
    const hasConversation = state.conversationId !== null;
    const hasSchema = state.selectedSchema !== null;

    // Sidebar
    elements.startBtn.disabled = !hasSchema;
    elements.copyBtn.disabled = !hasConversation;
    elements.conversationId.textContent = state.conversationId || '-';

    // Chat
    elements.messageInput.disabled = !state.isConnected;
    elements.sendBtn.disabled = !state.isConnected || state.isStreaming;

    // Actions
    elements.suggestBtn.disabled = !hasConversation;
    elements.generateBtn.disabled = !hasConversation;
    elements.clearBtn.disabled = !hasConversation;
    elements.downloadBtn.disabled = !state.generatedConfig;
    elements.copyConfigBtn.disabled = !state.generatedConfig;

    // Status
    updateConnectionStatus();
}

function updateConnectionStatus() {
    if (state.isConnected) {
        elements.connectionStatus.textContent = '● Connected';
        elements.connectionStatus.classList.remove('disconnected');
        elements.connectionStatus.classList.add('connected');
    } else {
        elements.connectionStatus.textContent = '● Disconnected';
        elements.connectionStatus.classList.remove('connected');
        elements.connectionStatus.classList.add('disconnected');
    }
}

function updateRequiredFields(schema) {
    const fieldsMap = {
        ServerConfig: ['port', 'host', 'timeout'],
        DatabaseConfig: ['host', 'port', 'database', 'username'],
        ApplicationConfig: ['name', 'version', 'debug_mode', 'log_level'],
    };

    const fields = fieldsMap[schema] || [];
    if (fields.length === 0) {
        elements.requiredFields.innerHTML =
            '<li class="placeholder">No fields for this schema</li>';
        return;
    }

    const fieldsHtml = fields
        .map((field) => `<li class="required">${escapeHtml(field)}</li>`)
        .join('');
    elements.requiredFields.innerHTML = fieldsHtml;
}

// ============================================================================
// Utility Functions
// ============================================================================

function insertSuggestion(field, value) {
    elements.messageInput.value = `Set ${field} to ${value}`;
    elements.messageInput.focus();
}

function generateConversationId() {
    return `conv-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
}

function showStatus(message, type = 'info') {
    elements.statusText.textContent = message;
    elements.statusText.style.color =
        type === 'error' ? 'var(--color-danger)' : 'var(--color-text-light)';
    setTimeout(() => {
        elements.statusText.textContent = 'Ready';
        elements.statusText.style.color = 'var(--color-text-light)';
    }, 3000);
}

function showLoading(show) {
    if (show) {
        elements.loadingOverlay.style.display = 'flex';
    } else {
        elements.loadingOverlay.style.display = 'none';
    }
}

function generateConfigPreview(format) {
    const configs = {
        json: JSON.stringify(
            {
                server: {
                    port: 8080,
                    host: 'localhost',
                    timeout: 30,
                },
                database: {
                    host: 'localhost',
                    port: 5432,
                    name: 'myapp',
                },
                logging: {
                    level: 'info',
                    format: 'json',
                },
            },
            null,
            2
        ),
        yaml: `server:
  port: 8080
  host: localhost
  timeout: 30
database:
  host: localhost
  port: 5432
  name: myapp
logging:
  level: info
  format: json`,
        toml: `[server]
port = 8080
host = "localhost"
timeout = 30

[database]
host = "localhost"
port = 5432
name = "myapp"

[logging]
level = "info"
format = "json"`,
    };

    return configs[format] || configs.json;
}

function escapeHtml(text) {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
}

function escapeAttr(text) {
    return text.replace(/"/g, '&quot;').replace(/'/g, '&#39;');
}

// ============================================================================
// Export for testing
// ============================================================================

if (typeof module !== 'undefined' && module.exports) {
    module.exports = { state, generateConversationId, escapeHtml };
}
