///|
fn rule(
  id : String,
  label : String,
  kind : PhiKind,
  pattern : String,
  placeholder : String,
  confidence : Int,
  contextual? : Bool = false,
) -> Rule {
  {
    id,
    label,
    kind,
    pattern,
    placeholder,
    confidence,
    enabled: true,
    contextual,
  }
}

///|
/// Built-in rules cover common PHI in Chinese and English clinical notes.
/// They intentionally favor precision over exhaustive recall.
pub fn builtin_rules() -> Array[Rule] {
  [
    rule(
      "cn_name_context",
      "Chinese contextual name",
      PersonName,
      "(姓名|患者|病人|联系人|家属)[:: ]{1,3}[\\u4e00-\\u9fff]{2,6}",
      "[NAME]",
      94,
      contextual=true,
    ),
    rule(
      "en_name_context",
      "English contextual name",
      PersonName,
      "(Name|Patient|Contact)[:: ]{1,3}[A-Z][a-z]+( [A-Z][a-z]+){0,2}",
      "[NAME]",
      90,
      contextual=true,
    ),
    rule(
      "cn_id",
      "Chinese resident identity number",
      IdNumber,
      "\\b[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])([0-2]\\d|3[0-1])\\d{3}[0-9Xx]\\b",
      "[ID]",
      98,
    ),
    rule(
      "passport",
      "Passport-like identifier",
      IdNumber,
      "\\b([EGPS][0-9]{8}|[A-Z]{1,2}[0-9]{6,9})\\b",
      "[ID]",
      80,
    ),
    rule(
      "cn_mobile",
      "Chinese mobile phone",
      Phone,
      "\\b1[3-9]\\d{9}\\b",
      "[PHONE]",
      96,
    ),
    rule(
      "us_phone",
      "North American phone",
      Phone,
      "\\b\\(?[2-9][0-9]{2}\\)?[ -.]?[0-9]{3}[-.]?[0-9]{4}\\b",
      "[PHONE]",
      88,
    ),
    rule(
      "iso_date",
      "ISO-like date",
      Date,
      "\\b(19|20)\\d{2}[-/.](0?[1-9]|1[0-2])[-/.]([0-2]?\\d|3[0-1])\\b",
      "[DATE]",
      84,
    ),
    rule(
      "cn_date",
      "Chinese date",
      Date,
      "(19|20)\\d{2}年(0?[1-9]|1[0-2])月([0-2]?\\d|3[0-1])日",
      "[DATE]",
      86,
    ),
    rule(
      "email",
      "Email address",
      Email,
      "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}",
      "[EMAIL]",
      95,
    ),
    rule(
      "mrn_context",
      "Medical record number",
      MedicalRecord,
      "(住院号|门诊号|病历号|MRN|Medical Record No\\.)[:: ]{1,3}[A-Za-z0-9-]{4,24}",
      "[MRN]",
      92,
      contextual=true,
    ),
    rule(
      "insurance_context",
      "Insurance number",
      Insurance,
      "(医保号|社保号|Insurance ID)[:: ]{1,3}[A-Za-z0-9-]{6,32}",
      "[INSURANCE]",
      89,
      contextual=true,
    ),
    rule(
      "hospital_context",
      "Organization or hospital",
      Organization,
      "(医院|科室|Hospital|Department)[:: ]{1,3}[\\u4e00-\\u9fffA-Za-z0-9 .-]{2,30}",
      "[ORG]",
      76,
      contextual=true,
    ),
    rule(
      "address_context",
      "Address",
      Address,
      "(住址|地址|Address)[:: ]{1,3}[\\u4e00-\\u9fffA-Za-z0-9 #,.-]{4,60}",
      "[ADDRESS]",
      82,
      contextual=true,
    ),
  ]
}

///|
pub fn enabled_rules(rules : Array[Rule]) -> Array[Rule] {
  rules.filter(fn(r) { r.enabled })
}