{% extends "base.html" %}

{% block content %}
  <div class="grid two-col">
    <section class="card">
      <div class="kicker">Index Control</div>
      <h2>Vault Status</h2>
      <p id="vault-status" class="muted mono">loading...</p>
      <div class="btn-row">
        <button id="index-all-btn" class="btn" type="button">Reindex Enabled Paths</button>
        <button id="refresh-btn" class="btn secondary" type="button">Refresh</button>
      </div>
      <div id="vault-action-output" class="muted" style="margin-top: 10px;"></div>
    </section>

    <section class="card">
      <div class="kicker">Path Management</div>
      <h2>Register Path</h2>
      <form id="vault-register-form" class="field-grid">
        <label>
          Folder Path
          <input type="text" id="vault-path-input" name="path" required placeholder="./notes" />
        </label>
        <div class="btn-row">
          <button class="btn" type="submit">Register</button>
        </div>
      </form>
    </section>
  </div>

  <section class="card" style="margin-top: 14px;">
    <div class="kicker">Registered Sources</div>
    <h3>Vault Paths</h3>
    <div class="table-wrap">
      <table>
        <thead>
          <tr>
            <th>ID</th>
            <th>Path</th>
            <th>Enabled</th>
            <th>Files</th>
            <th>Chunks</th>
            <th>Last Indexed</th>
            <th>Actions</th>
          </tr>
        </thead>
        <tbody id="vault-paths-body">
          <tr>
            <td colspan="7" class="muted">Loading paths...</td>
          </tr>
        </tbody>
      </table>
    </div>
  </section>

  <section class="card" style="margin-top: 14px;">
    <div class="kicker">Retrieval</div>
    <h3>Search Vault</h3>
    <form id="vault-search-form" class="field-grid">
      <div class="field-row">
        <label>
          Query
          <input type="text" name="q" required placeholder="kerberos ticket abuse" />
        </label>
        <label>
          Limit
          <input type="number" name="limit" min="1" max="20" value="10" />
        </label>
      </div>
      <div class="btn-row">
        <button class="btn" type="submit">Search</button>
      </div>
    </form>
    <div id="vault-search-results" class="grid" style="margin-top: 10px;"></div>
  </section>
{% endblock %}

