/**
 * Block classifier.
 *
 * Determines block type from the first line of a paragraph’s text.
 * With the re-architecture, each ProseMirror paragraph is exactly
 * one line of markdown, so no line-walking is required — the
 * classification is a single regex against the paragraph string.
 *
 * Exported types and helpers are kept minimal to make the interface
 * easy to replace if the set of block kinds ever changes.
 */

// ── Types ───────────────────────────────────────────────────────────

export type BlockKind =
  | "paragraph"
  | "heading"
  | "callout"
  | "blockquote"
  | "task"
  | "code"

export type ParagraphResult = { kind: "paragraph" }

export type HeadingResult = { kind: "heading"; level: number }

export type TaskResult = { kind: "task"; taskState: string }

export type CalloutResult = { kind: "callout"; calloutType: string }

export type BlockquoteResult = { kind: "blockquote" }

export type CodeResult = { kind: "code"; language: string }

export type ClassificationResult =
  | ParagraphResult
  | HeadingResult
  | TaskResult
  | CalloutResult
  | BlockquoteResult
  | CodeResult

// ─── Regex constants ────────────────────────────────────────────────

/** Heading: `# Heading` — up to 6 hashes followed by a space. */
const HEADING_RE = /^(#{1,6})\s+(.*)/

/** Callout: `> [!NOTE] text` */
const CALLOUT_RE = /^>\s*\[!([A-Z]+)\]\s*(.*)/

/** Plain blockquote: `> text` (not a callout) */
const BLOCKQUOTE_RE = /^>\s*(.*)/

/** Task: `  TODO buy milk` — optional leading whitespace */
const TASK_RE = /^\s*(TODO|DOING|DONE|LATER|NOW|WAITING|CANCELLED)\s+(.*)/i

/** Fenced code: ````python` or `~~~` */
const CODE_FENCE_RE = /^(```|~~~)\s*(\w*)/

// ─── Public API ─────────────────────────────────────────────────────

/**
 * Classify a line of text into a BlockKind.
 *
 * With the paragraph-per-line architecture, this is the only
 * classification step needed — no line-walking, no text-inspection
 * over multi-line nodes.
 */
export function classifyBlock(text: string): ClassificationResult {
  {
    const match = text.match(HEADING_RE)
    if (match) {
      return {
        kind: "heading",
        // biome-ignore lint/style/noNonNullAssertion: match confirmed by HEADING_RE
        level: match[1]!.length,
      }
    }
  }

  {
    const match = text.match(CALLOUT_RE)
    if (match) {
      return {
        kind: "callout",
        // biome-ignore lint/style/noNonNullAssertion: match confirmed by CALLOUT_RE
        calloutType: match[1]!,
      }
    }
  }

  {
    const match = text.match(BLOCKQUOTE_RE)
    if (match) {
      return {
        kind: "blockquote",
      }
    }
  }

  {
    const match = text.match(TASK_RE)
    if (match) {
      return {
        kind: "task",
        // biome-ignore lint/style/noNonNullAssertion: match confirmed by TASK_RE
        taskState: match[1]!.toUpperCase(),
      }
    }
  }

  {
    const match = text.match(CODE_FENCE_RE)
    if (match) {
      return {
        kind: "code",
        // biome-ignore lint/style/noNonNullAssertion: match confirmed by CODE_FENCE_RE
        language: match[2]!,
      }
    }
  }

  return { kind: "paragraph" }
}
