///|
/// Convert a single file tree node to string (recursive helper function)
/// 将单个文件树节点转换为字符串(递归辅助函数)
fn node_to_string(node : FileNode, prefix : String, is_last : Bool) -> String {
  let branch = get_branch_symbol(is_last)
  match node {
    File(name) => format_file_line(prefix, branch, name)
    Directory(name, children) =>
      format_directory_tree(prefix, branch, name, children, is_last)
  }
}

///|
/// Get the appropriate branch symbol
/// 获取适当的分支符号
fn get_branch_symbol(is_last : Bool) -> String {
  if is_last {
    "└── "
  } else {
    "├── "
  }
}

///|
/// Format a file line
/// 格式化文件行
fn format_file_line(prefix : String, branch : String, name : String) -> String {
  prefix + branch + name + "\n"
}

///|
/// Format a directory tree
/// 格式化目录树
fn format_directory_tree(
  prefix : String,
  branch : String,
  name : String,
  children : Array[FileNode],
  is_last : Bool,
) -> String {
  let mut result = format_directory_line(prefix, branch, name)
  let new_prefix = calculate_child_prefix(prefix, is_last)
  result = result + format_children_string(children, new_prefix)
  result
}

///|
/// Format a directory line
/// 格式化目录行
fn format_directory_line(
  prefix : String,
  branch : String,
  name : String,
) -> String {
  prefix + branch + name + "/\n"
}

///|
/// Calculate prefix for child nodes
/// 计算子节点的前缀
fn calculate_child_prefix(prefix : String, is_last : Bool) -> String {
  if is_last {
    prefix + "    "
  } else {
    prefix + "│   "
  }
}

///|
/// Format all children to string
/// 将所有子节点格式化为字符串
fn format_children_string(
  children : Array[FileNode],
  prefix : String,
) -> String {
  let mut result = ""
  let len = children.length()
  for i = 0; i < len; i = i + 1 {
    result = result + node_to_string(children[i], prefix, i == len - 1)
  }
  result
}

///|
/// Convert the complete file tree to a multi-line string
/// 将完整的文件树转换为多行字符串
///
/// # Parameters
/// ## 参数
///
/// - `node`: The root node of the file tree
/// - `node`: 文件树的根节点
///
/// # Returns
/// ## 返回值
///
/// - `String`: A multi-line string representation of the file tree
/// - `String`: 文件树的多行字符串表示
///
/// # Examples
/// ## 示例
///
/// ```moonbit
/// let tree = build_tree(".")
/// let tree_str = tree_to_string(tree)
/// println(tree_str)
/// // Output:
/// // .
/// // ├── src/
/// // │   └── main.mbt
/// // └── README.md
/// ```
pub fn tree_to_string(node : FileNode) -> String {
  match node {
    File(name) => format_root_file(name)
    Directory(name, children) => format_root_directory(name, children)
  }
}

///|
/// Format root file node
/// 格式化根文件节点
fn format_root_file(name : String) -> String {
  name + "\n"
}

///|
/// Format root directory node
/// 格式化根目录节点
fn format_root_directory(name : String, children : Array[FileNode]) -> String {
  let mut result = name + "/\n"
  result = result + format_children_string(children, "")
  result
}

///|
/// Test tree_to_string with simple file
/// 测试tree_to_string简单文件
test "tree_to_string simple file" {
  let tree = File("test.txt")
  let result = tree_to_string(tree)
  inspect(result, content="test.txt\n")
}

///|
/// Test tree_to_string with simple directory
/// 测试tree_to_string简单目录
test "tree_to_string simple directory" {
  let tree = Directory("test_dir", [File("file1.txt"), File("file2.txt")])
  let result = tree_to_string(tree)
  let expected = "test_dir/\n├── file1.txt\n└── file2.txt\n"
  inspect(result, content=expected)
}

///|
/// Test tree_to_string with nested directory
/// 测试tree_to_string嵌套目录
test "tree_to_string nested directory" {
  let subtree = Directory("subdir", [File("nested.txt")])
  let tree = Directory("root", [File("root.txt"), subtree])
  let result = tree_to_string(tree)
  let expected = "root/\n├── root.txt\n└── subdir/\n    └── nested.txt\n"
  inspect(result, content=expected)
}