
# =============================================================================
# apply_translation_rules: recursively parse a bracketed structure and translate
# =============================================================================


#' Apply Translation Rules to a Bracketed Structure String
#'
#' Recursively parses a string with \code{\{\}} brackets and \code{#N} tags,
#' resolves all sub-groups via recursion, then delegates to
#' \code{\link{eval_operator}} for the actual evaluation.
#'
#' @param s Bracketed string from \code{\link{add_brackets}} (only \code{\{\}} brackets).
#' @param type Character vector of grammatical types. \code{type[k]} is the
#'   type string for tag \code{#k}.
#' @param translation Character vector of translations. \code{translation[k]}
#'   is the translation for tag \code{#k}.
#' @return \code{c(type, translation)} of length 2, or error message of length 1.
#' @export
apply_translation_rules <- function(s, type, translation) {
  chars <- strsplit(s, "")[[1]]
  n <- length(chars)
  elements <- list()   # list of c(type_str, translation_str)
  seps <- character(0)
  buf <- ""
  i <- 1L

  # --- Phase 1: Parse elements and separators ---
  while (i <= n) {
    ch <- chars[i]

    if (ch == "#") {
      if (length(elements) > 0) seps <- c(seps, buf)
      buf <- ""
      rt <- read_tag(chars, i)
      i <- rt$next_i
      elements[[length(elements) + 1L]] <- c(type[rt$tag_num], translation[rt$tag_num])

    } else if (ch == "{") {
      if (length(elements) > 0) seps <- c(seps, buf)
      buf <- ""
      depth <- 1L; inner <- ""; i <- i + 1L
      while (i <= n && depth > 0) {
        if (chars[i] == "{") depth <- depth + 1L
        if (chars[i] == "}") depth <- depth - 1L
        if (depth > 0) inner <- paste0(inner, chars[i])
        i <- i + 1L
      }
      result <- apply_translation_rules(inner, type, translation)
      if (length(result) == 1) return(result)
      elements[[length(elements) + 1L]] <- result

    } else {
      buf <- paste0(buf, ch)
      i <- i + 1L
    }
  }
  trailing_sep <- buf

  # --- Phase 2: Base cases ---
  if (length(elements) == 0)
    return(c(NA_character_, ""))
  if (length(elements) == 1) {
    return(eval_operator(elements[[1]][1], elements[[1]][2], trailing_sep = trailing_sep))
  }

  # --- Phase 3: Prepare parameters for eval_operator ---
  op_idx <- NULL
  op_parsed <- NULL
  for (j in seq_along(elements)) {
    p <- parse_type(elements[[j]][1])
    if (p$is_operator) { op_idx <- j; op_parsed <- p; break }
  }

  if (!is.null(op_idx)) {
    # Operator found: build named args list
    operator  <- elements[[op_idx]][1]
    rule_trans <- elements[[op_idx]][2]
    arg_el <- elements[-op_idx]

    args <- build_args(arg_el)

    return(eval_operator(operator, rule_trans, args, seps, trailing_sep))
  }

  # No operator: composition
  args <- build_args(elements)
  eval_operator(NULL, NULL, args, seps, trailing_sep)
}
