{% extends "base.html" %}

{% block title %}Chat - {{ conversation_name }} - {{ app_name }}{% endblock %}

{% block content %}
<div class="row">
    <div class="col-12">
        <h2 class="mb-3">
            <i class="bi bi-chat-dots-fill"></i> {{ conversation_name }}
            <button class="btn btn-sm btn-outline-secondary float-end" data-bs-toggle="modal" data-bs-target="#infoModal">
                <i class="bi bi-info-circle"></i> Info
            </button>
        </h2>
    </div>
</div>

<!-- Chat Messages Area -->
<div class="row">
    <div class="col-12">
        <div class="card mb-3" style="height: 60vh;">
            <div class="card-body overflow-auto" id="chat-messages">
                <!-- Messages will be appended here -->
                <div class="text-center text-muted">
                    <output class="spinner-border spinner-border-sm">
                        <span class="visually-hidden">Loading...</span>
                    </output>
                    <span class="ms-2">Loading chat history...</span>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- Chat Input Area -->
<div class="row">
    <div class="col-12">
        <div class="card">
            <div class="card-body">
                <form id="chat-form">
                    <div class="mb-3">
                        <label for="message-input" class="form-label">Your Message</label>
                        <textarea
                            class="form-control"
                            id="message-input"
                            rows="3"
                            placeholder="Type your message here..."
                            required
                        ></textarea>
                    </div>
                    <div class="d-flex justify-content-between align-items-center">
                        <fieldset class="btn-group">
                            <button type="button" class="btn btn-outline-secondary btn-sm" onclick="showCommandMenu()">
                                <i class="bi bi-terminal"></i> Commands
                            </button>
                            <button type="button" class="btn btn-outline-secondary btn-sm" onclick="attachFiles()">
                                <i class="bi bi-paperclip"></i> Attach
                            </button>
                        </fieldset>
                        <div class="d-flex align-items-center gap-2">
                            {% if web_search_enabled %}
                            <button type="button" class="btn btn-primary btn-sm" id="web-search-toggle"
                                    title="Web search: ON" onclick="toggleWebSearch()">
                                <i class="bi bi-globe"></i>
                            </button>
                            {% endif %}
                            <button type="submit" class="btn btn-primary" id="send-btn">
                                <i class="bi bi-send-fill"></i> Send
                            </button>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>

<!-- Info Modal -->
<div class="modal fade" id="infoModal" tabindex="-1">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title"><i class="bi bi-info-circle"></i> Conversation Information</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
            </div>
            <div class="modal-body" id="info-content">
                <div class="text-center">
                    <output class="spinner-border spinner-border-sm">
                        <span class="visually-hidden">Loading...</span>
                    </output>
                </div>
            </div>
        </div>
    </div>
</div>

<script>
// Load conversation info when modal is shown
document.getElementById('infoModal').addEventListener('show.bs.modal', function() {
    loadConversationInfo();
});
</script>

<!-- Command Menu Modal -->
<div class="modal fade" id="commandModal" tabindex="-1">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title"><i class="bi bi-terminal"></i> Commands</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
            </div>
            <div class="modal-body">
                <div class="list-group">
                    <button class="list-group-item list-group-item-action" onclick="executeCommand('history')">
                        <i class="bi bi-clock-history"></i> View History
                    </button>
                    <button class="list-group-item list-group-item-action" onclick="executeCommand('info')">
                        <i class="bi bi-info-circle"></i> Show Info
                    </button>
                    <button class="list-group-item list-group-item-action" onclick="executeCommand('changemodel')">
                        <i class="bi bi-arrow-repeat"></i> Change Model
                    </button>
                    <button class="list-group-item list-group-item-action" onclick="executeCommand('export')">
                        <i class="bi bi-download"></i> Export Conversation
                    </button>
                    <button class="list-group-item list-group-item-action" onclick="executeCommand('attach')">
                        <i class="bi bi-paperclip"></i> Attach Files
                    </button>
                    <button class="list-group-item list-group-item-action" onclick="executeCommand('instructions')">
                        <i class="bi bi-card-text"></i> Change Instructions
                    </button>
                    <button class="list-group-item list-group-item-action" onclick="executeCommand('compaction')">
                        <i class="bi bi-layers"></i> Compaction Settings
                    </button>
                    <button class="list-group-item list-group-item-action" onclick="executeCommand('copy')">
                        <i class="bi bi-clipboard"></i> Copy Last Response
                    </button>
                    <button class="list-group-item list-group-item-action" onclick="executeCommand('mcpaudit')">
                        <i class="bi bi-shield-check"></i> MCP Audit Log
                    </button>
                    <button class="list-group-item list-group-item-action" onclick="executeCommand('mcpservers')">
                        <i class="bi bi-hdd-network"></i> MCP Server Management
                    </button>
                    <hr class="my-2">
                    <button class="list-group-item list-group-item-action" onclick="executeCommand('deletefiles')">
                        <i class="bi bi-file-earmark-x text-warning"></i> Delete Attached Files
                    </button>
                    <button class="list-group-item list-group-item-action text-danger" onclick="executeCommand('delete')">
                        <i class="bi bi-trash"></i> Delete Conversation
                    </button>
                </div>
            </div>
        </div>
    </div>
