// ============================================================================
// Miku Control Panel — Chat Interface + Voice Call Module
// ============================================================================

// Toggle image upload section based on model type
function toggleChatImageUpload() {
  const modelType = document.querySelector('input[name="chat-model-type"]:checked').value;
  const imageUploadSection = document.getElementById('chat-image-upload-section');

  if (modelType === 'vision') {
    imageUploadSection.style.display = 'block';
  } else {
    imageUploadSection.style.display = 'none';
  }
}

// Load voice debug mode setting from server
async function loadVoiceDebugMode() {
  try {
    const data = await apiCall('/voice/debug-mode');
    const checkbox = document.getElementById('voice-debug-mode');
    if (checkbox && data.debug_mode !== undefined) {
      checkbox.checked = data.debug_mode;
    }
  } catch (error) {
    console.error('Failed to load voice debug mode:', error);
  }
}

// Handle Enter key in chat input
function handleChatKeyPress(event) {
  if (event.ctrlKey && event.key === 'Enter') {
    event.preventDefault();
    sendChatMessage();
  }
}

// Clear chat history
function clearChatHistory() {
  if (confirm('Are you sure you want to clear all chat messages?')) {
    const chatMessages = document.getElementById('chat-messages');
    chatMessages.innerHTML = `
      <div style="text-align: center; color: #888; padding: 2rem;">
        💬 Start chatting with the LLM! Your conversation will appear here.
      </div>
    `;
    // Clear conversation history array
    chatConversationHistory = [];
    showNotification('Chat history cleared');
  }
}

// Add a message to the chat display
function addChatMessage(sender, content, isError = false) {
  const chatMessages = document.getElementById('chat-messages');

  // Remove welcome message if it exists
  const welcomeMsg = chatMessages.querySelector('div[style*="text-align: center"]');
  if (welcomeMsg) {
    welcomeMsg.remove();
  }

  const messageDiv = document.createElement('div');
  const messageClass = isError ? 'error-message' : (sender === 'You' ? 'user-message' : 'assistant-message');
  messageDiv.className = `chat-message ${messageClass}`;

  const timestamp = new Date().toLocaleTimeString();

  messageDiv.innerHTML = `
    <div class="chat-message-header">
      <span class="chat-message-sender">${escapeHtml(sender)}</span>
      <span class="chat-message-time">${timestamp}</span>
    </div>
    <div class="chat-message-content"></div>
  `;

  // Set content via textContent to prevent XSS
  messageDiv.querySelector('.chat-message-content').textContent = content;

  chatMessages.appendChild(messageDiv);

  // Scroll to bottom
  chatMessages.scrollTop = chatMessages.scrollHeight;

  return messageDiv;
}

// Add typing indicator
function showTypingIndicator() {
  const chatMessages = document.getElementById('chat-messages');

  const typingDiv = document.createElement('div');
  typingDiv.id = 'chat-typing-indicator';
  typingDiv.className = 'chat-message assistant-message';
  typingDiv.innerHTML = `
    <div class="chat-message-header">
      <span class="chat-message-sender">Miku</span>
      <span class="chat-message-time">typing...</span>
    </div>
    <div class="chat-typing-indicator">
      <span></span>
      <span></span>
      <span></span>
    </div>
  `;

  chatMessages.appendChild(typingDiv);
  chatMessages.scrollTop = chatMessages.scrollHeight;
}

// Remove typing indicator
function hideTypingIndicator() {
  const typingIndicator = document.getElementById('chat-typing-indicator');
  if (typingIndicator) {
    typingIndicator.remove();
  }
}

