///|
/// Language-glyph builtin number formats, mirroring Excelize's
/// `langNumFmt` tables and `langNumFmtFunc` dispatch (numfmt.go). The
/// builtin IDs 27-36, 50-62, and 67-81 have no universal format code:
/// their meaning depends on the workbook's culture, selected through
/// `Options::culture_info` ("en-US", "ja-JP", "ko-KR", "zh-CN", "zh-TW",
/// case-insensitive). An unknown or unset culture leaves the raw value
/// untouched, like Go's `getBuiltInNumFmtCode` ok=false path.

///|
fn normalize_culture_info(value : String) -> String {
  value.to_lower().replace_all(old="_", new="-").trim().to_owned()
}

///|
fn lang_num_fmt_zh_tw(id : Int) -> String {
  match id {
    27 | 36 | 50 | 57 => "[$-404]e/m/d"
    28 | 29 | 51 | 54 | 58 => "[$-404]e\"年\"m\"月\"d\"日\""
    30 => "m/d/yy"
    31 => "yyyy\"年\"m\"月\"d\"日\""
    32 => "hh\"時\"mm\"分\""
    33 => "hh\"時\"mm\"分\"ss\"秒\""
    34 | 52 | 55 => "上午/下午hh\"時\"mm\"分\""
    35 | 53 | 56 => "上午/下午hh\"時\"mm\"分\"ss\"秒\""
    _ => ""
  }
}

///|
fn lang_num_fmt_zh_cn(id : Int) -> String {
  match id {
    27 | 36 | 50 | 52 | 57 => "yyyy\"年\"m\"月\""
    28 | 29 | 51 | 53 | 54 | 58 => "m\"月\"d\"日\""
    30 => "m/d/yy"
    31 => "yyyy\"年\"m\"月\"d\"日\""
    32 => "h\"时\"mm\"分\""
    33 => "h\"时\"mm\"分\"ss\"秒\""
    34 | 55 => "上午/下午h\"时\"mm\"分\""
    35 | 56 => "上午/下午h\"时\"mm\"分\"ss\"秒\""
    _ => ""
  }
}

///|
fn lang_num_fmt_ja_jp(id : Int) -> String {
  match id {
    27 | 36 | 50 | 57 => "[$-411]ge.m.d"
    28 | 29 | 51 | 54 | 58 => "[$-411]ggge\"年\"m\"月\"d\"日\""
    30 => "m/d/yy"
    31 => "yyyy\"年\"m\"月\"d\"日\""
    32 => "h\"時\"mm\"分\""
    33 => "h\"時\"mm\"分\"ss\"秒\""
    34 | 52 | 55 => "yyyy\"年\"m\"月\""
    35 | 53 | 56 => "m\"月\"d\"日\""
    _ => ""
  }
}

///|
fn lang_num_fmt_ko_kr(id : Int) -> String {
  match id {
    27 | 36 | 50 | 57 => "yyyy\"年\" mm\"月\" dd\"日\""
    28 | 29 | 51 | 54 | 58 => "mm-dd"
    30 => "mm-dd-yy"
    31 => "yyyy\"년\" mm\"월\" dd\"일\""
    32 => "h\"시\" mm\"분\""
    33 => "h\"시\" mm\"분\" ss\"초\""
    34 | 35 | 52 | 53 | 55 | 56 => "yyyy-mm-dd"
    _ => ""
  }
}

///|
/// Resolves the format code for a language builtin number format ID under
/// the given options, mirroring Excelize's per-culture `langNumFmtFunc`
/// implementations: en-US renders short-date/long-time patterns, the CJK
/// cultures use their glyph tables, and IDs 30 / 32-33 honor the
/// `short_date_pattern` / `long_time_pattern` option overrides. Returns
/// `None` for an unknown or unset culture.
fn lang_num_fmt_code(options : Options, id : Int) -> String? {
  match normalize_culture_info(options.culture_info) {
    "en-us" => {
      let short_date = if options.short_date_pattern != "" {
        options.short_date_pattern
      } else {
        "M/d/yy"
      }
      let long_time = if options.long_time_pattern != "" {
        options.long_time_pattern
      } else {
        "h:mm:ss"
      }
      match id {
        32..=35 => Some(long_time)
        27..=31 | 50..=58 => Some(short_date)
        _ => Some("")
      }
    }
    "ja-jp" | "ko-kr" | "zh-cn" | "zh-tw" as culture => {
      if id == 30 && options.short_date_pattern != "" {
        return Some(options.short_date_pattern)
      }
      if (id == 32 || id == 33) && options.long_time_pattern != "" {
        return Some(options.long_time_pattern)
      }
      match culture {
        "ja-jp" => Some(lang_num_fmt_ja_jp(id))
        "ko-kr" => Some(lang_num_fmt_ko_kr(id))
        "zh-cn" => Some(lang_num_fmt_zh_cn(id))
        _ => Some(lang_num_fmt_zh_tw(id))
      }
    }
    _ => None
  }
}