</div>
{% endblock %}

{% block extra_scripts %}
<script src="/static/js/chat.js"></script>
<script src="/static/js/sse-client.js"></script>
<script>
// Initialise chat with conversation ID
const conversationId = {{ conversation_id }};

// Web search toggle state (default ON if web search is enabled for conversation)
let webSearchActive = {{ 'true' if web_search_enabled else 'false' }};

// Toggle web search for current request
function toggleWebSearch() {
    webSearchActive = !webSearchActive;
    const btn = document.getElementById('web-search-toggle');
    if (webSearchActive) {
        btn.classList.remove('btn-outline-secondary');
        btn.classList.add('btn-primary');
        btn.title = 'Web search: ON';
    } else {
        btn.classList.remove('btn-primary');
        btn.classList.add('btn-outline-secondary');
        btn.title = 'Web search: OFF';
    }
}

// Load chat history on page load
window.addEventListener('load', () => {
    loadChatHistory(conversationId);
});

// Handle chat form submission
document.getElementById('chat-form').addEventListener('submit', async (e) => {
    e.preventDefault();

    const messageInput = document.getElementById('message-input');
    const message = messageInput.value.trim();

    if (!message) return;

    // Clear input
    messageInput.value = '';

    // Change send button to cancel button
    const sendBtn = document.getElementById('send-btn');
    sendBtn.classList.remove('btn-primary');
    sendBtn.classList.add('btn-warning');
    sendBtn.innerHTML = '<i class="bi bi-x-circle"></i> Cancel';
    sendBtn.onclick = handleCancelClick;
    sendBtn.type = 'button';  // Prevent form submission when clicking cancel

    // Add user message to chat with current timestamp
    appendMessage('user', message, new Date().toISOString());

    // Send message via SSE (include web search active state)
    await sendMessageWithSSE(conversationId, message, webSearchActive);

    // Reset send button
    resetSendButton();

    // Focus on input
    messageInput.focus();
});

// Handle cancel button click
function handleCancelClick(e) {
    e.preventDefault();
    if (cancelCurrentRequest()) {
        resetSendButton();
        showToast('Request cancelled', 'info');
    }
}

// Reset send button to original state
function resetSendButton() {
    const sendBtn = document.getElementById('send-btn');
    sendBtn.classList.remove('btn-warning');
    sendBtn.classList.add('btn-primary');
    sendBtn.innerHTML = '<i class="bi bi-send-fill"></i> Send';
    sendBtn.onclick = null;  // Remove cancel handler
    sendBtn.type = 'submit';  // Restore form submission
    sendBtn.disabled = false;
}

// Handle Escape key to cancel request
document.addEventListener('keydown', (e) => {
    if (e.key === 'Escape' && isRequestInProgress()) {
        e.preventDefault();
        if (cancelCurrentRequest()) {
            resetSendButton();
            showToast('Request cancelled (Escape)', 'info');
        }
    }
});

// Show command menu
function showCommandMenu() {
    const modal = new bootstrap.Modal(document.getElementById('commandModal'));
    modal.show();
}

// Execute command
async function executeCommand(command) {
    // Close modal
    bootstrap.Modal.getInstance(document.getElementById('commandModal')).hide();

    // Execute command based on type
    switch (command) {
        case 'info':
            await loadConversationInfo();
            const infoModal = new bootstrap.Modal(document.getElementById('infoModal'));
            infoModal.show();
            break;
        case 'history':
            await loadChatHistory(conversationId);
            break;
        case 'export':
            await showExportModal();
            break;
        case 'changemodel':
            await showChangeModelModal();
            break;
        case 'attach':
            await showAttachFilesModal();
            break;
        case 'instructions':
            await showInstructionsModal();
            break;
        case 'copy':
            await copyLastResponse();
            break;
        case 'deletefiles':
            await showDeleteFilesModal();
            break;
        case 'compaction':
            await showCompactionSettingsModal();
            break;
        case 'delete':
            await confirmDeleteConversation();
            break;
        case 'mcpaudit':
            await showMCPAuditModal();
            break;
        case 'mcpservers':
            await showMCPServersModal();
            break;
        default:
            alert(`Command '${command}' not yet implemented in web UI`);
    }
}

// Export conversation
async function showExportModal() {
    const modalHTML = `
        <div class="modal fade" id="exportModal" tabindex="-1">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title"><i class="bi bi-download"></i> Export Conversation</h5>
                        <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                    </div>
                    <div class="modal-body">
                        <div class="mb-3">
                            <label class="form-label">Export Format</label>
                            <select class="form-select" id="export-format">
                                <option value="markdown">Markdown (.md)</option>
                                <option value="html">HTML (.html)</option>
                                <option value="csv">CSV (.csv)</option>
                            </select>
                        </div>
                        <div class="form-check">
                            <input class="form-check-input" type="checkbox" id="export-include-tools" checked>
                            <label class="form-check-label" for="export-include-tools">
                                Include tool call details
                            </label>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
                        <button type="button" class="btn btn-primary" onclick="performExport()">
                            <i class="bi bi-download"></i> Export
                        </button>
                    </div>
                </div>
            </div>
        </div>
    `;

    // Remove old modal if exists
    const oldModal = document.getElementById('exportModal');
    if (oldModal) oldModal.remove();

    document.body.insertAdjacentHTML('beforeend', modalHTML);
    const modal = new bootstrap.Modal(document.getElementById('exportModal'));
    modal.show();
}

