<script>
  import { onMount } from "svelte";
  import { api, formatTime } from "../lib/api.js";
  import Icon from "../lib/Icon.svelte";

  let query = $state("");
  let category = $state("");
  let memories = $state([]);
  let loading = $state(true);
  let error = $state("");
  let limit = $state(100);
  let editingKey = $state(null);
  let confirmingKey = $state(null);
  let draftContent = $state("");
  let draftImportance = $state(0);
  let saving = $state(false);
  let deleting = $state(false);
  let actionError = $state("");

  const knowledge = $derived(memories.filter((item) => item.category === "knowledge").length);
  const timeline = $derived(memories.length - knowledge);
  const hasMore = $derived(memories.length >= limit);

  async function load() {
    loading = true;
    error = "";
    const params = new URLSearchParams({ limit: String(limit) });
    if (query.trim()) params.set("query", query.trim());
    if (category) params.set("category", category);
    try { memories = (await api(`/api/memories?${params}`)).memories; }
    catch (caught) { error = caught.message; }
    finally { loading = false; }
  }

  function applyFilters() {
    limit = 100;
    editingKey = null;
    confirmingKey = null;
    actionError = "";
    load();
  }

  function loadMore() {
    limit += 100;
    load();
  }

  function startEdit(memory) {
    confirmingKey = null;
    actionError = "";
    editingKey = memory.key;
    draftContent = memory.content;
    draftImportance = Number(memory.importance);
  }

  function cancelEdit() {
    editingKey = null;
    actionError = "";
  }

  async function saveEdit(key) {
    saving = true;
    actionError = "";
    try {
      await api(`/api/memories/${encodeURIComponent(key)}`, {
        method: "PUT",
        body: JSON.stringify({ content: draftContent, importance: Number(draftImportance) })
      });
      editingKey = null;
      await load();
    } catch (caught) { actionError = caught.message; }
    finally { saving = false; }
  }

  function startConfirm(memory) {
    editingKey = null;
    actionError = "";
    confirmingKey = memory.key;
  }

  function cancelConfirm() {
    confirmingKey = null;
    actionError = "";
  }

  async function removeMemory(key) {
    deleting = true;
    actionError = "";
    try {
      await api(`/api/memories/${encodeURIComponent(key)}`, { method: "DELETE" });
      confirmingKey = null;
      await load();
    } catch (caught) { actionError = caught.message; }
    finally { deleting = false; }
  }

  onMount(load);
</script>