// Send chat message with streaming support
async function sendChatMessage() {
  const input = document.getElementById('chat-input');
  const message = input.value.trim();

  if (!message) {
    showNotification('Please enter a message', 'error');
    return;
  }

  // Get configuration
  const modelType = document.querySelector('input[name="chat-model-type"]:checked').value;
  const useSystemPrompt = document.querySelector('input[name="chat-system-prompt"]:checked').value === 'true';
  const selectedMood = document.getElementById('chat-mood-select').value;

  // Get image data if vision model
  let imageData = null;
  if (modelType === 'vision') {
    const imageFile = document.getElementById('chat-image-file').files[0];
    if (imageFile) {
      try {
        imageData = await readFileAsBase64(imageFile);
        // Remove data URL prefix if present
        if (imageData.includes(',')) {
          imageData = imageData.split(',')[1];
        }
      } catch (error) {
        showNotification('Failed to read image file', 'error');
        return;
      }
    }
  }

  // Disable send button
  const sendBtn = document.getElementById('chat-send-btn');
  const originalBtnText = sendBtn.innerHTML;
  sendBtn.disabled = true;
  sendBtn.innerHTML = '⏳ Sending...';

  // Add user message to display
  addChatMessage('You', message);

  // Clear input
  input.value = '';

  // Show typing indicator
  showTypingIndicator();

  try {
    // Build user message for history
    let userMessageContent;
    if (modelType === 'vision' && imageData) {
      // Vision model with image - store as multimodal content
      userMessageContent = [
        {
          "type": "text",
          "text": message
        },
        {
          "type": "image_url",
          "image_url": {
            "url": `data:image/jpeg;base64,${imageData}`
          }
        }
      ];
    } else {
      // Text-only message
      userMessageContent = message;
    }

    // Prepare request payload with conversation history
    const payload = {
      message: message,
      model_type: modelType,
      use_system_prompt: useSystemPrompt,
      image_data: imageData,
      conversation_history: chatConversationHistory,
      mood: selectedMood
    };

    // Make streaming request
    const response = await fetch('/chat/stream', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(payload)
    });

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

    // Hide typing indicator
    hideTypingIndicator();

    // Create message element for streaming response
    const assistantName = useSystemPrompt ? 'Miku' : 'LLM';
    const responseDiv = addChatMessage(assistantName, '');
    const contentDiv = responseDiv.querySelector('.chat-message-content');

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

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

      if (done) break;

      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 dataStr = line.slice(6);
          try {
            const data = JSON.parse(dataStr);

            if (data.error) {
              contentDiv.textContent = `❌ Error: ${data.error}`;
              responseDiv.classList.add('error-message');
              break;
            }

            if (data.content) {
              fullResponse += data.content;
              contentDiv.textContent = fullResponse;

              // Auto-scroll
              const chatMessages = document.getElementById('chat-messages');
              chatMessages.scrollTop = chatMessages.scrollHeight;
            }

            if (data.done) {
              break;
            }
          } catch (e) {
            console.error('Failed to parse SSE data:', e);
          }
        }
      }
    }

    // If no response was received, show error
    if (!fullResponse) {
      contentDiv.textContent = '❌ No response received from LLM';
      responseDiv.classList.add('error-message');
    } else {
      // Add user message to conversation history
      chatConversationHistory.push({
        role: "user",
        content: userMessageContent
      });

      // Add assistant response to conversation history
      chatConversationHistory.push({
        role: "assistant",
        content: fullResponse
      });

      console.log('💬 Conversation history updated:', chatConversationHistory.length, 'messages');
    }

  } catch (error) {
    console.error('Chat error:', error);
    hideTypingIndicator();
    addChatMessage('Error', `Failed to send message: ${error.message}`, true);
    showNotification('Failed to send message', 'error');
  } finally {
    // Re-enable send button
    sendBtn.disabled = false;
    sendBtn.innerHTML = originalBtnText;
  }
}

// Helper function to read file as base64
function readFileAsBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result);
    reader.onerror = reject;
    reader.readAsDataURL(file);
  });
}

// ============================================================================
// Voice Call Management Functions
// ============================================================================

