const SYNAP_URL =
  process.env.SYNAP_URL ?? "https://api.synap.orchard9.ai";
const SYNAP_API_KEY = process.env.SYNAP_API_KEY ?? "";
const SYNAP_SPACE = process.env.SYNAP_SPACE ?? "";

// --- Response types ---

export interface SynapConfidence {
  value: number;
  category: string;
}

export interface SynapMessageResponse {
  message_id: string;
  stored_at: string;
  activated_memories?: SynapActivatedMemory[];
}

export interface SynapActivatedMemory {
  id: string;
  content: string;
  confidence: SynapConfidence;
}

export interface SynapMessage {
  id: string;
  user_id: string;
  content: string;
  timestamp: string;
}

export interface SynapMessagesResponse {
  messages: SynapMessage[];
  activated_memories?: SynapActivatedMemory[];
  pagination: { offset: number; limit: number; returned: number };
}

export interface SynapRecallMemory {
  id: string;
  content: string;
  confidence: SynapConfidence;
  activation_level: number;
}

export interface SynapRecallResponse {
  memories: {
    vivid: SynapRecallMemory[];
    associated: SynapRecallMemory[];
    reconstructed: SynapRecallMemory[];
  };
  recall_confidence: SynapConfidence;
}

export interface SynapRememberResponse {
  memory_id: string;
  observed_at: string;
  stored_at: string;
  storage_confidence: SynapConfidence;
}

// --- Client ---

async function request<T>(
  path: string,
  init?: RequestInit
): Promise<T> {
  const res = await fetch(`${SYNAP_URL}${path}`, {
    ...init,
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${SYNAP_API_KEY}`,
      ...(SYNAP_SPACE ? { "X-Memory-Space-Id": SYNAP_SPACE } : {}),
      ...init?.headers,
    },
  });

  if (!res.ok) {
    const body = await res.text().catch(() => "");
    throw new Error(`Synap ${res.status}: ${body}`);
  }

  return res.json();
}

/** Store a message in a conversation. */
export function sendMessage(
  userId: string,
  message: string,
  conversationId: string
): Promise<SynapMessageResponse> {
  return request("/api/v1/messages", {
    method: "POST",
    body: JSON.stringify({
      user_id: userId,
      message,
      conversation_id: conversationId,
    }),
  });
}

/** Retrieve messages for a conversation. */
export function getMessages(
  conversationId: string,
  limit = 50,
  offset = 0
): Promise<SynapMessagesResponse> {
  const params = new URLSearchParams({
    conversation_id: conversationId,
    limit: String(limit),
    offset: String(offset),
  });
  return request(`/api/v1/messages?${params}`);
}

/** Recall relevant memories by natural language query. */
export function recall(
  query: string,
  maxResults = 5,
  threshold = 0.5
): Promise<SynapRecallResponse> {
  const params = new URLSearchParams({
    query,
    max_results: String(maxResults),
    threshold: String(threshold),
  });
  return request(`/api/v1/memories/recall?${params}`);
}

/** Recall memories filtered by tags. */
export function recallByTag(
  query: string,
  tags: string[],
  maxResults = 10,
  threshold = 0.3
): Promise<SynapRecallResponse> {
  const params = new URLSearchParams({
    query,
    max_results: String(maxResults),
    threshold: String(threshold),
    tags: tags.join(","),
  });
  return request(`/api/v1/memories/recall?${params}`);
}

/** Store a new memory. */
export function remember(
  content: string,
  opts: {
    confidence?: number;
    memoryType?: "semantic" | "episodic" | "procedural";
    tags?: string[];
  } = {}
): Promise<SynapRememberResponse> {
  return request("/api/v1/memories/remember", {
    method: "POST",
    body: JSON.stringify({
      content,
      confidence: opts.confidence ?? 0.7,
      memory_type: opts.memoryType ?? "semantic",
      tags: opts.tags,
    }),
  });
}
