///|
/// 增强像素画布:抗锯齿(2x 超采样)+ 圆角矩形 + 5×7 位图字体 + DEFLATE 压缩。
///
/// 渲染管线:Document → layout → 高分辨率 RGBA → downscale → DEFLATE PNG。
/// 输出比 store-mode 小 5-20 倍,且边缘平滑、有文字标注、圆角柔和。

// ---------------------------------------------------------------------------
// 高分辨率 RGBA 帧缓冲(2x 超采样 → 内部像素密度 = 2)
// ---------------------------------------------------------------------------

struct HiResBuf {
  width : Int // 最终输出宽
  height : Int
  ss : Int // 超采样倍率(当前固定 2)
  pixels : FixedArray[Int] // ARGB,尺寸 = (width*ss) * (height*ss)
}

///|
fn hires_new(width : Int, height : Int) -> HiResBuf {
  let ss = 2
  {
    width,
    height,
    ss,
    pixels: FixedArray::make(width * ss * height * ss, 0xFF000000),
  }
}

///|
fn hires_set(buf : HiResBuf, x : Int, y : Int, argb : Int) -> Unit {
  let w = buf.width * buf.ss
  if x >= 0 && x < w && y >= 0 && y < buf.height * buf.ss {
    buf.pixels[y * w + x] = argb
  }
}

///|
fn hires_get(buf : HiResBuf, x : Int, y : Int) -> Int {
  let w = buf.width * buf.ss
  if x >= 0 && x < w && y >= 0 && y < buf.height * buf.ss {
    buf.pixels[y * w + x]
  } else {
    0xFF000000
  }
}

// ---------------------------------------------------------------------------
// 抗锯齿 downsample(box filter 2x2 → 1x)
// ---------------------------------------------------------------------------

///|
fn downsample(buf : HiResBuf) -> RgbaBuf {
  let out = rgba_new(buf.width, buf.height)
  for y in 0.. Int {
  let r = (
      ((a >> 16) & 0xFF) +
      ((b >> 16) & 0xFF) +
      ((c >> 16) & 0xFF) +
      ((d >> 16) & 0xFF)
    ) /
    4
  let g = (
      ((a >> 8) & 0xFF) +
      ((b >> 8) & 0xFF) +
      ((c >> 8) & 0xFF) +
      ((d >> 8) & 0xFF)
    ) /
    4
  let bl = ((a & 0xFF) + (b & 0xFF) + (c & 0xFF) + (d & 0xFF)) / 4
  0xFF000000 + (r << 16) + (g << 8) + bl
}

// ---------------------------------------------------------------------------
// 圆角矩形(超采样坐标系下逐像素填充)
// ---------------------------------------------------------------------------

///|
fn fill_rounded_rect(
  buf : HiResBuf,
  x : Double,
  y : Double,
  w : Double,
  h : Double,
  radius : Double,
  argb : Int,
) -> Unit {
  let ss = buf.ss.to_double()
  let x0 = (x * ss).to_int()
  let y0 = (y * ss).to_int()
  let x1 = ((x + w) * ss).to_int()
  let y1 = ((y + h) * ss).to_int()
  let r = (radius * ss).to_int()
  for yy in y0.. Bool {
  if r <= 0 {
    return true
  }
  let r = if r * 2 > w { w / 2 } else if r * 2 > h { h / 2 } else { r }
  // 四角检查
  let cx = if px < r { r } else if px > w - r { w - r } else { px }
  let cy = if py < r { r } else if py > h - r { h - r } else { py }
  let dx = px - cx
  let dy = py - cy
  dx * dx + dy * dy <= r * r
}

///|
fn stroke_rounded_rect(
  buf : HiResBuf,
  x : Double,
  y : Double,
  w : Double,
  h : Double,
  radius : Double,
  argb : Int,
) -> Unit {
  let ss = buf.ss.to_double()
  let x0 = (x * ss).to_int()
  let y0 = (y * ss).to_int()
  let x1 = ((x + w) * ss).to_int()
  let y1 = ((y + h) * ss).to_int()
  let r = (radius * ss).to_int()
  let bw = x1 - x0
  let bh = y1 - y0
  let r = if r * 2 > bw { bw / 2 } else if r * 2 > bh { bh / 2 } else { r }
  for yy in y0.. bw - r { bw - r } else { px }
      let cy = if py < r { r } else if py > bh - r { bh - r } else { py }
      let dx = px - cx
      let dy = py - cy
      let dist2 = dx * dx + dy * dy
      let outer = r + 2 // 边框厚度(超采样像素)
      let inner = r - 2
      if r <= 0 {
        // 直角:只画边缘
        if px <= 2 || px >= bw - 3 || py <= 2 || py >= bh - 3 {
          hires_set(buf, xx, yy, argb)
        }
      } else if dist2 <= outer * outer && dist2 >= inner * inner {
        hires_set(buf, xx, yy, argb)
      } else if r <= 2 && (px <= 1 || px >= bw - 2 || py <= 1 || py >= bh - 2) {
        hires_set(buf, xx, yy, argb)
      }
    }
  }
}