async function performExport() {
    const format = document.getElementById('export-format').value;
    const includeTools = document.getElementById('export-include-tools').checked;

    try {
        const formData = new FormData();
        formData.append('format', format);
        formData.append('include_tools', includeTools);

        const response = await fetch(`/api/chat/${conversationId}/command/export`, {
            method: 'POST',
            body: formData
        });

        const data = await response.json();

        if (data.status === 'success') {
            // Download file
            const blob = new Blob([data.content], { type: 'text/plain' });
            const url = window.URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = `conversation_${conversationId}.${data.format === 'markdown' ? 'md' : data.format}`;
            document.body.appendChild(a);
            a.click();
            window.URL.revokeObjectURL(url);
            a.remove();

            // Close modal
            bootstrap.Modal.getInstance(document.getElementById('exportModal')).hide();
            showToast('Conversation exported successfully', 'success');
        }
    } catch (error) {
        showToast('Failed to export conversation', 'error');
    }
}

// Change model
async function showChangeModelModal() {
    // Check if model is locked first
    try {
        const configResponse = await fetch('/api/models');
        const configData = await configResponse.json();

        if (configData.model_locked) {
            showToast(`Model changing is disabled - model is locked to '${configData.mandatory_model}' via configuration`, 'error');
            return;
        }

        const models = configData.models || configData;

        const modalHTML = `
            <div class="modal fade" id="changeModelModal" tabindex="-1">
                <div class="modal-dialog">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h5 class="modal-title"><i class="bi bi-arrow-repeat"></i> Change Model</h5>
                            <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                        </div>
                        <div class="modal-body">
                            <div class="mb-3">
                                <label class="form-label">Select New Model</label>
                                <select class="form-select" id="new-model-select">
                                    <option value="">Select a model...</option>
                                </select>
                            </div>
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
                            <button type="button" class="btn btn-primary" onclick="performChangeModel()">
                                <i class="bi bi-check-circle-fill"></i> Change Model
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        `;

        // Remove old modal if exists
        const oldModal = document.getElementById('changeModelModal');
        if (oldModal) oldModal.remove();

        document.body.insertAdjacentHTML('beforeend', modalHTML);

        const select = document.getElementById('new-model-select');
        models.forEach(model => {
            const option = document.createElement('option');
            option.value = model.id;

            let displayText = model.name;
            if (model.model_maker && model.provider !== model.model_maker) {
                displayText += ` [${model.model_maker} via ${model.provider}]`;
            } else {
                displayText += ` [${model.provider}]`;
            }

            option.textContent = displayText;
            select.appendChild(option);
        });

        const modal = new bootstrap.Modal(document.getElementById('changeModelModal'));
        modal.show();
    } catch (error) {
        showToast('Failed to load models', 'error');
    }
}

async function performChangeModel() {
    const modelId = document.getElementById('new-model-select').value;

    if (!modelId) {
        showToast('Please select a model', 'error');
        return;
    }

    try {
        const formData = new FormData();
        formData.append('model_id', modelId);

        const response = await fetch(`/api/chat/${conversationId}/command/changemodel`, {
            method: 'POST',
            body: formData
        });

        const data = await response.json();

        if (data.status === 'success') {
            bootstrap.Modal.getInstance(document.getElementById('changeModelModal')).hide();
            showToast('Model changed successfully', 'success');
        }
    } catch (error) {
        showToast('Failed to change model', 'error');
    }
}

// MCP Audit Log
async function showMCPAuditModal() {
    const modalHTML = `
        <div class="modal fade" id="mcpAuditModal" tabindex="-1">
            <div class="modal-dialog modal-xl">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title"><i class="bi bi-shield-check"></i> MCP Audit Log</h5>
                        <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                    </div>
                    <div class="modal-body" id="mcp-audit-content">
                        <div class="text-center">
                            <output class="spinner-border spinner-border-sm"></output>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    `;

    // Remove old modal if exists
    const oldModal = document.getElementById('mcpAuditModal');
    if (oldModal) oldModal.remove();

    document.body.insertAdjacentHTML('beforeend', modalHTML);

    // Load audit log
    try {
        const response = await fetch(`/api/chat/${conversationId}/command/mcpaudit`);
        const data = await response.json();

        const transactions = data.data.transactions;

        let html = '';
        if (transactions.length === 0) {
            html = '<p class="text-muted">No MCP transactions recorded</p>';
        } else {
            html = `
                <div class="table-responsive">
                    <table class="table table-sm table-striped">
                        <thead>
                            <tr>
                                <th>Time</th>
                                <th>Tool</th>
                                <th>Server</th>
                                <th>Status</th>
                                <th>Exec Time</th>
                            </tr>
                        </thead>
                        <tbody>
            `;

            transactions.forEach(tx => {
                const timestamp = new Date(tx.transaction_timestamp).toLocaleString();
                const status = tx.is_error ? '<span class="badge bg-danger">Error</span>' : '<span class="badge bg-success">Success</span>';

                html += `
                    <tr>
                        <td class="small">${timestamp}</td>
                        <td><code class="small">${escapeHtml(tx.tool_name)}</code></td>
                        <td class="small">${escapeHtml(tx.tool_server)}</td>
                        <td>${status}</td>
                        <td class="small">${tx.execution_time_ms}ms</td>
                    </tr>
                `;
            });

            html += `
                        </tbody>
                    </table>
                </div>
            `;
        }

        document.getElementById('mcp-audit-content').innerHTML = html;
    } catch (error) {
        document.getElementById('mcp-audit-content').innerHTML = `
            <div class="alert alert-danger">Failed to load MCP audit log</div>
        `;
    }

    const modal = new bootstrap.Modal(document.getElementById('mcpAuditModal'));
    modal.show();
}

