<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width,initial-scale=1" />
  <title>RAG Chat</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-100 min-h-screen">
  <div id="appRoot" class="flex flex-col h-screen">
    <header class="flex items-center justify-between bg-white shadow px-4 py-3">
      <div class="flex items-center gap-4">
        <h1 class="text-lg font-semibold">RAG Chat</h1>
        <div class="flex gap-2 items-center">
          <label for="chatModelSelect" class="text-sm font-medium text-gray-700 mr-1">Model:</label>
          <select id="chatModelSelect" class="border rounded px-2 py-1 text-sm focus:ring-blue-500 focus:border-blue-500 mr-2 min-w-[120px]">
            <option value="">Loading...</option>
          </select>
          <button id="initBtn" class="bg-indigo-600 text-white px-3 py-2 rounded hover:bg-indigo-700">Initialize</button>
          <button id="reloadBtn" class="bg-yellow-600 text-white px-3 py-2 rounded hover:bg-yellow-700">Reload</button>
        </div>
        <span id="status" class="ml-3 text-sm text-gray-600">Not initialized</span>
      </div>
      <div class="flex items-center gap-3"></div>
    </header>

    <main class="flex-1 flex p-4 gap-4">
      <!-- left: chat area -->
      <section class="flex-1 flex flex-col bg-white rounded shadow overflow-hidden">
        <div id="chatBox" class="flex-1 p-4 overflow-auto">
          <!-- messages will appear here -->
        </div>
        <div class="p-3 border-t bg-gray-50">
          <form id="queryForm" class="flex gap-2">
            <input id="question" type="text" placeholder="Ask a question..." class="flex-1 border rounded px-3 py-2" />
            <button type="submit" class="bg-blue-600 text-white px-3 py-2 rounded hover:bg-blue-700">Send</button>
          </form>
          <div id="error" class="text-red-600 mt-2"></div>
        </div>
      </section>

      <!-- right: optional controls / info -->
      <aside id="controls" class="w-80 flex-shrink-0 bg-white rounded shadow p-4 overflow-auto">
        <h3 class="font-medium mb-2">Settings</h3>
        <p class="text-xs text-gray-600 mb-3">Mode and query settings</p>
        <div class="mb-3">
          <label class="block text-xs text-gray-700">Mode</label>
          <select id="modeAside" class="w-full border rounded px-2 py-2">
            <option value="local">local</option>
            <option value="global">global</option>
            <option value="naive">naive</option>
            <option value="hybrid">hybrid</option>
          </select>
        </div>
        <div class="mb-3">
          <label class="block text-xs text-gray-700">Top K</label>
          <input id="topkAside" type="number" value="5" min="1" class="w-full border rounded px-2 py-2" />
        </div>
        <div class="mt-4">
          <h4 class="font-medium">Actions</h4>
          <div class="flex gap-2 mt-2">
            <p class="text-sm text-gray-600">Use the header buttons to initialize or reload the RAG.</p>
          </div>
        </div>
      </aside>
    </main>
  </div>

  <script>
  const statusEl = document.getElementById('status');
  const chatBox = document.getElementById('chatBox');
  const errorEl = document.getElementById('error');
  const appRoot = document.getElementById('appRoot');
  const modeAside = document.getElementById('modeAside');
  const topkAside = document.getElementById('topkAside');
  const initBtnAside = document.getElementById('initBtnAside');
  const reloadBtnAside = document.getElementById('reloadBtnAside');

    function appendMessage(role, text) {
      const wrapper = document.createElement('div');
      wrapper.className = 'mb-3';
      const who = document.createElement('div');
      who.className = 'text-xs text-gray-500';
      who.textContent = role;
      const body = document.createElement('div');
      body.className = 'mt-1 p-3 rounded';
      body.style.whiteSpace = 'pre-wrap';
      if (role === 'user') {
        body.classList.add('bg-blue-100', 'text-blue-900');
      } else {
        body.classList.add('bg-gray-100', 'text-gray-900');
      }
      body.textContent = text;
      wrapper.appendChild(who);
      wrapper.appendChild(body);
      chatBox.appendChild(wrapper);
      chatBox.scrollTop = chatBox.scrollHeight;
    }

    // Fullscreen button removed — no-op

    // Note: mode and top_k are taken from the aside controls when submitting a query

    document.getElementById('initBtn').addEventListener('click', async () => {
      errorEl.textContent = '';
      statusEl.textContent = 'Initializing...';
      try {
        const chatModel = document.getElementById('chatModelSelect')?.value || '';
        const res = await fetch('/rag/initialize', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ chat_model: chatModel })
        });
        const data = await res.json();
        statusEl.textContent = data.message || 'Initialized';
        appendMessage('system', JSON.stringify(data));
      } catch (e) {
        errorEl.textContent = 'Initialization failed: ' + e;
        statusEl.textContent = 'Initialization failed';
      }
    });

    document.getElementById('reloadBtn').addEventListener('click', async () => {
      errorEl.textContent = '';
      statusEl.textContent = 'Reloading...';
      try {
        const chatModel = document.getElementById('chatModelSelect')?.value || '';
        const res = await fetch('/rag/reload', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ chat_model: chatModel })
        });
        const data = await res.json();
        statusEl.textContent = data.message || 'Reload complete';
        appendMessage('system', JSON.stringify(data));
      } catch (e) {
        errorEl.textContent = 'Reload failed: ' + e;
        statusEl.textContent = 'Reload failed';
      }
    });
  // Populate chat model dropdown from /text/models
  async function populateChatModelDropdown() {
    const select = document.getElementById('chatModelSelect');
    try {
      const res = await fetch('/text/models');
      if (!res.ok) throw new Error('Failed to fetch models');
      const data = await res.json();
      if (data && Array.isArray(data.models)) {
        select.innerHTML = '';
        data.models.forEach(model => {
          const opt = document.createElement('option');
          opt.value = model;
          opt.textContent = model;
          select.appendChild(opt);
        });
      } else {
        select.innerHTML = '<option value="">No models found</option>';
      }
    } catch (err) {
      select.innerHTML = '<option value="">Error loading models</option>';
    }
  }

  document.addEventListener('DOMContentLoaded', function () {
    populateChatModelDropdown();
  });

    document.getElementById('queryForm').addEventListener('submit', async (ev) => {
      ev.preventDefault();
      errorEl.textContent = '';
      const q = document.getElementById('question').value.trim();
      if (!q) return;
      const mode = (modeAside && modeAside.value) ? modeAside.value : 'local';
      const top_k = parseInt((topkAside && topkAside.value) ? topkAside.value : '5', 10);
      appendMessage('user', q);
      document.getElementById('question').value = '';
      try {
        const res = await fetch('/rag/query', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ question: q, mode, top_k })
        });
        if (!res.ok) {
          const text = await res.text();
          throw new Error(text || res.statusText);
        }
        const data = await res.json();
        // server returns { response: ... }
        const resp = data.response;
        appendMessage('rag', typeof resp === 'string' ? resp : JSON.stringify(resp, null, 2));
      } catch (err) {
        errorEl.textContent = 'Query failed: ' + (err.message || err);
      }
    });
  </script>
</body>
</html>
