///|
fn is_zh(lang : String) -> Bool {
  lang != "en"
}

///|
fn yes_no(value : Bool) -> String {
  if value {
    "yes"
  } else {
    "no"
  }
}

///|
fn yes_no_lang(value : Bool, lang : String) -> String {
  if is_zh(lang) {
    if value {
      "是"
    } else {
      "否"
    }
  } else {
    yes_no(value)
  }
}

///|
fn display_path(report : ProjectReport, file : String) -> String {
  let root = report.project_root
  if root != "" {
    let normalized_root = root.replace(old="/", new="\\")
    let normalized_file = file.replace(old="/", new="\\")
    if normalized_file.has_prefix(normalized_root + "\\") {
      normalized_file[normalized_root.length() + 1:].to_owned()
    } else {
      file
    }
  } else {
    file
  }
}

///|
fn issue_location(
  report : ProjectReport,
  issue : DocIssue,
  lang : String,
) -> String {
  let path = display_path(report, issue.file)
  let message = issue_message(issue, lang)
  if path == message {
    match issue.line {
      Some(line) => path + ":" + line.to_string()
      None => path
    }
  } else if message.has_prefix(path + " ") {
    match issue.line {
      Some(line) =>
        path +
        ":" +
        line.to_string() +
        " " +
        message[path.length() + 1:].to_owned()
      None => message
    }
  } else {
    match issue.line {
      Some(line) => path + ":" + line.to_string() + " " + message
      None => path + " " + message
    }
  }
}

///|
fn readiness_level(report : ProjectReport, lang : String) -> String {
  if report.documentation_coverage >= 90 &&
    report.readme.found &&
    report.readme.has_usage &&
    report.moon_mod.found &&
    report.has_generated_mbti &&
    report.ci.has_moon_check &&
    report.ci.has_moon_test {
    if is_zh(lang) {
      "优秀"
    } else {
      "Excellent"
    }
  } else if report.documentation_coverage >= 70 &&
    report.readme.found &&
    report.moon_mod.found {
    if is_zh(lang) {
      "良好"
    } else {
      "Good"
    }
  } else if report.documentation_coverage >= 40 {
    if is_zh(lang) {
      "需要改进"
    } else {
      "Needs improvement"
    }
  } else if is_zh(lang) {
    "高风险"
  } else {
    "High risk"
  }
}

///|
fn readiness_comment(report : ProjectReport, lang : String) -> String {
  if report.documentation_coverage >= 90 &&
    report.readme.found &&
    report.moon_mod.found &&
    report.has_generated_mbti {
    if is_zh(lang) {
      "项目已经具备较好的发布前文档准备度。"
    } else {
      "The project has strong release-readiness signals."
    }
  } else if report.documentation_coverage < 40 {
    if is_zh(lang) {
      "公开 API 文档覆盖率是当前主要短板。"
    } else {
      "Public API documentation is the main blocker."
    }
  } else if !report.readme.found || !report.readme.has_usage {
    if is_zh(lang) {
      "建议优先补充 README 项目介绍和文档入口。"
    } else {
      "README overview and documentation entry should be improved first."
    }
  } else if !report.has_generated_mbti {
    if is_zh(lang) {
      "发布或评审前建议运行 `moon info`。"
    } else {
      "Run `moon info` before publishing or review."
    }
  } else if is_zh(lang) {
    "项目基本可用,但仍有文档缺口。"
  } else {
    "The project is usable but still has documentation gaps."
  }
}

///|
fn missing_api_files(report : ProjectReport) -> Array[FileCoverage] {
  let files : Array[FileCoverage] = []
  for item in report.file_coverage {
    if item.public_api_missing_docs > 0 {
      files.push(item)
    }
  }
  files
}

///|
fn top_missing_files(
  report : ProjectReport,
  limit : Int,
) -> Array[FileCoverage] {
  let files = missing_api_files(report)
  files.sort_by((a, b) => {
    if a.documentation_coverage != b.documentation_coverage {
      a.documentation_coverage.compare(b.documentation_coverage)
    } else {
      b.public_api_missing_docs.compare(a.public_api_missing_docs)
    }
  })
  if files.length() <= limit {
    files
  } else {
    files[:limit].to_owned()
  }
}

