///| Emphasis (`*`, `_`) and strong (`**`, `__`) inline parsing.

///|

///| Split from inline_parser.mbt to keep that file focused on the inline

///| dispatcher; this file contains the simple single-pass emphasis matcher

///| plus its `parse_until_closing_marker` helper. The full CommonMark

///| delimiter-stack algorithm lives in inline_parser_strict.mbt.

///|
/// Try to parse emphasis or strong
fn InlineParser::try_parse_emphasis(
  self : InlineParser,
  start : Int,
  marker_char : Char,
) -> Inline? {
  // Count opening markers
  let marker_count = self.scanner.count_char(marker_char)
  if marker_count == 0 {
    return None
  }

  // Only handle 1 or 2 markers (emphasis or strong)
  let is_strong = marker_count >= 2
  let consume_count = if is_strong { 2 } else { 1 }
  self.scanner.advance(consume_count)

  // Check if followed by whitespace (not valid opener)
  match self.scanner.peek() {
    Some(' ') | Some('\t') | Some('\n') | None => {
      self.scanner.restore(start)
      return None
    }
    _ => ()
  }

  // Parse content until closing marker
  let children = self.parse_until_closing_marker(marker_char, consume_count)
  if children.is_empty() {
    self.scanner.restore(start)
    return None
  }
  let marker = if marker_char == '*' {
    EmphasisMarker::Asterisk
  } else {
    EmphasisMarker::Underscore
  }
  if is_strong {
    Some(
      Inline::Strong(
        marker~,
        children~,
        span=Span::new(start, self.scanner.pos),
      ),
    )
  } else {
    Some(
      Inline::Emphasis(
        marker~,
        children~,
        span=Span::new(start, self.scanner.pos),
      ),
    )
  }
}

///|
/// Parse content until closing marker
fn InlineParser::parse_until_closing_marker(
  self : InlineParser,
  marker_char : Char,
  marker_count : Int,
) -> Array[Inline] {
  let children : Array[Inline] = []
  let text_buf = StringBuilder::new()
  let text_start = self.scanner.pos
  while !self.scanner.is_eof() {
    // Check for closing marker
    let closing_count = self.scanner.count_char(marker_char)
    if closing_count >= marker_count {
      // Check if preceded by non-whitespace
      let prev_char = self.scanner.peek_at(-1)
      match prev_char {
        Some(' ') | Some('\t') | Some('\n') => () // Not valid closer
        _ => {
          // Valid closer - flush text and consume markers
          if !text_buf.is_empty() {
            children.push(
              Inline::Text(
                content=text_buf.to_string(),
                span=Span::new(text_start, self.scanner.pos),
              ),
            )
          }
          self.scanner.advance(marker_count)
          return children
        }
      }
    }

    // Handle nested inline elements
    match self.scanner.peek() {
      Some('`') => {
        // Flush text before inline
        if !text_buf.is_empty() {
          children.push(
            Inline::Text(
              content=text_buf.to_string(),
              span=Span::new(text_start, self.scanner.pos),
            ),
          )
        }
        let nested_start = self.scanner.pos
        match self.try_parse_code_span(nested_start) {
          Some(code) => {
            children.push(code)
            continue
          }
          None => ()
        }
      }
      Some('[') => {
        if !text_buf.is_empty() {
          children.push(
            Inline::Text(
              content=text_buf.to_string(),
              span=Span::new(text_start, self.scanner.pos),
            ),
          )
        }
        let nested_start = self.scanner.pos
        match self.try_parse_link(nested_start) {
          Some(link) => {
            children.push(link)
            continue
          }
          None => ()
        }
      }
      Some('\n') =>
        // Newline ends emphasis in most cases
        break
      _ => ()
    }

    // Regular character
    match self.scanner.consume() {
      Some(c) => text_buf.write_char(c)
      None => break
    }
  }

  // No closing marker found
  []
}