// MCP Server Management
async function showMCPServersModal() {
    const modalHTML = `
        <div class="modal fade" id="mcpServersModal" tabindex="-1">
            <div class="modal-dialog modal-lg">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title"><i class="bi bi-hdd-network"></i> MCP Server Management</h5>
                        <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                    </div>
                    <div class="modal-body" id="mcp-servers-content">
                        <div class="text-center">
                            <output class="spinner-border spinner-border-sm"></output>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    `;

    // Remove old modal if exists
    const oldModal = document.getElementById('mcpServersModal');
    if (oldModal) oldModal.remove();

    document.body.insertAdjacentHTML('beforeend', modalHTML);

    // Load server states
    try {
        const response = await fetch(`/api/chat/${conversationId}/command/mcpservers`);
        const data = await response.json();

        const servers = data.data.servers;

        let html = '';
        if (servers.length === 0) {
            html = '<p class="text-muted">No MCP servers configured</p>';
        } else {
            html = '<div class="list-group">';

            servers.forEach(server => {
                const enabled = server.enabled;
                const badge = enabled ?
                    '<span class="badge bg-success">Enabled</span>' :
                    '<span class="badge bg-secondary">Disabled</span>';

                html += `
                    <div class="list-group-item">
                        <div class="d-flex justify-content-between align-items-center">
                            <div>
                                <h6 class="mb-1">${escapeHtml(server.server_name)}</h6>
                                ${badge}
                            </div>
                            <div class="form-check form-switch">
                                <input
                                    class="form-check-input"
                                    type="checkbox"
                                    id="server-${escapeHtml(server.server_name)}"
                                    ${enabled ? 'checked' : ''}
                                    onchange="toggleMCPServer('${escapeHtml(server.server_name)}', this.checked)"
                                >
                            </div>
                        </div>
                    </div>
                `;
            });

            html += '</div>';
        }

        document.getElementById('mcp-servers-content').innerHTML = html;
    } catch (error) {
        document.getElementById('mcp-servers-content').innerHTML = `
            <div class="alert alert-danger">Failed to load MCP servers</div>
        `;
    }

    const modal = new bootstrap.Modal(document.getElementById('mcpServersModal'));
    modal.show();
}

async function toggleMCPServer(serverName, enabled) {
    try {
        const formData = new FormData();
        formData.append('server_name', serverName);
        formData.append('enabled', enabled);

        const response = await fetch(`/api/chat/${conversationId}/command/mcpservers/toggle`, {
            method: 'POST',
            body: formData
        });

        const data = await response.json();

        if (data.status === 'success') {
            showToast(`Server ${serverName} ${enabled ? 'enabled' : 'disabled'}`, 'success');
        }
    } catch (error) {
        showToast('Failed to toggle server', 'error');
    }
}