///|
fn rule_line() -> String {
  "----------------------------------------"
}

///|
fn fix_hint(issue : DocIssue, lang : String) -> String {
  if issue.message.contains("Missing documentation for public API") {
    if is_zh(lang) {
      "在该公开 API 前添加 `///` 文档注释。"
    } else {
      "Add a leading `///` doc comment before this public API."
    }
  } else if issue.message.contains("Weak documentation") {
    if is_zh(lang) {
      "将占位注释改成说明用途或用法的句子。"
    } else {
      "Replace placeholder docs with a useful purpose or usage sentence."
    }
  } else if issue.message.contains("README") {
    if is_zh(lang) {
      "在 README 中补充缺失的项目信息。"
    } else {
      "Update README with the missing project information."
    }
  } else if issue.message.contains("moon.mod") {
    if is_zh(lang) {
      "在 `moon.mod` 中补充缺失元数据。"
    } else {
      "Add the missing metadata field in `moon.mod`."
    }
  } else if issue.message.contains("moon info") {
    if is_zh(lang) {
      "运行 `moon info`,并按需保留接口摘要。"
    } else {
      "Run `moon info` and keep generated interface summaries when appropriate."
    }
  } else if is_zh(lang) {
    "检查该项并完善项目文档。"
  } else {
    "Review this item and update the project documentation."
  }
}

///|
fn issue_message(issue : DocIssue, lang : String) -> String {
  if !is_zh(lang) {
    issue.message
  } else if issue.message.has_prefix("Missing documentation for public API `") {
    match issue.message.strip_prefix("Missing documentation for public API `") {
      Some(rest) => "公开 API `" + rest.to_owned()
      None => issue.message
    }
  } else if issue.message.has_prefix("Weak documentation for public API `") {
    match issue.message.strip_prefix("Weak documentation for public API `") {
      Some(rest) => "公开 API 文档较弱 `" + rest.to_owned()
      None => issue.message
    }
  } else if issue.message == "README file not found" {
    "未找到 README 文件"
  } else if issue.message == "README is missing usage instructions" {
    "README 缺少使用说明"
  } else if issue.message == "README is missing project overview" {
    "README 缺少项目介绍"
  } else if issue.message == "README is missing documentation entry" {
    "README 缺少文档入口"
  } else if issue.message == "README has no code example" {
    "README 缺少代码示例"
  } else if issue.message == "README does not mention development commands" {
    "README 未提到开发命令"
  } else if issue.message == "README does not mention the license" {
    "README 未提到许可证"
  } else if issue.message == "`moon.mod` file not found" {
    "未找到 `moon.mod` 文件"
  } else if issue.message.contains("`moon.mod` is missing") {
    issue.message.replace(old="`moon.mod` is missing", new="`moon.mod` 缺少")
  } else if issue.message == "GitHub Actions workflow not found" {
    "未找到 GitHub Actions workflow"
  } else if issue.message.has_prefix("CI does not run") {
    issue.message.replace(old="CI does not run", new="CI 未运行")
  } else if issue.message.has_prefix("Generated interface summary not found") {
    "未找到生成的接口摘要;发布或评审前请运行 `moon info`"
  } else if issue.message.has_prefix(
      "Public API documentation coverage is below configured minimum",
    ) {
    "公开 API 文档覆盖率低于配置的最低要求"
  } else {
    issue.message
  }
}

///|
fn push_summary(
  lines : Array[String],
  report : ProjectReport,
  lang : String,
) -> Unit {
  lines.push(
    if is_zh(lang) {
      "公开 API 文档:"
    } else {
      "Public API documentation:"
    },
  )
  lines.push(
    (if is_zh(lang) { "  总数: " } else { "  Total: " }) +
    report.public_api_total.to_string(),
  )
  lines.push(
    (if is_zh(lang) { "  已文档化: " } else { "  Documented: " }) +
    report.public_api_documented.to_string(),
  )
  lines.push(
    (if is_zh(lang) { "  缺失: " } else { "  Missing: " }) +
    report.public_api_missing_docs.to_string(),
  )
  lines.push(
    (if is_zh(lang) { "  覆盖率: " } else { "  Coverage: " }) +
    report.documentation_coverage.to_string() +
    "%",
  )
}

