/** LTM semantic memory — code and project knowledge (English, LLM-to-LLM) */

import * as Log from "@saeeol/core/util/log"
import * as Embedder from "@/provider/local/embedder"
import type { Memory } from "@/ltm/types"

const log = Log.create({ service: "ltm/memory/semantic" })

/** Create a semantic memory from a code chunk */
export async function fromCodeChunk(
  projectID: string,
  filePath: string,
  chunk: string,
  startLine: number,
  endLine: number,
): Promise<Memory | undefined> {
  if (chunk.length < 20) return undefined

  const summary = codeSummary(filePath, chunk, startLine, endLine)

  try {
    const vector = await Embedder.embedOne(summary)
    return {
      id: `sem:${projectID}:${filePath}:${startLine}-${endLine}`,
      type: "semantic",
      content: chunk.slice(0, 500),
      summary,
      vector,
      metadata: {
        source: `file:${filePath}`,
        timestamp: Date.now(),
        projectID,
        tags: [pathExtension(filePath), "code"],
      },
    }
  } catch (e) {
    log.error("failed to create semantic memory", { error: e, filePath })
    return undefined
  }
}

/** Create a semantic memory from project structure overview */
export async function fromProjectStructure(
  projectID: string,
  structure: string,
): Promise<Memory | undefined> {
  const summary = `project structure: ${structure.slice(0, 300)}`

  try {
    const vector = await Embedder.embedOne(summary)
    return {
      id: `sem:${projectID}:structure`,
      type: "semantic",
      content: structure.slice(0, 500),
      summary,
      vector,
      metadata: {
        source: `project:${projectID}`,
        timestamp: Date.now(),
        projectID,
        tags: ["structure"],
      },
    }
  } catch (e) {
    log.error("failed to create project structure memory", { error: e })
    return undefined
  }
}

/** Build a code chunk summary for embedding */
function codeSummary(filePath: string, chunk: string, start: number, end: number): string {
  const ext = pathExtension(filePath)
  const preview = chunk.slice(0, 150).replace(/\n/g, " ").trim()
  return `${filePath}:${start}-${end} (${ext}) ${preview}`
}

function pathExtension(filePath: string): string {
  const parts = filePath.split(".")
  return parts.length > 1 ? parts[parts.length - 1]! : "unknown"
}