// Load conversation info
async function loadConversationInfo() {
    try {
        document.getElementById('info-content').innerHTML = `
            <div class="text-center">
                <output class="spinner-border spinner-border-sm">
                    <span class="visually-hidden">Loading...</span>
                </output>
            </div>
        `;

        const response = await fetch(`/api/chat/${conversationId}/command/info`, {
            method: 'POST'
        });
        const data = await response.json();

        const conv = data.data.conversation;
        const modelUsage = data.data.model_usage;
        const rollupSettings = data.data.rollup_settings;

        let infoHTML = `
            <div class="mb-3">
                <h6>Conversation Details</h6>
                <ul class="list-unstyled small">
                    <li><strong>Name:</strong> ${conv.name}</li>
                    <li><strong>Model:</strong> <code>${conv.model_id}</code></li>
                    <li><strong>Created:</strong> ${new Date(conv.created_at).toLocaleString()}</li>
                    <li><strong>Total Tokens:</strong> ${conv.total_tokens.toLocaleString()}</li>
                </ul>
            </div>
        `;

        if (modelUsage && modelUsage.length > 0) {
            infoHTML += `
                <div class="mb-3">
                    <h6>Model Usage</h6>
                    <div class="table-responsive">
                        <table class="table table-sm">
                            <thead>
                                <tr>
                                    <th>Model</th>
                                    <th>Input</th>
                                    <th>Output</th>
                                    <th>Total</th>
                                </tr>
                            </thead>
                            <tbody>
            `;

            modelUsage.forEach(usage => {
                infoHTML += `
                    <tr>
                        <td><code class="small">${usage.model_id}</code></td>
                        <td>${usage.input_tokens.toLocaleString()}</td>
                        <td>${usage.output_tokens.toLocaleString()}</td>
                        <td>${usage.total_tokens.toLocaleString()}</td>
                    </tr>
                `;
            });

            infoHTML += `
                            </tbody>
                        </table>
                    </div>
                </div>
            `;
        }

        // Add rollup/compaction settings
        if (rollupSettings && !rollupSettings.error) {
            const usagePercent = rollupSettings.context_usage_percent || 0;
            const compactionThresholdPercent = (rollupSettings.compaction_threshold * 100).toFixed(0);
            const emergencyThresholdPercent = (rollupSettings.emergency_threshold * 100).toFixed(0);

            // Determine status colour based on usage
            let statusClass = 'text-success';
            let statusText = 'Normal';
            if (usagePercent >= rollupSettings.emergency_threshold * 100) {
                statusClass = 'text-danger';
                statusText = 'Emergency';
            } else if (usagePercent >= rollupSettings.compaction_threshold * 100) {
                statusClass = 'text-warning';
                statusText = 'Compaction Due';
            }

            infoHTML += `
                <div class="mb-3">
                    <h6>Context &amp; Rollup Settings</h6>
                    <div class="small">
                        <div class="mb-2">
                            <strong>Context Usage:</strong>
                            <span class="${statusClass}">${usagePercent}%</span>
                            <span class="text-muted">(${rollupSettings.current_tokens?.toLocaleString() || 0} / ${rollupSettings.context_window?.toLocaleString() || 0} tokens)</span>
                            <span class="badge ${statusClass === 'text-success' ? 'bg-success' : statusClass === 'text-warning' ? 'bg-warning text-dark' : 'bg-danger'}">${statusText}</span>
                        </div>
                        <div class="progress mb-2" style="height: 8px;">
                            <div class="progress-bar ${usagePercent >= rollupSettings.emergency_threshold * 100 ? 'bg-danger' : usagePercent >= rollupSettings.compaction_threshold * 100 ? 'bg-warning' : 'bg-success'}"
                                 role="progressbar"
                                 style="width: ${Math.min(usagePercent, 100)}%">
                            </div>
                            <div class="position-absolute" style="left: ${compactionThresholdPercent}%; width: 2px; height: 8px; background-color: orange; top: 0;"></div>
                            <div class="position-absolute" style="left: ${emergencyThresholdPercent}%; width: 2px; height: 8px; background-color: red; top: 0;"></div>
                        </div>
                        <ul class="list-unstyled mb-0">
                            <li><strong>Context Window:</strong> ${rollupSettings.context_window?.toLocaleString() || 'Unknown'} tokens</li>
                            <li><strong>Max Output:</strong> ${rollupSettings.max_output?.toLocaleString() || 'Unknown'} tokens</li>
                            <li><strong>Compaction Threshold:</strong> ${compactionThresholdPercent}% (${rollupSettings.compaction_trigger_tokens?.toLocaleString() || 0} tokens)</li>
                            <li><strong>Emergency Threshold:</strong> ${emergencyThresholdPercent}% (${rollupSettings.emergency_trigger_tokens?.toLocaleString() || 0} tokens)</li>
                            <li><strong>Provider:</strong> ${rollupSettings.provider || 'Unknown'}</li>
                        </ul>
                    </div>
                </div>
            `;
        } else if (rollupSettings && rollupSettings.error) {
            infoHTML += `
                <div class="mb-3">
                    <h6>Context &amp; Rollup Settings</h6>
                    <p class="text-muted small">Unable to load rollup settings: ${rollupSettings.error}</p>
                </div>
            `;
        }

        document.getElementById('info-content').innerHTML = infoHTML;

    } catch (error) {
        document.getElementById('info-content').innerHTML = `
            <div class="alert alert-danger">
                <i class="bi bi-exclamation-triangle-fill"></i> Failed to load conversation info
            </div>
        `;
    }
}

// Attach files
function showAttachFilesModal() {
    const modalHTML = `
        <div class="modal fade" id="attachFilesModal" tabindex="-1">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title"><i class="bi bi-paperclip"></i> Attach Files</h5>
                        <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                    </div>
                    <div class="modal-body">
                        <div class="mb-3">
                            <label class="form-label">Select files to attach</label>
                            <input type="file" class="form-control" id="attach-files-input" multiple>
                            <div class="form-text">
                                Supported formats: txt, md, json, yaml, yml, xml, csv, log, py, js, ts, java, cpp, c, h
                            </div>
                        </div>
                        <div id="attach-files-list" class="mb-3"></div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
                        <button type="button" class="btn btn-primary" onclick="performAttachFiles()">
                            <i class="bi bi-paperclip"></i> Attach Files
                        </button>
                    </div>
                </div>
            </div>
        </div>
    `;

    // Remove old modal if exists
    const oldModal = document.getElementById('attachFilesModal');
    if (oldModal) oldModal.remove();

    document.body.insertAdjacentHTML('beforeend', modalHTML);

    // Add file selection change listener
    const fileInput = document.getElementById('attach-files-input');
    fileInput.addEventListener('change', function() {
        const filesList = document.getElementById('attach-files-list');
        if (this.files.length > 0) {
            let html = '<div class="alert alert-info"><strong>Selected files:</strong><ul class="mb-0 mt-2">';
            for (let i = 0; i < this.files.length; i++) {
                html += `<li>${this.files[i].name} (${(this.files[i].size / 1024).toFixed(2)} KB)</li>`;
            }
            html += '</ul></div>';
            filesList.innerHTML = html;
        } else {
            filesList.innerHTML = '';
        }
    });

    const modal = new bootstrap.Modal(document.getElementById('attachFilesModal'));
    modal.show();
}