///|
fn push_assessment(
  lines : Array[String],
  report : ProjectReport,
  lang : String,
) -> Unit {
  lines.push(if is_zh(lang) { "总体评价:" } else { "Overall assessment:" })
  lines.push(
    (if is_zh(lang) { "  等级: " } else { "  Level: " }) +
    readiness_level(report, lang),
  )
  lines.push(
    (if is_zh(lang) { "  说明: " } else { "  Comment: " }) +
    readiness_comment(report, lang),
  )
  lines.push(
    if is_zh(lang) {
      "  摘要: " +
      report.public_api_total.to_string() +
      " 个公开 API 中有 " +
      report.public_api_missing_docs.to_string() +
      " 个缺少文档。"
    } else {
      "  Summary: " +
      report.public_api_missing_docs.to_string() +
      " of " +
      report.public_api_total.to_string() +
      " public APIs are missing docs."
    },
  )
}

///|
fn push_top_missing(
  lines : Array[String],
  report : ProjectReport,
  lang : String,
) -> Unit {
  let top_files = top_missing_files(report, 5)
  if !top_files.is_empty() {
    lines.push("")
    lines.push(
      if is_zh(lang) {
        "缺文档重灾区:"
      } else {
        "Top missing-doc files:"
      },
    )
    for summary in top_files {
      lines.push(
        "  - " +
        display_path(report, summary.file) +
        ": " +
        summary.public_api_missing_docs.to_string() +
        (if is_zh(lang) { " 个缺失," } else { " missing, " }) +
        summary.documentation_coverage.to_string() +
        (if is_zh(lang) { "% 覆盖率" } else { "% coverage" }),
      )
    }
  }
}

///|
fn push_file_coverage(
  lines : Array[String],
  report : ProjectReport,
  lang : String,
) -> Unit {
  if !report.file_coverage.is_empty() {
    lines.push("")
    lines.push(if is_zh(lang) { "文件覆盖率:" } else { "File coverage:" })
    for summary in report.file_coverage {
      lines.push(
        "  - " +
        display_path(report, summary.file) +
        ": " +
        summary.public_api_documented.to_string() +
        "/" +
        summary.public_api_total.to_string() +
        (if is_zh(lang) { " 已文档化 (" } else { " documented (" }) +
        summary.documentation_coverage.to_string() +
        "%)",
      )
    }
  }
}