// ---------------------------------------------------------------------------
// 5×7 位图字体(ASCII 32–126 的核心字符)
// ---------------------------------------------------------------------------

///|
fn font_a() -> FixedArray[Int] {
  [0x0E, 0x11, 0x11, 0x1F, 0x11, 0x11, 0x11] // A
}

///|
fn font_b() -> FixedArray[Int] {
  [0x1E, 0x11, 0x11, 0x1E, 0x11, 0x11, 0x1E] // B
}

///|
fn font_c() -> FixedArray[Int] {
  [0x0E, 0x11, 0x10, 0x10, 0x10, 0x11, 0x0E] // C
}

///|
fn font_d() -> FixedArray[Int] {
  [0x1C, 0x12, 0x11, 0x11, 0x11, 0x12, 0x1C] // D
}

///|
fn font_e() -> FixedArray[Int] {
  [0x1F, 0x10, 0x10, 0x1E, 0x10, 0x10, 0x1F] // E
}

///|
fn font_f() -> FixedArray[Int] {
  [0x1F, 0x10, 0x10, 0x1E, 0x10, 0x10, 0x10] // F
}

///|
fn font_g() -> FixedArray[Int] {
  [0x0E, 0x11, 0x10, 0x17, 0x11, 0x11, 0x0E] // G
}

///|
fn font_h() -> FixedArray[Int] {
  [0x11, 0x11, 0x11, 0x1F, 0x11, 0x11, 0x11] // H
}

///|
fn font_i() -> FixedArray[Int] {
  [0x0E, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0E] // I
}

///|
fn font_j() -> FixedArray[Int] {
  [0x01, 0x01, 0x01, 0x01, 0x01, 0x11, 0x0E] // J
}

///|
fn font_k() -> FixedArray[Int] {
  [0x11, 0x12, 0x14, 0x18, 0x14, 0x12, 0x11] // K
}

///|
fn font_l() -> FixedArray[Int] {
  [0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F] // L
}

///|
fn font_m() -> FixedArray[Int] {
  [0x11, 0x1B, 0x15, 0x15, 0x11, 0x11, 0x11] // M
}

///|
fn font_n() -> FixedArray[Int] {
  [0x11, 0x19, 0x15, 0x13, 0x11, 0x11, 0x11] // N
}

///|
fn font_o() -> FixedArray[Int] {
  [0x0E, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0E] // O
}

///|
fn font_p() -> FixedArray[Int] {
  [0x1E, 0x11, 0x11, 0x1E, 0x10, 0x10, 0x10] // P
}

///|
fn font_q() -> FixedArray[Int] {
  [0x0E, 0x11, 0x11, 0x11, 0x15, 0x12, 0x0D] // Q
}

///|
fn font_r() -> FixedArray[Int] {
  [0x1E, 0x11, 0x11, 0x1E, 0x14, 0x12, 0x11] // R
}

///|
fn font_s() -> FixedArray[Int] {
  [0x0F, 0x10, 0x10, 0x0E, 0x01, 0x01, 0x1E] // S
}

///|
fn font_t() -> FixedArray[Int] {
  [0x1F, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04] // T
}

///|
fn font_u() -> FixedArray[Int] {
  [0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0E] // U
}

///|
fn font_v() -> FixedArray[Int] {
  [0x11, 0x11, 0x11, 0x11, 0x11, 0x0A, 0x04] // V
}

///|
fn font_w() -> FixedArray[Int] {
  [0x11, 0x11, 0x11, 0x15, 0x15, 0x1B, 0x11] // W
}

///|
fn font_x() -> FixedArray[Int] {
  [0x11, 0x11, 0x0A, 0x04, 0x0A, 0x11, 0x11] // X
}

///|
fn font_y() -> FixedArray[Int] {
  [0x11, 0x11, 0x0A, 0x04, 0x04, 0x04, 0x04] // Y
}