async function performAttachFiles() {
    const fileInput = document.getElementById('attach-files-input');

    if (!fileInput.files || fileInput.files.length === 0) {
        showToast('Please select at least one file', 'error');
        return;
    }

    try {
        const formData = new FormData();

        // Add all selected files
        for (let i = 0; i < fileInput.files.length; i++) {
            formData.append('files', fileInput.files[i]);
        }

        const response = await fetch(`/api/chat/${conversationId}/command/attach`, {
            method: 'POST',
            body: formData
        });

        const data = await response.json();

        if (data.status === 'success' || data.status === 'partial') {
            // Close modal
            bootstrap.Modal.getInstance(document.getElementById('attachFilesModal')).hide();

            // Show success message
            const message = data.status === 'success'
                ? `Successfully attached ${data.data.files.length} file(s)`
                : `${data.message} - Some files may have failed`;
            showToast(message, data.status === 'success' ? 'success' : 'warning');

            // Reload conversation info to show updated file list
            await loadConversationInfo();
        } else {
            showToast(data.message || 'Failed to attach files', 'error');
        }
    } catch (error) {
        console.error('Error attaching files:', error);
        showToast('Failed to attach files', 'error');
    }
}

function attachFiles() {
    showAttachFilesModal();
}

// Show instructions modal
async function showInstructionsModal() {
    try {
        // Load current instructions
        const response = await fetch(`/api/chat/${conversationId}/command/info`, {
            method: 'POST'
        });
        const data = await response.json();
        const currentInstructions = data.data.conversation.instructions || '';

        const modalHTML = `
            <div class="modal fade" id="instructionsModal" tabindex="-1">
                <div class="modal-dialog modal-lg">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h5 class="modal-title"><i class="bi bi-card-text"></i> Change Instructions</h5>
                            <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                        </div>
                        <div class="modal-body">
                            <div class="mb-3">
                                <label for="instructions-text" class="form-label">System Instructions / Prompt</label>
                                <textarea class="form-control" id="instructions-text" rows="10"
                                    placeholder="Enter system instructions for this conversation...">${escapeHtml(currentInstructions)}</textarea>
                                <div class="form-text">These instructions are sent as a system prompt with each message.</div>
                            </div>
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-outline-warning" onclick="clearInstructions()">
                                <i class="bi bi-eraser"></i> Clear
                            </button>
                            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
                            <button type="button" class="btn btn-primary" onclick="saveInstructions()">
                                <i class="bi bi-check-lg"></i> Save
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        `;

        // Remove old modal if exists
        const oldModal = document.getElementById('instructionsModal');
        if (oldModal) oldModal.remove();

        document.body.insertAdjacentHTML('beforeend', modalHTML);
        const modal = new bootstrap.Modal(document.getElementById('instructionsModal'));
        modal.show();
    } catch (error) {
        showToast('Failed to load instructions', 'error');
    }
}

async function saveInstructions() {
    const instructions = document.getElementById('instructions-text').value;

    try {
        const formData = new FormData();
        formData.append('instructions', instructions);

        const response = await fetch(`/api/chat/${conversationId}/command/instructions`, {
            method: 'POST',
            body: formData
        });

        const data = await response.json();

        if (data.status === 'success') {
            bootstrap.Modal.getInstance(document.getElementById('instructionsModal')).hide();
            showToast('Instructions updated successfully', 'success');
        } else {
            showToast(data.message || 'Failed to update instructions', 'error');
        }
    } catch (error) {
        showToast('Failed to update instructions', 'error');
    }
}

async function clearInstructions() {
    if (!confirm('Are you sure you want to clear the instructions?')) return;

    try {
        const formData = new FormData();
        formData.append('instructions', '');

        const response = await fetch(`/api/chat/${conversationId}/command/instructions`, {
            method: 'POST',
            body: formData
        });

        const data = await response.json();

        if (data.status === 'success') {
            document.getElementById('instructions-text').value = '';
            showToast('Instructions cleared', 'success');
        } else {
            showToast(data.message || 'Failed to clear instructions', 'error');
        }
    } catch (error) {
        showToast('Failed to clear instructions', 'error');
    }
}