///|
fn push_project_signals(
  lines : Array[String],
  report : ProjectReport,
  lang : String,
) -> Unit {
  lines.push("")
  lines.push(rule_line())
  lines.push("")
  lines.push("README:")
  lines.push(
    (if is_zh(lang) { "  找到: " } else { "  Found: " }) +
    yes_no_lang(report.readme.found, lang),
  )
  lines.push(
    (if is_zh(lang) { "  有项目介绍: " } else { "  Has overview: " }) +
    yes_no_lang(report.readme.has_overview, lang),
  )
  lines.push(
    (if is_zh(lang) { "  有文档入口: " } else { "  Has docs entry: " }) +
    yes_no_lang(report.readme.has_usage, lang),
  )
  lines.push(
    (if is_zh(lang) {
      "  提到许可证: "
    } else {
      "  Has license mention: "
    }) +
    yes_no_lang(report.readme.has_license_mention, lang),
  )
  lines.push("")
  lines.push(if is_zh(lang) { "Moon 元数据:" } else { "Moon metadata:" })
  lines.push("  moon.mod: " + yes_no_lang(report.moon_mod.found, lang))
  lines.push(
    "  moon.mod.json: " + yes_no_lang(report.moon_mod.legacy_json_found, lang),
  )
  lines.push(
    (if is_zh(lang) { "  有描述: " } else { "  Has description: " }) +
    yes_no_lang(report.moon_mod.has_description, lang),
  )
  lines.push(
    (if is_zh(lang) { "  有仓库地址: " } else { "  Has repository: " }) +
    yes_no_lang(report.moon_mod.has_repository, lang),
  )
  lines.push(
    (if is_zh(lang) { "  有许可证: " } else { "  Has license: " }) +
    yes_no_lang(report.moon_mod.has_license, lang),
  )
  lines.push("")
  lines.push(
    if is_zh(lang) {
      "生成的接口摘要:"
    } else {
      "Generated interface:"
    },
  )
  lines.push(
    "  pkg.generated.mbti: " + yes_no_lang(report.has_generated_mbti, lang),
  )
  if !report.has_generated_mbti {
    lines.push(
      if is_zh(lang) {
        "  建议: 运行 `moon info`"
      } else {
        "  Suggestion: run `moon info`"
      },
    )
  }
  lines.push("")
  lines.push(if is_zh(lang) { "示例:" } else { "Examples:" })
  lines.push(
    (if is_zh(lang) {
      "  mbt check 代码块: "
    } else {
      "  mbt check blocks: "
    }) +
    report.markdown.mbt_check_blocks.to_string(),
  )
  lines.push(
    (if is_zh(lang) {
      "  普通 MoonBit 代码块: "
    } else {
      "  ordinary MoonBit blocks: "
    }) +
    report.markdown.moonbit_blocks.to_string(),
  )
  lines.push("")
  lines.push("CI:")
  lines.push(
    (if is_zh(lang) {
      "  GitHub Actions 文件数: "
    } else {
      "  GitHub Actions files: "
    }) +
    report.ci.workflow_files.to_string(),
  )
  lines.push("  moon check: " + yes_no_lang(report.ci.has_moon_check, lang))
  lines.push("  moon test: " + yes_no_lang(report.ci.has_moon_test, lang))
  lines.push(
    (if is_zh(lang) { "  脚本式验证: " } else { "  Script validation: " }) +
    yes_no_lang(report.ci.has_script_validation, lang),
  )
}

///|
fn push_issues(
  lines : Array[String],
  report : ProjectReport,
  all_issues : Bool,
  lang : String,
) -> Unit {
  if !report.issues.is_empty() {
    lines.push("")
    lines.push(rule_line())
    lines.push("")
    lines.push(if is_zh(lang) { "问题清单:" } else { "Issues:" })
    let limit = if all_issues {
      report.issues.length()
    } else if report.issues.length() > 20 {
      20
    } else {
      report.issues.length()
    }
    for index in 0.. limit {
      lines.push(
        "  ... " + (report.issues.length() - limit).to_string() + " more issues",
      )
      lines.push(
        if is_zh(lang) {
          "  使用 `--all-issues` 或导出 Markdown 查看完整列表。"
        } else {
          "  Run with `--all-issues` or `--format markdown --output DOC_REPORT.md` to view the full list."
        },
      )
    }
  }
}