async function initiateVoiceCall() {
  const userId = document.getElementById('voice-user-id').value.trim();
  const channelId = document.getElementById('voice-channel-id').value.trim();
  const debugMode = document.getElementById('voice-debug-mode').checked;

  // Validation
  if (!userId) {
    showNotification('Please enter a user ID', 'error');
    return;
  }

  if (!channelId) {
    showNotification('Please enter a voice channel ID', 'error');
    return;
  }

  // Check if user IDs are valid (numeric)
  if (isNaN(userId) || isNaN(channelId)) {
    showNotification('User ID and Channel ID must be numeric', 'error');
    return;
  }

  // Set debug mode
  try {
    const debugFormData = new FormData();
    debugFormData.append('enabled', debugMode);
    await fetch('/voice/debug-mode', {
      method: 'POST',
      body: debugFormData
    });
  } catch (error) {
    console.error('Failed to set debug mode:', error);
  }

  // Disable button and show status
  const callBtn = document.getElementById('voice-call-btn');
  const cancelBtn = document.getElementById('voice-call-cancel-btn');
  const statusDiv = document.getElementById('voice-call-status');
  const statusText = document.getElementById('voice-call-status-text');

  callBtn.disabled = true;
  statusDiv.style.display = 'block';
  cancelBtn.style.display = 'inline-block';
  voiceCallActive = true;

  try {
    statusText.innerHTML = '⏳ Starting STT and TTS containers...';

    const formData = new FormData();
    formData.append('user_id', userId);
    formData.append('voice_channel_id', channelId);

    const response = await fetch('/voice/call', {
      method: 'POST',
      body: formData
    });

    const data = await response.json();

    // Check for HTTP error status (422 validation error, etc.)
    if (!response.ok) {
      let errorMsg = data.error || data.detail || 'Unknown error';
      // Handle FastAPI validation errors
      if (data.detail && Array.isArray(data.detail)) {
        errorMsg = data.detail.map(e => `${e.loc.join('.')}: ${e.msg}`).join(', ');
      }
      statusText.innerHTML = `❌ Error: ${errorMsg}`;
      showNotification(`Voice call failed: ${errorMsg}`, 'error');
      callBtn.disabled = false;
      cancelBtn.style.display = 'none';
      voiceCallActive = false;
      return;
    }

    if (!data.success) {
      statusText.innerHTML = `❌ Error: ${data.error}`;
      showNotification(`Voice call failed: ${data.error}`, 'error');
      callBtn.disabled = false;
      cancelBtn.style.display = 'none';
      voiceCallActive = false;
      return;
    }

    // Success!
    statusText.innerHTML = `✅ Voice call initiated!<br>User ID: ${data.user_id}<br>Channel: ${data.channel_id}`;

    // Show invite link
    const inviteDiv = document.getElementById('voice-call-invite-link');
    const inviteUrl = document.getElementById('voice-call-invite-url');
    inviteUrl.href = data.invite_url;
    inviteUrl.textContent = data.invite_url;
    inviteDiv.style.display = 'block';

    // Add to call history
    addVoiceCallToHistory(userId, channelId, data.invite_url);

    showNotification('Voice call initiated successfully!', 'success');

    // Auto-reset after 5 minutes (call should be done by then or timed out)
    setTimeout(() => {
      if (voiceCallActive) {
        resetVoiceCall();
      }
    }, 300000); // 5 minutes

  } catch (error) {
    console.error('Voice call error:', error);
    statusText.innerHTML = `❌ Error: ${error.message}`;
    showNotification(`Voice call error: ${error.message}`, 'error');
    callBtn.disabled = false;
    cancelBtn.style.display = 'none';
    voiceCallActive = false;
  }
}

function cancelVoiceCall() {
  resetVoiceCall();
  showNotification('Voice call cancelled', 'info');
}

function resetVoiceCall() {
  const callBtn = document.getElementById('voice-call-btn');
  const cancelBtn = document.getElementById('voice-call-cancel-btn');
  const statusDiv = document.getElementById('voice-call-status');

  callBtn.disabled = false;
  cancelBtn.style.display = 'none';
  statusDiv.style.display = 'none';
  voiceCallActive = false;

  // Clear inputs
  document.getElementById('voice-user-id').value = '';
  document.getElementById('voice-channel-id').value = '';
}

function addVoiceCallToHistory(userId, channelId, inviteUrl) {
  const now = new Date();
  const timestamp = now.toLocaleTimeString();

  const callEntry = {
    userId: userId,
    channelId: channelId,
    inviteUrl: inviteUrl,
    timestamp: timestamp
  };

  voiceCallHistory.unshift(callEntry); // Add to front

  // Keep only last 10 calls
  if (voiceCallHistory.length > 10) {
    voiceCallHistory.pop();
  }

  updateVoiceCallHistoryDisplay();
}

function updateVoiceCallHistoryDisplay() {
  const historyDiv = document.getElementById('voice-call-history');

  if (voiceCallHistory.length === 0) {
    historyDiv.innerHTML = '<div style="text-align: center; color: #888;">No calls yet. Start one above!</div>';
    return;
  }

  let html = '';
  voiceCallHistory.forEach((call, index) => {
    html += `
      <div style="background: #242424; padding: 0.75rem; margin-bottom: 0.5rem; border-radius: 4px; border-left: 3px solid #61dafb;">
        <div style="display: flex; justify-content: space-between; align-items: center;">
          <div>
            <strong>${call.timestamp}</strong>
            <div style="font-size: 0.85rem; color: #aaa; margin-top: 0.3rem;">
              User: <code>${call.userId}</code> | Channel: <code>${call.channelId}</code>
            </div>
          </div>
          <a href="${call.inviteUrl}" target="_blank" style="color: #61dafb; text-decoration: none; padding: 0.3rem 0.7rem; background: #333; border-radius: 4px; font-size: 0.85rem;">
            View Link →
          </a>
        </div>
      </div>
    `;
  });

  historyDiv.innerHTML = html;
}
