/** Simple content hash for change detection (djb2 variant, base-36 encoded). */
export function contentHash(content: string): string {
  let hash = 0
  for (let i = 0; i < content.length; i++) {
    const chr = content.charCodeAt(i)
    hash = (hash << 5) - hash + chr
    hash |= 0
  }
  return hash.toString(36)
}

/**
 * Classify a block's type from its first line content.
 * Matches the block_type CHECK constraint in the schema.
 */
export function detectBlockType(content: string): string {
  const first = content.trimStart()
  if (/^#{1,6}\s/.test(first)) return "heading"
  if (
    /^TODO\s|^DOING\s|^DONE\s|^LATER\s|^NOW\s|^WAITING\s|^CANCELLED\s/i.test(
      first,
    )
  )
    return "task"
  if (/^>\s*\[!/.test(first)) return "callout"
  if (/^>\s/.test(first)) return "blockquote"
  if (/^```/.test(first)) return "code"
  if (/^\|.+\|/.test(first)) return "table"
  if (/^\$\$/.test(first)) return "math"
  if (/^\w+::\s/.test(first)) return "property"
  return "paragraph"
}

/** Extract the first `# Heading 1` from markdown content. */
export function extractTitle(content: string): string {
  const match = content.match(/^# (.+)/m)
  return match ? match[1]?.trim() : ""
}

export interface ExtractedLink {
  target: string
  linkType: "page-ref" | "block-ref" | "tag"
  offset: number
}

/**
 * Extract [[Page Name]], ((block-id)), and #tag references from block content.
 * Returns target text, link type, and character offset within the block.
 */
export function extractLinks(content: string): ExtractedLink[] {
  const links: ExtractedLink[] = []

  for (const m of content.matchAll(/\[\[([^\]|]+)(?:\|[^\]]+)?\]\]/g)) {
    links.push({
      target: m[1]!, // biome-ignore lint/style/noNonNullAssertion: matchAll guarantees group 1
      linkType: "page-ref",
      offset: m.index,
    })
  }
  for (const m of content.matchAll(/\(\(([a-zA-Z0-9_-]+)\)\)/g)) {
    links.push({ target: m[1]!, linkType: "block-ref", offset: m.index })
  }
  for (const m of content.matchAll(/(?:\s|^)#([a-zA-Z0-9_-]+)/g)) {
    links.push({
      target: m[1]!,
      linkType: "tag",
      offset: m.index + 1,
    })
  }

  return links
}