///|
fn next_steps(report : ProjectReport, lang : String) -> Array[String] {
  let steps : Array[String] = []
  if report.public_api_missing_docs > 0 {
    steps.push(
      if is_zh(lang) {
        "优先给缺文档重灾区中的公开 API 添加 `///` 注释。"
      } else {
        "Add `///` comments to public APIs in the top missing-doc files first."
      },
    )
  }
  if !report.readme.found {
    steps.push(
      if is_zh(lang) {
        "补充 README,让用户先看到项目用途、安装或运行方式。"
      } else {
        "Add a README that explains the project purpose and how to run it."
      },
    )
  } else if !report.readme.has_usage {
    steps.push(
      if is_zh(lang) {
        "在 README 中补充项目入口、目录跳转或用户指南链接。"
      } else {
        "Add project entry points, a contents section, or a user guide link to the README."
      },
    )
  }
  if report.markdown.moonbit_blocks > 0 && report.markdown.mbt_check_blocks == 0 {
    steps.push(
      if is_zh(lang) {
        "把关键 MoonBit 示例改成 ```mbt check,让示例可以被工具检查。"
      } else {
        "Convert key MoonBit examples to ```mbt check so they are checked."
      },
    )
  }
  if !report.moon_mod.found && !report.moon_mod.legacy_json_found {
    steps.push(
      if is_zh(lang) {
        "补充 `moon.mod`,并填写描述、仓库地址和许可证等元数据。"
      } else {
        "Add `moon.mod` with description, repository, and license metadata."
      },
    )
  } else if report.moon_mod.legacy_json_found && !report.moon_mod.found {
    steps.push(
      if is_zh(lang) {
        "项目使用旧版 `moon.mod.json`,如准备发布建议迁移或同时说明兼容状态。"
      } else {
        "The project uses legacy `moon.mod.json`; consider migration or document compatibility."
      },
    )
  } else if !report.moon_mod.has_description ||
    !report.moon_mod.has_repository ||
    !report.moon_mod.has_license {
    steps.push(
      if is_zh(lang) {
        "完善 Moon 元数据中的描述、仓库地址或许可证字段。"
      } else {
        "Complete Moon metadata such as description, repository, or license."
      },
    )
  }
  if !report.has_generated_mbti {
    steps.push(
      if is_zh(lang) {
        "发布或评审前运行 `moon info`,生成 `pkg.generated.mbti` 接口摘要。"
      } else {
        "Run `moon info` before release or review to generate `pkg.generated.mbti`."
      },
    )
  }
  if report.ci.workflow_files == 0 {
    steps.push(
      if is_zh(lang) {
        "如果项目要持续维护,建议添加 CI 来运行 MoonBit 检查。"
      } else {
        "If the project will be maintained, add CI for MoonBit checks."
      },
    )
  } else if !report.ci.has_moon_check &&
    !report.ci.has_moon_test &&
    !report.ci.has_script_validation {
    steps.push(
      if is_zh(lang) {
        "在 CI 中加入 `moon check` 或 `moon test`,或明确调用验证脚本。"
      } else {
        "Add `moon check`, `moon test`, or an explicit validation script to CI."
      },
    )
  }
  if report.issues.length() > 20 {
    steps.push(
      if is_zh(lang) {
        "问题较多时用 `--all-issues` 或 `--format html --output report.html` 查看完整列表。"
      } else {
        "For large issue lists, use `--all-issues` or `--format html --output report.html`."
      },
    )
  }
  if steps.is_empty() {
    steps.push(
      if is_zh(lang) {
        "当前没有明显阻塞项,可以保留报告作为发布或评审记录。"
      } else {
        "No obvious blockers were found; keep the report as a release or review record."
      },
    )
  }
  if steps.length() > 5 {
    steps[:5].to_owned()
  } else {
    steps
  }
}

///|
fn push_next_steps(
  lines : Array[String],
  report : ProjectReport,
  lang : String,
) -> Unit {
  lines.push("")
  lines.push(rule_line())
  lines.push("")
  lines.push(if is_zh(lang) { "下一步:" } else { "Next steps:" })
  for step in next_steps(report, lang) {
    lines.push("  - " + step)
  }
}

///|
/// Render a project report as terminal-friendly text.
pub fn render_text(
  report : ProjectReport,
  all_issues? : Bool = false,
  lang? : String = "zh",
) -> String {
  let lines : Array[String] = []
  lines.push(
    if is_zh(lang) {
      "MoonDocCheck 报告"
    } else {
      "MoonDocCheck Report"
    },
  )
  lines.push(rule_line())
  lines.push("")
  lines.push("Project: " + report.project_name)
  lines.push(
    (if is_zh(lang) { "扫描文件数: " } else { "Files scanned: " }) +
    report.files_scanned.to_string(),
  )
  lines.push(
    (if is_zh(lang) {
      "MoonBit 源文件数: "
    } else {
      "MoonBit source files: "
    }) +
    report.moonbit_source_files.to_string(),
  )
  lines.push("")
  push_summary(lines, report, lang)
  lines.push("")
  push_assessment(lines, report, lang)
  push_top_missing(lines, report, lang)
  lines.push("")
  lines.push(rule_line())
  push_file_coverage(lines, report, lang)
  push_project_signals(lines, report, lang)
  push_issues(lines, report, all_issues, lang)
  push_next_steps(lines, report, lang)
  lines.join("\n")
}