// Show compaction settings modal
async function showCompactionSettingsModal() {
    try {
        // Load current compaction settings and available models in parallel
        const [settingsResponse, modelsResponse] = await Promise.all([
            fetch(`/api/chat/${conversationId}/command/compaction`, { method: 'GET' }),
            fetch('/api/models')
        ]);

        const settingsData = await settingsResponse.json();
        const modelsData = await modelsResponse.json();

        const settings = settingsData.data;
        const models = modelsData.models || modelsData;

        const modelLocked = settings.model_locked;
        const lockedModel = settings.locked_model;
        const currentModel = settings.model || '';
        const threshold = (settings.threshold * 100).toFixed(0);
        const ratio = (settings.summary_ratio * 100).toFixed(0);

        const modelDisabledAttr = modelLocked ? 'disabled' : '';
        const modelLockNote = modelLocked
            ? `<div class="text-muted small mt-1"><i class="bi bi-lock"></i> Model locked to: <code>${escapeHtml(lockedModel)}</code></div>`
            : '';

        // Build model options HTML
        let modelOptionsHtml = '<option value="">Use conversation model</option>';
        models.forEach(model => {
            const selected = model.id === currentModel ? 'selected' : '';
            let displayText = model.name;
            if (model.model_maker && model.provider !== model.model_maker) {
                displayText += ` [${model.model_maker} via ${model.provider}]`;
            } else if (model.provider) {
                displayText += ` [${model.provider}]`;
            }
            modelOptionsHtml += `<option value="${escapeHtml(model.id)}" ${selected}>${escapeHtml(displayText)}</option>`;
        });

        const modalHTML = `
            <div class="modal fade" id="compactionModal" tabindex="-1">
                <div class="modal-dialog">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h5 class="modal-title"><i class="bi bi-layers"></i> Compaction Settings</h5>
                            <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                        </div>
                        <div class="modal-body">
                            <div class="mb-3">
                                <label for="compaction-model" class="form-label">Compaction Model</label>
                                <select class="form-select" id="compaction-model" ${modelDisabledAttr}>
                                    ${modelOptionsHtml}
                                </select>
                                ${modelLockNote}
                                <div class="form-text">The model used for generating compaction summaries.</div>
                            </div>
                            <div class="mb-3">
                                <label for="compaction-threshold" class="form-label">Compaction Threshold</label>
                                <div class="input-group">
                                    <input type="number" class="form-control" id="compaction-threshold"
                                        min="5" max="95" step="5" value="${threshold}">
                                    <span class="input-group-text">%</span>
                                </div>
                                <div class="form-text">Trigger compaction when context reaches this % of the window.</div>
                            </div>
                            <div class="mb-3">
                                <label for="compaction-ratio" class="form-label">Summary Ratio</label>
                                <div class="input-group">
                                    <input type="number" class="form-control" id="compaction-ratio"
                                        min="5" max="90" step="5" value="${ratio}">
                                    <span class="input-group-text">%</span>
                                </div>
                                <div class="form-text">Target size for compacted summaries as % of original.</div>
                            </div>
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
                            <button type="button" class="btn btn-primary" onclick="saveCompactionSettings()">
                                <i class="bi bi-check-lg"></i> Save
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        `;

        // Remove old modal if exists
        const oldModal = document.getElementById('compactionModal');
        if (oldModal) oldModal.remove();

        document.body.insertAdjacentHTML('beforeend', modalHTML);
        const modal = new bootstrap.Modal(document.getElementById('compactionModal'));
        modal.show();
    } catch (error) {
        console.error('Error loading compaction settings:', error);
        showToast('Failed to load compaction settings', 'error');
    }
}

async function saveCompactionSettings() {
    const modelInput = document.getElementById('compaction-model');
    const thresholdInput = document.getElementById('compaction-threshold');
    const ratioInput = document.getElementById('compaction-ratio');

    const model = modelInput.value.trim();
    const threshold = parseFloat(thresholdInput.value) / 100;
    const ratio = parseFloat(ratioInput.value) / 100;

    let errors = [];

    // Save threshold
    try {
        const thresholdFormData = new FormData();
        thresholdFormData.append('threshold', threshold.toString());
        const thresholdResponse = await fetch(`/api/chat/${conversationId}/command/compaction-threshold`, {
            method: 'POST',
            body: thresholdFormData
        });
        const thresholdData = await thresholdResponse.json();
        if (thresholdData.status !== 'success') {
            errors.push(thresholdData.message || 'Failed to save threshold');
        }
    } catch (error) {
        errors.push('Failed to save threshold');
    }

    // Save ratio
    try {
        const ratioFormData = new FormData();
        ratioFormData.append('ratio', ratio.toString());
        const ratioResponse = await fetch(`/api/chat/${conversationId}/command/compaction-ratio`, {
            method: 'POST',
            body: ratioFormData
        });
        const ratioData = await ratioResponse.json();
        if (ratioData.status !== 'success') {
            errors.push(ratioData.message || 'Failed to save ratio');
        }
    } catch (error) {
        errors.push('Failed to save ratio');
    }

    // Save model if not locked and has value
    if (!modelInput.disabled && model) {
        try {
            const modelFormData = new FormData();
            modelFormData.append('model_id', model);
            const modelResponse = await fetch(`/api/chat/${conversationId}/command/compaction-model`, {
                method: 'POST',
                body: modelFormData
            });
            const modelData = await modelResponse.json();
            if (modelData.status !== 'success') {
                errors.push(modelData.message || 'Failed to save model');
            }
        } catch (error) {
            errors.push('Failed to save model');
        }
    }

    // Close modal and show result
    bootstrap.Modal.getInstance(document.getElementById('compactionModal')).hide();

    if (errors.length === 0) {
        showToast('Compaction settings saved successfully', 'success');
    } else {
        showToast(errors.join('; '), 'error');
    }
}

