// 基本数据结构定义
///|
pub(all) struct Formatter {
  types : Array[FMT_Type]
}

///|
pub(all) enum FMT_Type {
  Text(String)
  Int(space~ : Int, zero_pad~ : Bool, left_align~ : Bool, show_sign~ : Bool) // 添加show_sign
  Double(
    space_front~ : Int,
    space_back~ : Int,
    mode~ : Bool,
    zero_pad~ : Bool,
    left_align~ : Bool,
    show_sign~ : Bool
  )
  String(space~ : Int, left_align~ : Bool)
  HexLower(space~ : Int, zero_pad~ : Bool, left_align~ : Bool)
  HexUpper(space~ : Int, zero_pad~ : Bool, left_align~ : Bool)
  Octal(space~ : Int, zero_pad~ : Bool, left_align~ : Bool)
  Scientific(
    space_front~ : Int,
    space_back~ : Int,
    uppercase~ : Bool,
    show_sign~ : Bool
  )
  General(
    space_front~ : Int,
    space_back~ : Int,
    uppercase~ : Bool,
    show_sign~ : Bool
  ) // 新增General类型
  Unsigned(space~ : Int, zero_pad~ : Bool, left_align~ : Bool)
  Char(space~ : Int, left_align~ : Bool) // 新增字符类型
  Bool(space~ : Int, left_align~ : Bool) // 新增布尔类型
}

///|
pub(all) enum Args_Type {
  String(String)
  Int(Int)
  UInt(UInt) // 无符号整数
  Double(Double)
  Char(Char) // 新增字符类型
  Bool(Bool) // 新增布尔类型
}

// 添加辅助函数检测特殊浮点数值
///|
fn is_infinite(num : Double) -> Bool {
  num == 1.0 / 0.0 || num == -1.0 / 0.0
}

///|
fn is_nan(num : Double) -> Bool {
  num != num
}

///|
fn max(a : Int, b : Int) -> Int {
  if a >= b {
    a
  } else {
    b
  }
}

///|
fn format_general(num : Double, precision : Int, uppercase : Bool) -> String {
  let mut exp = 0
  let mut value = num.abs()

  // 计算指数
  if value != 0.0 {
    while value >= 10.0 {
      value = value / 10.0
      exp += 1
    }
    while value < 1.0 {
      value = value * 10.0
      exp -= 1
    }
  }

  // 根据指数选择格式
  if exp < -4 || exp >= precision {
    // 使用科学计数法
    format_scientific(num, precision - 1, uppercase)
  } else {
    // 使用定点表示法
    format_decimal(num, max(precision - 1 - exp, 0), true)
  }
}

// 进制转换函数
///|
fn to_base(val : Int, base : Int, uppercase : Bool) -> String {
  let digits = match base {
    8 => "01234567"
    16 => if uppercase { "0123456789ABCDEF" } else { "0123456789abcdef" }
    _ => return "Unsupported base"
  }
  if val == 0 {
    return "0"
  }
  let mut result = ""
  let mut num = val
  while num > 0 {
    let remainder = num % base
    result = result + digits[remainder].to_string()
    num /= base
  }
  result.rev()
}

// 科学计数法格式化函数
///|
fn format_scientific(num : Double, precision : Int, uppercase : Bool) -> String {
  let mut exponent = 0
  let mut value = num
  if value != 0.0 {
    while value.abs() >= 10.0 {
      value = value / 10.0
      exponent += 1
    }
    while value.abs() < 1.0 {
      value = value * 10.0
      exponent -= 1
    }
  }
  let mantissa = format_decimal(value, precision, true)
  let exp_symbol = if uppercase { "E" } else { "e" }
  let exp_str = if exponent >= 0 { "+" } else { "-" }
  mantissa + exp_symbol + exp_str + exponent.abs().to_string().pad_start(2, '0')
}