<section class="page active content-page">
  <form class="toolbar filters" onsubmit={(event) => { event.preventDefault(); applyFilters(); }}>
    <label class="search grow"><Icon name="search" size={16} /><input bind:value={query} placeholder="搜索记忆内容或键" /></label>
    <select bind:value={category}><option value="">全部</option><option value="knowledge">Knowledge</option><option value="timeline">Timeline</option></select>
    <button class="secondary" type="submit">查询</button>
  </form>
  <div class="metrics"><div class="metric"><b>{memories.length}</b><small>总数</small></div><div class="metric"><b>{knowledge}</b><small>Knowledge</small></div><div class="metric"><b>{timeline}</b><small>Timeline</small></div></div>
  <div class="cards">
    {#if loading}<div class="loading">加载中…</div>
    {:else if error}<div class="empty-card error-text">{error}</div>
    {:else}
      {#each memories as memory (memory.id)}
        <article class="card">
          {#if editingKey === memory.key}
            <div class="card-row"><h3 class="memory-key">{memory.key}</h3><span class="badge" class:ok={memory.category === "knowledge"}>{memory.category}</span></div>
            <label class="edit-field"><span>内容</span><textarea bind:value={draftContent} rows="4" disabled={saving}></textarea></label>
            <label class="edit-field"><span>重要度 {Number(draftImportance).toFixed(2)}</span><input type="range" min="0" max="1" step="0.05" bind:value={draftImportance} disabled={saving} /></label>
            {#if actionError}<p class="error-text action-error">{actionError}</p>{/if}
            <div class="card-actions">
              <button class="primary" onclick={() => saveEdit(memory.key)} disabled={saving}>保存</button>
              <button class="secondary" onclick={cancelEdit} disabled={saving}>取消</button>
            </div>
          {:else}
            <div class="card-row">
              <div class="card-main">
                <h3 class="memory-key">{memory.key}</h3>
                <p class="memory-content">{memory.content}</p>
                <div class="meta"><span>重要度 {Number(memory.importance).toFixed(2)}</span><span>更新 {formatTime(memory.updated_at)}</span>{#if memory.session_id}<span>{memory.session_id}</span>{/if}</div>
              </div>
              <div class="card-side">
                <span class="badge" class:ok={memory.category === "knowledge"}>{memory.category}</span>
                <div class="card-actions">
                  <button class="secondary" onclick={() => startEdit(memory)}>编辑</button>
                  <button class="secondary danger-outline" onclick={() => startConfirm(memory)}>删除</button>
                </div>
              </div>
            </div>
            {#if confirmingKey === memory.key}
              <div class="confirm" class:confirm-danger={memory.category === "timeline"}>
                {#if memory.category === "timeline"}
                  <p class="confirm-warning">Timeline 是压缩后的历史上下文，删除后模型将永久失去该时段长期记忆且无法自动重建；原始消息仍保留在聊天历史，但不再进入模型上下文</p>
                {:else}
                  <p class="confirm-text">删除后不可恢复，影响后续召回</p>
                {/if}
                {#if actionError}<p class="error-text action-error">{actionError}</p>{/if}
                <div class="card-actions">
                  <button class="danger-solid" onclick={() => removeMemory(memory.key)} disabled={deleting}>{memory.category === "timeline" ? "我了解，确认删除" : "确认删除"}</button>
                  <button class="secondary" onclick={cancelConfirm} disabled={deleting}>取消</button>
                </div>
              </div>
            {/if}
          {/if}
        </article>
      {:else}<div class="empty-card">没有匹配的记忆</div>{/each}
      {#if hasMore}<div class="load-more"><button class="secondary" onclick={loadMore}>加载更多</button></div>{/if}
    {/if}
  </div>
</section>

<style>
  .card-main { min-width: 0; flex: 1; }
  .card-side { display: flex; flex-direction: column; align-items: flex-end; gap: 10px; flex: 0 0 auto; }
  .card-actions { display: flex; gap: 8px; flex-wrap: wrap; }
  .card > .card-actions { margin-top: 14px; }
  .danger-outline { border-color: var(--danger-border); color: var(--danger); }
  .danger-solid { border-radius: 4px; padding: 5px 12px; font-weight: 600; cursor: pointer; border: 1px solid var(--danger); background: var(--danger); color: #fff; }
  .danger-solid:hover { filter: brightness(1.08); }
  .edit-field { display: grid; gap: 6px; margin-top: 12px; }
  .edit-field > span { color: var(--muted); font-size: 12px; }
  .edit-field textarea { width: 100%; min-height: 90px; resize: vertical; border: 1px solid var(--line-strong); border-radius: 4px; background: var(--panel); color: var(--text); padding: 10px; font: 14px/1.6 var(--font-ui); }
  .edit-field input[type="range"] { width: 100%; accent-color: var(--accent); }
  .action-error { margin: 12px 0 0; font-size: 13px; }
  .confirm { margin-top: 12px; border-top: 1px solid var(--line); padding-top: 12px; display: grid; gap: 10px; }
  .confirm-text { margin: 0; color: var(--muted); font-size: 13px; }
  .confirm-danger { border: 1px solid var(--danger-border); border-radius: 8px; background: var(--danger-soft); padding: 12px; }
  .confirm-warning { margin: 0; color: var(--danger); font-size: 13px; line-height: 1.6; }
  .load-more { display: flex; justify-content: center; padding: 6px 0; }
</style>