// Copy last response to clipboard
async function copyLastResponse() {
    // Find the last assistant message in the chat
    const chatContainer = document.getElementById('chat-container');
    const assistantMessages = chatContainer.querySelectorAll('.assistant-message');

    if (assistantMessages.length === 0) {
        showToast('No assistant response to copy', 'warning');
        return;
    }

    const lastMessage = assistantMessages[assistantMessages.length - 1];
    const messageContent = lastMessage.querySelector('.message-content');

    if (!messageContent) {
        showToast('No content to copy', 'warning');
        return;
    }

    try {
        // Get the text content, preserving some formatting
        const text = messageContent.innerText || messageContent.textContent;
        await navigator.clipboard.writeText(text);
        showToast('Response copied to clipboard', 'success');
    } catch (error) {
        // Fallback for older browsers
        const textarea = document.createElement('textarea');
        textarea.value = messageContent.innerText || messageContent.textContent;
        document.body.appendChild(textarea);
        textarea.select();
        document.execCommand('copy');
        document.body.removeChild(textarea);
        showToast('Response copied to clipboard', 'success');
    }
}

// Show delete files modal
async function showDeleteFilesModal() {
    try {
        // Load attached files
        const response = await fetch(`/api/chat/${conversationId}/command/info`, {
            method: 'POST'
        });
        const data = await response.json();
        const files = data.data.attached_files || [];

        if (files.length === 0) {
            showToast('No files attached to this conversation', 'info');
            return;
        }

        let filesHTML = '';
        files.forEach(file => {
            filesHTML += `
                <div class="form-check">
                    <input class="form-check-input file-delete-checkbox" type="checkbox" value="${file.id}" id="file-${file.id}">
                    <label class="form-check-label" for="file-${file.id}">
                        <i class="bi bi-file-earmark"></i> ${escapeHtml(file.filename)}
                        <span class="text-muted small">(${(file.size_bytes / 1024).toFixed(2)} KB)</span>
                    </label>
                </div>
            `;
        });

        const modalHTML = `
            <div class="modal fade" id="deleteFilesModal" tabindex="-1">
                <div class="modal-dialog">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h5 class="modal-title"><i class="bi bi-file-earmark-x text-warning"></i> Delete Attached Files</h5>
                            <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                        </div>
                        <div class="modal-body">
                            <p>Select files to delete:</p>
                            <div class="mb-3">
                                <button class="btn btn-sm btn-outline-secondary me-2" onclick="toggleAllDeleteFiles(true)">Select All</button>
                                <button class="btn btn-sm btn-outline-secondary" onclick="toggleAllDeleteFiles(false)">Deselect All</button>
                            </div>
                            <div id="delete-files-list">
                                ${filesHTML}
                            </div>
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
                            <button type="button" class="btn btn-danger" onclick="performDeleteFiles()">
                                <i class="bi bi-trash"></i> Delete Selected
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        `;

        // Remove old modal if exists
        const oldModal = document.getElementById('deleteFilesModal');
        if (oldModal) oldModal.remove();

        document.body.insertAdjacentHTML('beforeend', modalHTML);
        const modal = new bootstrap.Modal(document.getElementById('deleteFilesModal'));
        modal.show();
    } catch (error) {
        showToast('Failed to load attached files', 'error');
    }
}

function toggleAllDeleteFiles(checked) {
    document.querySelectorAll('.file-delete-checkbox').forEach(cb => cb.checked = checked);
}

async function performDeleteFiles() {
    const checkboxes = document.querySelectorAll('.file-delete-checkbox:checked');
    const fileIds = Array.from(checkboxes).map(cb => cb.value);

    if (fileIds.length === 0) {
        showToast('Please select at least one file to delete', 'warning');
        return;
    }

    if (!confirm(`Are you sure you want to delete ${fileIds.length} file(s)?`)) return;

    try {
        const response = await fetch(`/api/chat/${conversationId}/command/deletefiles`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ file_ids: fileIds.map(id => parseInt(id)) })
        });

        const data = await response.json();

        if (data.status === 'success') {
            bootstrap.Modal.getInstance(document.getElementById('deleteFilesModal')).hide();
            showToast(`Deleted ${data.data.deleted_count} file(s)`, 'success');
        } else {
            showToast(data.message || 'Failed to delete files', 'error');
        }
    } catch (error) {
        showToast('Failed to delete files', 'error');
    }
}

// Confirm and delete conversation
async function confirmDeleteConversation() {
    if (!confirm('Are you sure you want to delete this conversation? This cannot be undone.')) return;

    try {
        const response = await fetch(`/api/conversations/${conversationId}`, {
            method: 'DELETE'
        });

        const data = await response.json();

        if (data.status === 'success') {
            showToast('Conversation deleted', 'success');
            // Redirect to main menu after a short delay
            setTimeout(() => {
                window.location.href = '/';
            }, 1000);
        } else {
            showToast(data.message || 'Failed to delete conversation', 'error');
        }
    } catch (error) {
        showToast('Failed to delete conversation', 'error');
    }
}
</script>
{% endblock %}
