/**
 * Tauri adapter for {@link MemoryGateway} (L14).
 *
 * Commands use snake_case (Tauri convention); payload keys are camelCase
 * (matching the backend DTO `#[serde(rename_all = "camelCase")]`), consistent
 * with the other adapters in this directory. Mutating commands that take a
 * structured request (`create_memory`, `update_memory`, `recall_memory`) wrap
 * their fields under a `request` key; the read commands pass their args flat.
 * Identity is the immutable **slug**, so `updateMemory` never sends a name.
 */

import { invoke } from "@tauri-apps/api/core";

import type { Memory, MemoryIndexEntry, MemoryLink, MemoryType } from "@/domain";
import type { CreateMemoryInput, MemoryGateway } from "@/ports";

export class TauriMemoryGateway implements MemoryGateway {
  listMemories(projectId: string): Promise<Memory[]> {
    return invoke<Memory[]>("list_memories", { projectId });
  }

  getMemory(projectId: string, slug: string): Promise<Memory> {
    return invoke<Memory>("get_memory", { projectId, slug });
  }

  createMemory(input: CreateMemoryInput): Promise<Memory> {
    return invoke<Memory>("create_memory", {
      request: {
        projectId: input.projectId,
        name: input.name,
        description: input.description,
        type: input.type,
        content: input.content,
      },
    });
  }

  updateMemory(
    projectId: string,
    slug: string,
    description: string,
    type: MemoryType,
    content: string,
  ): Promise<Memory> {
    return invoke<Memory>("update_memory", {
      request: { projectId, slug, description, type, content },
    });
  }

  async deleteMemory(projectId: string, slug: string): Promise<void> {
    await invoke("delete_memory", { projectId, slug });
  }

  readIndex(projectId: string): Promise<MemoryIndexEntry[]> {
    return invoke<MemoryIndexEntry[]>("read_memory_index", { projectId });
  }

  resolveLinks(projectId: string, slug: string): Promise<MemoryLink[]> {
    return invoke<MemoryLink[]>("resolve_memory_links", { projectId, slug });
  }

  recall(
    projectId: string,
    text: string,
    tokenBudget: number,
  ): Promise<MemoryIndexEntry[]> {
    return invoke<MemoryIndexEntry[]>("recall_memory", {
      request: { projectId, text, tokenBudget },
    });
  }
}