{% block page_scripts %}
  <script>
    (() => {
      const statusLabel = document.getElementById("vault-status")
      const actionOutput = document.getElementById("vault-action-output")
      const pathsBody = document.getElementById("vault-paths-body")
      const indexAllBtn = document.getElementById("index-all-btn")
      const refreshBtn = document.getElementById("refresh-btn")
      const registerForm = document.getElementById("vault-register-form")
      const searchForm = document.getElementById("vault-search-form")
      const searchResults = document.getElementById("vault-search-results")

      const api = async (url, options = {}) => {
        const response = await fetch(url, {
          headers: {
            "Content-Type": "application/json",
            ...(options.headers || {}),
          },
          ...options,
        })
        const text = await response.text()
        let payload = null
        try {
          payload = text ? JSON.parse(text) : null
        } catch {
          payload = null
        }
        if (!response.ok) {
          throw new Error(payload?.detail || text || `HTTP ${response.status}`)
        }
        return payload
      }

      const formatDate = (value) => {
        if (!value) return "-"
        const dt = new Date(value)
        if (Number.isNaN(dt.getTime())) return String(value)
        return dt.toLocaleString()
      }

      const setOutput = (message) => {
        actionOutput.textContent = message || ""
      }

      const renderStatus = (status) => {
        const base = [
          `paths=${status.paths} enabled=${status.enabled_paths}`,
          `files=${status.files} enabled_files=${status.enabled_files || 0}`,
          `chunks=${status.chunks} enabled_chunks=${status.enabled_chunks || 0}`,
        ]
        if (status.needs_index) base.push("needs_index=yes")
        if (status.is_running) base.push("indexing=running")
        if (status.enabled_last_indexed_at) base.push(`enabled_last_indexed=${formatDate(status.enabled_last_indexed_at)}`)
        else if (status.last_indexed_at) base.push(`last_indexed=${formatDate(status.last_indexed_at)}`)
        if (status.last_finished_at) base.push(`last_finished=${formatDate(status.last_finished_at)}`)
        statusLabel.textContent = base.join(" | ")
      }

      const renderPaths = (paths) => {
        if (!paths.length) {
          pathsBody.innerHTML = '<tr><td colspan="7" class="muted">No registered paths.</td></tr>'
          return
        }

        pathsBody.innerHTML = ""
        for (const item of paths) {
          const row = document.createElement("tr")
          row.innerHTML = `
            <td class="mono">${item.id}</td>
            <td class="mono">${item.path}</td>
            <td>${item.enabled ? "yes" : "no"}</td>
            <td>${item.file_count || 0}</td>
            <td>${item.chunk_count || 0}</td>
            <td class="mono">${formatDate(item.last_indexed_at)}</td>
            <td>
              <div class="btn-row">
                <button class="btn secondary" type="button" data-action="index" data-path-id="${item.id}">Index</button>
                <button class="btn secondary" type="button" data-action="toggle" data-path-id="${item.id}" data-enabled="${item.enabled ? "1" : "0"}">
                  ${item.enabled ? "Disable" : "Enable"}
                </button>
              </div>
            </td>
          `
          pathsBody.appendChild(row)
        }
      }

      const loadAll = async () => {
        const [status, pathsPayload] = await Promise.all([api("/vault/status"), api("/vault/paths")])
        renderStatus(status)
        renderPaths(pathsPayload.paths || [])
      }

      const runIndex = async (pathId = null) => {
        setOutput(pathId ? `Indexing path ${pathId}...` : "Indexing enabled paths...")
        const payload = pathId ? { path_id: pathId } : {}
        const result = await api("/vault/index", {
          method: "POST",
          body: JSON.stringify(payload),
        })
        const stats = result.stats || {}
        setOutput(
          `Index complete: scanned=${stats.files_scanned || 0}, indexed=${stats.files_indexed || 0}, skipped=${stats.files_skipped || 0}, deleted=${stats.files_deleted || 0}, errors=${stats.errors || 0}`,
        )
        await loadAll()
      }

      registerForm.addEventListener("submit", async (event) => {
        event.preventDefault()
        const path = String(new FormData(registerForm).get("path") || "").trim()
        if (!path) return
        try {
          await api("/vault/register", {
            method: "POST",
            body: JSON.stringify({ path }),
          })
          registerForm.reset()
          setOutput("Path registered.")
          await loadAll()
        } catch (error) {
          setOutput(`Register failed: ${error instanceof Error ? error.message : String(error)}`)
        }
      })

      indexAllBtn.addEventListener("click", async () => {
        try {
          await runIndex(null)
        } catch (error) {
          setOutput(`Index failed: ${error instanceof Error ? error.message : String(error)}`)
        }
      })

      refreshBtn.addEventListener("click", async () => {
        try {
          setOutput("Refreshing...")
          await loadAll()
          setOutput("")
        } catch (error) {
          setOutput(`Refresh failed: ${error instanceof Error ? error.message : String(error)}`)
        }
      })

      pathsBody.addEventListener("click", async (event) => {
        const target = event.target
        if (!(target instanceof HTMLElement)) return
        const action = target.getAttribute("data-action")
        const pathIdRaw = target.getAttribute("data-path-id")
        const pathId = Number(pathIdRaw)
        if (!action || !Number.isFinite(pathId)) return

        try {
          if (action === "index") {
            await runIndex(pathId)
            return
          }

          if (action === "toggle") {
            const currentlyEnabled = target.getAttribute("data-enabled") === "1"
            await api(`/vault/paths/${pathId}/enabled`, {
              method: "POST",
              body: JSON.stringify({ enabled: !currentlyEnabled }),
            })
            setOutput(`Path ${pathId} ${currentlyEnabled ? "disabled" : "enabled"}.`)
            await loadAll()
          }
        } catch (error) {
          setOutput(`Action failed: ${error instanceof Error ? error.message : String(error)}`)
        }
      })

      searchForm.addEventListener("submit", async (event) => {
        event.preventDefault()
        const formData = new FormData(searchForm)
        const query = String(formData.get("q") || "").trim()
        const limit = Number.parseInt(String(formData.get("limit") || "10"), 10)
        if (!query) return

        searchResults.innerHTML = '<div class="muted">Searching...</div>'
        try {
          const payload = await api(`/vault/search?q=${encodeURIComponent(query)}&limit=${Number.isFinite(limit) ? limit : 10}`)
          const items = payload.results || []
          if (!items.length) {
            searchResults.innerHTML = '<div class="muted">No matches.</div>'
            return
          }
          searchResults.innerHTML = ""
          for (const item of items) {
            const card = document.createElement("article")
            card.className = "card"
            card.style.padding = "10px 12px"
            card.innerHTML = `
              <div style="display:flex;justify-content:space-between;gap:10px;align-items:center;">
                <span class="mono">${item.file_path}</span>
                <span class="pill">chunk ${item.chunk_id}</span>
              </div>
              <div class="muted" style="margin-top:8px;">${String(item.snippet || "").replaceAll("<mark>", "").replaceAll("</mark>", "")}</div>
            `
            searchResults.appendChild(card)
          }
        } catch (error) {
          const detail = error instanceof Error ? error.message : String(error)
          if (detail.includes("not indexed")) {
            searchResults.innerHTML = '<div class="muted">Vault is configured but not indexed for enabled paths yet.</div>'
            return
          }
          searchResults.innerHTML = `<div class="muted">Search failed: ${detail}</div>`
        }
      })

      loadAll().catch((error) => {
        setOutput(`Initial load failed: ${error instanceof Error ? error.message : String(error)}`)
      })
    })()
  </script>
{% endblock %}