///|
fn font_z() -> FixedArray[Int] {
  [0x1F, 0x01, 0x02, 0x04, 0x08, 0x10, 0x1F] // Z
}

///|
fn font_0() -> FixedArray[Int] {
  [0x0E, 0x11, 0x13, 0x15, 0x19, 0x11, 0x0E] // 0
}

///|
fn font_1() -> FixedArray[Int] {
  [0x04, 0x0C, 0x04, 0x04, 0x04, 0x04, 0x0E] // 1
}

///|
fn font_2() -> FixedArray[Int] {
  [0x0E, 0x11, 0x01, 0x02, 0x04, 0x08, 0x1F] // 2
}

///|
fn font_3() -> FixedArray[Int] {
  [0x0E, 0x11, 0x01, 0x06, 0x01, 0x11, 0x0E] // 3
}

///|
fn font_4() -> FixedArray[Int] {
  [0x02, 0x06, 0x0A, 0x12, 0x1F, 0x02, 0x02] // 4
}

///|
fn font_5() -> FixedArray[Int] {
  [0x1F, 0x10, 0x1E, 0x01, 0x01, 0x11, 0x0E] // 5
}

///|
fn font_6() -> FixedArray[Int] {
  [0x06, 0x08, 0x10, 0x1E, 0x11, 0x11, 0x0E] // 6
}

///|
fn font_7() -> FixedArray[Int] {
  [0x1F, 0x01, 0x02, 0x04, 0x08, 0x08, 0x08] // 7
}

///|
fn font_8() -> FixedArray[Int] {
  [0x0E, 0x11, 0x11, 0x0E, 0x11, 0x11, 0x0E] // 8
}

///|
fn font_9() -> FixedArray[Int] {
  [0x0E, 0x11, 0x11, 0x0F, 0x01, 0x02, 0x0C] // 9
}

///|
/// ASCII → 5 位行编码(7 行)
fn glyph_of(c : Char) -> FixedArray[Int]? {
  match c {
    'A' => Some(font_a())
    'B' => Some(font_b())
    'C' => Some(font_c())
    'D' => Some(font_d())
    'E' => Some(font_e())
    'F' => Some(font_f())
    'G' => Some(font_g())
    'H' => Some(font_h())
    'I' => Some(font_i())
    'J' => Some(font_j())
    'K' => Some(font_k())
    'L' => Some(font_l())
    'M' => Some(font_m())
    'N' => Some(font_n())
    'O' => Some(font_o())
    'P' => Some(font_p())
    'Q' => Some(font_q())
    'R' => Some(font_r())
    'S' => Some(font_s())
    'T' => Some(font_t())
    'U' => Some(font_u())
    'V' => Some(font_v())
    'W' => Some(font_w())
    'X' => Some(font_x())
    'Y' => Some(font_y())
    'Z' => Some(font_z())
    '0' => Some(font_0())
    '1' => Some(font_1())
    '2' => Some(font_2())
    '3' => Some(font_3())
    '4' => Some(font_4())
    '5' => Some(font_5())
    '6' => Some(font_6())
    '7' => Some(font_7())
    '8' => Some(font_8())
    '9' => Some(font_9())
    _ => None
  }
}

