import type { NoteNode } from "../types/flow"

type NoteLike = {
  id?: string
  label?: { markdown?: string }
  content?: { markdown?: string }
  properties?: { summary?: { text?: string } }
  style?: { type?: string }
}

/**
 * Normalize an optional string value for text extraction.
 */
const trimOrEmpty = (value?: string) => (value ?? "").trim()

/**
 * Pick the most useful plain-text content for a node.
 */
const buildPlainNodeText = (node: NoteNode) => {
  const data = node.data as NoteLike | undefined
  const label = trimOrEmpty(data?.label?.markdown)
  const content = trimOrEmpty(data?.content?.markdown)
  const summary = trimOrEmpty(data?.properties?.summary?.text)

  if (label && content && label !== content) {
    return `Title: ${label}\nContent: ${content}`
  }
  if (label) return label
  if (summary) return summary
  if (content) return content
  return ""
}

/**
 * Build a structured note block with ids and note types for agent context.
 */
const buildStructuredNoteBlock = (node: NoteNode) => {
  const data = node.data as NoteLike | undefined
  const noteId = trimOrEmpty(data?.id || node.id)
  const noteType = trimOrEmpty(data?.style?.type)
  const plainText = buildPlainNodeText(node)
  const lines = [
    "<SelectedNote>",
    noteId ? `NoteId: ${noteId}` : "",
    noteType ? `NoteType: ${noteType}` : "",
  ]

  if (plainText.startsWith("Title: ")) {
    lines.push(...plainText.split("\n"))
  } else if (plainText) {
    lines.push(`Content: ${plainText}`)
  }

  lines.push("</SelectedNote>")
  return lines.filter(Boolean).join("\n")
}

/**
 * Build a structured context payload from a node list.
 * Each selected note is represented as its own compact tagged block.
 */
export const buildContextTextFromNodes = (
  nodes: NoteNode[],
  options: { skipPrefix?: boolean } = {}
) => {
  const { skipPrefix = false } = options
  const blocks = nodes
    .filter((node) => (node.data as { kind?: string } | undefined)?.kind !== "point")
    .map((node) => (skipPrefix ? buildPlainNodeText(node) : buildStructuredNoteBlock(node)))
    .filter((text) => text.length > 0)

  if (blocks.length === 0) return ""
  return blocks.join("\n\n")
}
