///|
const TaskCardStyle : String = "display:flex;flex-direction:column;gap:4px;width:100%;max-width:640px;padding:12px 16px;border-radius:16px;background:var(--sumi-frame-80,rgba(32,32,34,0.8));backdrop-filter:blur(40px);-webkit-backdrop-filter:blur(40px)"

///|
const TaskCardTitleStyle : String = "margin:0;min-width:0;font-size:14px;line-height:24px;font-weight:500;color:var(--sumi-text,#ffffff);overflow:hidden;text-overflow:ellipsis;white-space:nowrap"

///|
const TaskCardSummaryStyle : String = "margin:0;font-size:14px;line-height:24px;color:var(--sumi-text-secondary,rgba(255,255,255,0.7));overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical"

///|
/// A submitted-task bubble of the task list: a frosted 16px-radius card
/// with a 14/24 Medium title, an optional generation status, and a
/// two-line summary. Pass `children` instead of `summary` for a rich body
/// (e.g. a `tool_call_row`).
///
/// ```moonbit nocheck
/// task_card(
///   title="Neon Harbor Nights",
///   status=Generating,
///   summary="I will first break down the brief into its core elements.",
/// )
/// ```
pub fn task_card(
  title~ : String,
  status? : SessionStatus,
  summary? : String = "",
  children? : Array[@html.Html],
  on_click? : @cmd.Cmd,
  aria_label? : String,
  id? : String,
  class? : String,
  attrs? : @html.Attrs,
  style? : Array[String] = [],
) -> @html.Html {
  let element_attrs = @internal.sumi_attrs(attrs).data_set("slot", "task-card")
  if aria_label is Some(label_text) {
    ignore(element_attrs.aria_label(label_text))
  }
  let status_view : @html.Html = match status {
    Some(kind) => session_status(kind~)
    None => @html.nothing
  }
  let body : @html.Html = match children {
    Some(rich) =>
      @html.div(
        style=["width:100%;min-width:0"],
        attrs=@html.Attrs::build().data_set("slot", "task-card-body"),
        rich,
      )
    None => @html.p(style=[TaskCardSummaryStyle], [@html.text(summary)])
  }
  @html.div(
    style=@internal.sumi_styles(
      [
        @internal.SumiBoxSizing,
        @internal.SumiFontSans,
        @internal.SumiTextRendering,
        TaskCardStyle,
        if on_click is Some(_) {
          "cursor:pointer"
        } else {
          ""
        },
      ],
      style,
    ),
    id?,
    class?,
    on_click?,
    attrs=element_attrs,
    [
      @html.div(style=["display:flex;align-items:center;gap:4px;width:100%"], [
        @html.p(style=[TaskCardTitleStyle], [@html.text(title)]),
        status_view,
      ]),
      body,
    ],
  )
}

///|
/// The scrollable task-card feed ("bubble list"): 8px padding and gaps, a
/// bottom fade mask (`fade` px, default 44), and the blue-tinted thin
/// scrollbar. Children are usually `task_card` bubbles.
///
/// ```moonbit nocheck
/// task_list(height=400, children=cards)
/// ```
pub fn task_list(
  children~ : Array[@html.Html],
  height? : Int = 400,
  fade? : Int = 44,
  aria_label? : String,
  id? : String,
  class? : String,
  attrs? : @html.Attrs,
  style? : Array[String] = [],
) -> @html.Html {
  let element_attrs = @internal.sumi_attrs(attrs).data_set("slot", "task-list")
  if aria_label is Some(label_text) {
    ignore(element_attrs.aria_label(label_text))
  }
  @html.div(
    style=@internal.sumi_styles(
      [
        @internal.SumiBoxSizing,
        @internal.SumiFontSans,
        @internal.SumiTextRendering,
        "display:flex;flex-direction:column;gap:8px;width:100%;height:\{height}px;padding:8px;overflow-x:clip;overflow-y:auto;--sumi-scrollbar:rgba(204,221,255,0.12)",
        if fade > 0 {
          "-webkit-mask-image:linear-gradient(to bottom,#000 0px,#000 calc(100% - \{fade}px),transparent 100%);mask-image:linear-gradient(to bottom,#000 0px,#000 calc(100% - \{fade}px),transparent 100%)"
        } else {
          ""
        },
      ],
      style,
    ),
    id?,
    class?,
    attrs=element_attrs,
    children,
  )
}