/** LTM — long-term memory type definitions */

import { Schema } from "effect"
import { optionalOmitUndefined } from "@/util/schema"


export const MemoryType = Schema.Literals(["episodic", "semantic", "procedural"])
export type MemoryType = Schema.Schema.Type<typeof MemoryType>


export const MemoryMetadata = Schema.Struct({
  source: Schema.String,
  timestamp: Schema.Number,
  projectID: optionalOmitUndefined(Schema.String),
  sessionID: optionalOmitUndefined(Schema.String),
  tags: Schema.mutable(Schema.Array(Schema.String)),
})
export type MemoryMetadata = Schema.Schema.Type<typeof MemoryMetadata>

export const Memory = Schema.Struct({
  id: Schema.String,
  type: MemoryType,
  content: Schema.String,
  summary: Schema.String,
  vector: Schema.mutable(Schema.Array(Schema.Number)),
  metadata: MemoryMetadata,
  score: optionalOmitUndefined(Schema.Number),
})
export type Memory = Schema.Schema.Type<typeof Memory>


export const EmbedderStatus = Schema.Literals(["stopped", "starting", "running", "error"])
export type EmbedderStatus = Schema.Schema.Type<typeof EmbedderStatus>

export const EmbeddingServer = Schema.Struct({
  id: Schema.String,
  model: Schema.String,
  status: EmbedderStatus,
  endpoint: Schema.String,
  dimensions: Schema.Number,
  vramMB: Schema.Number,
})
export type EmbeddingServer = Schema.Schema.Type<typeof EmbeddingServer>


export const HardwareProfile = Schema.Struct({
  gpuCount: Schema.Number,
  totalVRAMMB: Schema.Number,
  availableVRAMMB: Schema.Number,
  totalRAMMB: Schema.Number,
  cpuCores: Schema.Number,
  cudaAvailable: Schema.Boolean,
})
export type HardwareProfile = Schema.Schema.Type<typeof HardwareProfile>


export const LLMBakeParams = Schema.Struct({
  /** Embedding model ID */
  embeddingModel: Schema.String,
  /** Embedding dimensions */
  embeddingDimensions: Schema.Number,
  /** Embedding model VRAM usage (MB) */
  embeddingVRAMMB: Schema.Number,
  /** Context length */
  contextLength: Schema.Number,
  /** Batch size */
  batchSize: Schema.Number,
  /** Ollama thread count */
  numThread: Schema.Number,
  /** GPU layer count (-1=all) */
  numGPU: Schema.Number,
  /** Profile detection hash at generation time (triggers recompute on change) */
  hardwareHash: Schema.String,
})
export type LLMBakeParams = Schema.Schema.Type<typeof LLMBakeParams>


export const LTMConfig = Schema.Struct({
  enabled: Schema.Boolean,
  embeddingModel: Schema.String,
  vectorStore: Schema.Literals(["filesystem", "qdrant", "chroma"]),
  maxMemories: Schema.Number,
  episodic: Schema.Struct({
    enabled: Schema.Boolean,
    summaryInterval: Schema.Number,
    retainDays: Schema.Number,
  }),
  semantic: Schema.Struct({
    enabled: Schema.Boolean,
    indexOnFileChange: Schema.Boolean,
  }),
  procedural: Schema.Struct({
    enabled: Schema.Boolean,
    trackPreferences: Schema.Boolean,
  }),
  retrieval: Schema.Struct({
    topK: Schema.Number,
    minScore: Schema.Number,
    maxTokens: Schema.Number,
  }),
})
export type LTMConfig = Schema.Schema.Type<typeof LTMConfig>