///|
/// 在超采样坐标画一段文字(5×7 位图,每字符间隔 1 列)
fn draw_text_hires(
  buf : HiResBuf,
  text : String,
  x : Double,
  y : Double,
  argb : Int,
) -> Unit {
  let ss = buf.ss.to_double()
  let bx = (x * ss).to_int()
  let by = (y * ss).to_int()
  let scale = buf.ss // 字体缩放 = ss(最终输出中 5×7 → 10×14 有效像素)
  for ci in 0..
        match glyph_of(c) {
          Some(glyph) =>
            for row in 0..<7 {
              for col in 0..<5 {
                let bit = (glyph[row] >> (4 - col)) & 1
                if bit == 1 {
                  for sy in 0.. ()
        }
      None => ()
    }
  }
}

// ---------------------------------------------------------------------------
// 主渲染入口:Document → 高分辨率 RGBA → downsample → DEFLATE PNG
// ---------------------------------------------------------------------------

///|
pub fn render_png_hires(
  doc : @core.Document,
  width : Int,
  height : Int,
) -> Array[Byte] {
  let layout = @core.solve(doc)
  let buf = hires_new(width, height)
  let ss = buf.ss.to_double()

  // 白底
  fill_rounded_rect(
    buf,
    0.0,
    0.0,
    width.to_double(),
    height.to_double(),
    0.0,
    color_from_hex("#F8F9FB"),
  )

  // 树序遍历渲染
  render_node_hires(buf, doc, doc.root_id, layout, ss)
  let down = downsample(buf)
  png_encode_deflate(down)
}

///|
fn render_node_hires(
  buf : HiResBuf,
  doc : @core.Document,
  id : String,
  layout : @core.SolvedLayout,
  ss : Double,
) -> Unit {
  match doc.nodes.get(id) {
    None => ()
    Some(n) =>
      match layout.rect_of(id) {
        None => ()
        Some(r) => {
          let fill_hex : String = if n.style.fill == "none" {
            ""
          } else {
            n.style.fill
          }
          let radius = n.style.corner_radius
          // 填充
          if fill_hex != "" && fill_hex != "#FFFFFF" {
            fill_rounded_rect(
              buf,
              r.x,
              r.y,
              r.width,
              r.height,
              radius,
              color_from_hex(fill_hex),
            )
          }
          // 边框
          let border_c : Int = if n.style.stroke != "none" {
            color_from_hex(n.style.stroke)
          } else {
            color_from_hex("#C8CDD6")
          }
          stroke_rounded_rect(
            buf,
            r.x,
            r.y,
            r.width,
            r.height,
            radius,
            border_c,
          )
          // 文字(取 id 的大写首字母段或 n.text 的 ASCII 部分)
          let label : String = if n.text != "" {
            ascii_only(n.text)
          } else {
            ascii_only(n.id)
          }
          if label != "" {
            let tx = r.x + 8.0
            let ty = r.y + 4.0
            let tc : Int = if fill_hex != "" && is_dark_hex(fill_hex) {
              color_from_hex("#FFFFFF")
            } else {
              color_from_hex("#333333")
            }
            draw_text_hires(buf, label, tx, ty, tc)
          }
          for cid in n.children.iter() {
            render_node_hires(buf, doc, cid, layout, ss)
          }
        }
      }
  }
}

///|
fn ascii_only(s : String) -> String {
  let sb = StringBuilder::new()
  for c in s.iter() {
    let code = c.to_int()
    if code >= 32 && code <= 126 {
      sb.write_char(c)
    }
  }
  sb.to_string()
}

///|
fn is_dark_hex(hex : String) -> Bool {
  match rgb_of(hex) {
    None => false
    Some((r, g, b)) => (r + g + b) / 3 < 128
  }
}

// ---------------------------------------------------------------------------
// DEFLATE 压缩版 PNG 编码
// ---------------------------------------------------------------------------

///|
fn png_encode_deflate(buf : RgbaBuf) -> Array[Byte] {
  let out : Array[Byte] = []
  // 签名
  push_b(out, 137)
  push_b(out, 80)
  push_b(out, 78)
  push_b(out, 71)
  push_b(out, 13)
  push_b(out, 10)
  push_b(out, 26)
  push_b(out, 10)

  // IHDR
  let ihdr : Array[Byte] = []
  push_be32(ihdr, buf.width)
  push_be32(ihdr, buf.height)
  push_b(ihdr, 8)
  push_b(ihdr, 6)
  push_b(ihdr, 0)
  push_b(ihdr, 0)
  push_b(ihdr, 0)
  let ihdr_chunk = png_chunk("IHDR", ihdr)
  for x in ihdr_chunk.iter() {
    out.push(x)
  }

  // 原始扫描线
  let raw : Array[Byte] = []
  for y in 0..> 16) & 0xFF)
      push_b(raw, (px >> 8) & 0xFF)
      push_b(raw, px & 0xFF)
      push_b(raw, (px >> 24) & 0xFF)
    }
  }

  // DEFLATE 压缩
  let raw_bytes = Bytes::from_iter(raw.iter())
  let compressed = deflate_compress_fixed_v(raw_bytes)

  // zlib 包装(2 字节头 + deflate + 4 字节 adler)
  let zlib : Array[Byte] = []
  push_b(zlib, 0x78)
  push_b(zlib, 0x01)
  for i in 0.. zlib.push(b)
      None => ()
    }
  }
  push_be32(zlib, adler32(raw))

  let idat = png_chunk("IDAT", zlib)
  for x in idat.iter() {
    out.push(x)
  }

  // IEND
  let iend = png_chunk("IEND", [])
  for x in iend.iter() {
    out.push(x)
  }
  out
}