// 浮点数格式化函数
///|
fn format_decimal(num : Double, precision : Int, mode : Bool) -> String {
  // 负零检测
  let mut number = num
  if number == 0.0 {
    number = 0.0
  }
  let mut scale = 1
  for i = 0; i < precision; i = i + 1 {
    scale *= 10
  }
  let rounded = if mode {
    (number * scale.to_double() + 0.5).to_int()
  } else {
    (number * scale.to_double()).to_int()
  }
  let integer_part = (rounded / scale).to_string()
  let decimal_part = (rounded % scale).to_string()
  let mut result = integer_part
  if precision >= 1 {
    result = result + "." + decimal_part
    if result.ends_with(".") {
      result = result.substring(start=0, end=result.length() - 1)
    }
  }
  result
}

///|
pub fn Formatter::new(fmt : String) -> Formatter {
  let types : Array[FMT_Type] = []
  let mut i = 0
  while i < fmt.length() {
    if fmt[i] == '%' {
      if i + 1 == fmt.length() {
        break
      }
      i += 1
      let mut space_front = 0
      let mut space_back = 6
      let mut zero_pad = false
      let mut left_align = false
      let mut show_sign = false

      // 解析格式标志
      while i < fmt.length() {
        match fmt[i] {
          '-' => {
            left_align = true
            i += 1
          }
          '+' => {
            show_sign = true
            i += 1
          }
          '0' => {
            if left_align == false {
              zero_pad = true
            }
            i += 1
          }
          _ => break
        }
      }

      // 解析宽度
      while i < fmt.length() && fmt[i] >= '0' && fmt[i] <= '9' {
        space_front = space_front * 10 + fmt[i].to_int() - 48
        i += 1
      }

      // 解析精度
      if i < fmt.length() && fmt[i] == '.' {
        i += 1
        space_back = 0
        while i < fmt.length() && fmt[i] >= '0' && fmt[i] <= '9' {
          space_back = space_back * 10 + fmt[i].to_int() - 48
          i += 1
        }
      }

      // 处理格式说明符
      if i < fmt.length() {
        match fmt[i] {
          'd' =>
            types.push(
              FMT_Type::Int(
                space=space_front,
                zero_pad~,
                left_align~,
                show_sign~,
              ),
            )
          'f' =>
            types.push(
              FMT_Type::Double(
                space_front~,
                space_back~,
                mode=true,
                zero_pad~,
                left_align~,
                show_sign~,
              ),
            )
          's' => types.push(FMT_Type::String(space=space_front, left_align~))
          'x' =>
            types.push(
              FMT_Type::HexLower(space=space_front, zero_pad~, left_align~),
            )
          'X' =>
            types.push(
              FMT_Type::HexUpper(space=space_front, zero_pad~, left_align~),
            )
          'o' =>
            types.push(
              FMT_Type::Octal(space=space_front, zero_pad~, left_align~),
            )
          'e' =>
            types.push(
              FMT_Type::Scientific(
                space_front~,
                space_back~,
                uppercase=false,
                show_sign~,
              ),
            )
          'E' =>
            types.push(
              FMT_Type::Scientific(
                space_front~,
                space_back~,
                uppercase=true,
                show_sign~,
              ),
            )
          'g' =>
            types.push(
              FMT_Type::General(
                space_front~,
                space_back~,
                uppercase=false,
                show_sign~,
              ),
            )
          'G' =>
            types.push(
              FMT_Type::General(
                space_front~,
                space_back~,
                uppercase=true,
                show_sign~,
              ),
            )
          'u' =>
            types.push(
              FMT_Type::Unsigned(space=space_front, zero_pad~, left_align~),
            )
          'c' => types.push(FMT_Type::Char(space=space_front, left_align~))
          't' => types.push(FMT_Type::Bool(space=space_front, left_align~))
          _ => types.push(FMT_Type::Text("%" + fmt[i].to_string()))
        }
      }
    } else {
      types.push(FMT_Type::Text(fmt[i].to_string()))
    }
    i += 1
  }
  return { types, }
}

///|
pub fn Formatter::fmt(self : Formatter, args : Array[Args_Type]) -> String {
  let mut result = ""
  let mut arg_index = 0
  for typ in self.types {
    match typ {
      FMT_Type::Text(t) => result += t
      FMT_Type::Int(space~, zero_pad~, left_align~, show_sign~) => {
        if arg_index >= args.length() {
          println("Not enough arguments")
          break
        }
        match args[arg_index] {
          Args_Type::Int(val) => {
            let sign = if show_sign && val >= 0 {
              "+"
            } else if val < 0 {
              "-"
            } else {
              ""
            }
            let str_val = val.abs().to_string()
            let pad_char = if zero_pad && left_align == false {
              "0"
            } else {
              " "
            }
            let padding = pad_char.repeat(
              max(0, space - str_val.length() - sign.length()),
            )
            result += if left_align {
              sign + str_val + padding
            } else if zero_pad {
              sign + padding + str_val
            } else {
              padding + sign + str_val
            }
            arg_index += 1
          }
          _ => println("Type mismatch: expected Int")
        }
      }
      FMT_Type::Double(
        space_front~,
        space_back~,
        mode~,
        zero_pad~,
        left_align~,
        show_sign~
      ) =>
        match args[arg_index] {
          Args_Type::Double(val) => {
            let formatted = if is_infinite(val) {
              if val > 0.0 {
                "inf"
              } else {
                "-inf"
              }
            } else if is_nan(val) {
              "nan"
            } else {
              let sign = if show_sign && val >= 0.0 {
                "+"
              } else if val < 0.0 {
                "-"
              } else {
                ""
              }
              sign + format_decimal(val.abs(), space_back, mode)
            }

            // 根据zero_pad选择填充字符
            let pad_char = if zero_pad && left_align == false {
              "0"
            } else {
              " "
            }
            let padding = pad_char.repeat(
              max(0, space_front - formatted.length()),
            )

            // 特殊处理零填充和符号
            result += if left_align {
              formatted + padding
            } else if zero_pad &&
              is_infinite(val) == false &&
              is_nan(val) == false {
              // 对于零填充,需要将符号放在填充字符前面
              let sign_part = if val >= 0.0 && show_sign {
                "+"
              } else if val < 0.0 {
                "-"
              } else {
                ""
              }
              let value_part = formatted.substring(start=sign_part.length())
              sign_part + padding + value_part
            } else {
              padding + formatted
            }
            arg_index += 1
          }
          _ => println("Type mismatch: expected Double")
        }
      FMT_Type::String(space~, left_align~) => {
        if arg_index >= args.length() {
          println("Not enough arguments")
          break
        }
        match args[arg_index] {
          Args_Type::String(val) => {
            let padding = " ".repeat(max(0, space - val.length()))
            result += if left_align { val + padding } else { padding + val }
            arg_index += 1
          }
          _ => println("Type mismatch: expected String")
        }
      }
      FMT_Type::HexLower(space~, zero_pad~, left_align~) => {
        if arg_index >= args.length() {
          println("Not enough arguments")
          break
        }
        match args[arg_index] {
          Args_Type::Int(val) => {
            let str_val = to_base(val, 16, false)
            let pad_char = if zero_pad && left_align == false {
              "0"
            } else {
              " "
            }
            let padding = pad_char.repeat(max(0, space - str_val.length()))
            result += if left_align {
              str_val + padding
            } else {
              padding + str_val
            }
            arg_index += 1
          }
          _ => println("Type mismatch: expected Int")
        }
      }
      FMT_Type::HexUpper(space~, zero_pad~, left_align~) => {
        if arg_index >= args.length() {
          println("Not enough arguments")
          break
        }
        match args[arg_index] {
          Args_Type::Int(val) => {
            let str_val = to_base(val, 16, true)
            let pad_char = if zero_pad && left_align == false {
              "0"
            } else {
              " "
            }
            let padding = pad_char.repeat(max(0, space - str_val.length()))
            result += if left_align {
              str_val + padding
            } else {
              padding + str_val
            }
            arg_index += 1
          }
          _ => println("Type mismatch: expected Int")
        }
      }
      FMT_Type::Octal(space~, zero_pad~, left_align~) => {
        if arg_index >= args.length() {
          println("Not enough arguments")
          break
        }
        match args[arg_index] {
          Args_Type::Int(val) => {
            let str_val = to_base(val, 8, false)
            let pad_char = if zero_pad && left_align == false {
              "0"
            } else {
              " "
            }
            let padding = pad_char.repeat(max(0, space - str_val.length()))
            result += if left_align {
              str_val + padding
            } else {
              padding + str_val
            }
            arg_index += 1
          }
          _ => println("Type mismatch: expected Int")
        }
      }
      FMT_Type::Scientific(space_front~, space_back~, uppercase~, show_sign~) => {
        if arg_index >= args.length() {
          println("Not enough arguments")
          break
        }
        match args[arg_index] {
          Args_Type::Double(val) => {
            let sign = if show_sign && val >= 0.0 {
              "+"
            } else if val < 0.0 {
              "-"
            } else {
              ""
            }
            let formatted = format_scientific(val.abs(), space_back, uppercase)
            let padding = " ".repeat(
              max(0, space_front - formatted.length() - sign.length()),
            )
            result += padding + sign + formatted
            arg_index += 1
          }
          _ => println("Type mismatch: expected Double")
        }
      }
      FMT_Type::General(space_front~, space_back~, uppercase~, show_sign~) =>
        match args[arg_index] {
          Args_Type::Double(val) => {
            let formatted = if is_infinite(val) {
              if val > 0.0 {
                if uppercase {
                  "INF"
                } else {
                  "inf"
                }
              } else if uppercase {
                "-INF"
              } else {
                "-inf"
              }
            } else if is_nan(val) {
              if uppercase {
                "NAN"
              } else {
                "nan"
              }
            } else {
              let sign = if show_sign && val >= 0.0 {
                "+"
              } else if val < 0.0 {
                "-"
              } else {
                ""
              }
              sign + format_general(val.abs(), space_back, uppercase)
            }
            let padding = " ".repeat(max(0, space_front - formatted.length()))
            result += padding + formatted
            arg_index += 1
          }
          _ => println("Type mismatch: expected Double")
        }
      FMT_Type::Unsigned(space~, zero_pad~, left_align~) => {
        if arg_index >= args.length() {
          println("Not enough arguments")
          break
        }
        match args[arg_index] {
          Args_Type::UInt(val) => {
            let str_val = val.to_string()
            let pad_char = if zero_pad && left_align == false {
              "0"
            } else {
              " "
            }
            let padding = pad_char.repeat(max(0, space - str_val.length()))
            result += if left_align {
              str_val + padding
            } else {
              padding + str_val
            }
            arg_index += 1
          }
          _ => println("Type mismatch: expected UInt")
        }
      }
      FMT_Type::Char(space~, left_align~) => {
        if arg_index >= args.length() {
          println("Not enough arguments")
          break
        }
        match args[arg_index] {
          Args_Type::Char(val) => {
            let str_val = val.to_string()
            let padding = " ".repeat(max(0, space - 1)) // 字符总是长度为1
            result += if left_align {
              str_val + padding
            } else {
              padding + str_val
            }
            arg_index += 1
          }
          _ => println("Type mismatch: expected Char")
        }
      }
      FMT_Type::Bool(space~, left_align~) => {
        if arg_index >= args.length() {
          println("Not enough arguments")
          break
        }
        match args[arg_index] {
          Args_Type::Bool(val) => {
            let str_val = if val { "true" } else { "false" }
            let padding = " ".repeat(max(0, space - str_val.length()))
            result += if left_align {
              str_val + padding
            } else {
              padding + str_val
            }
            arg_index += 1
          }
          _ => println("Type mismatch: expected Bool")
        }
      }
    }
  }
  return result
}