///|
const PaginationRootStyle : String = "display:flex;width:100%;min-width:0;justify-content:center;margin-inline:auto"

///|
const PaginationContentStyle : String = "display:flex;max-width:100%;flex-wrap:nowrap;align-items:center;justify-content:center;gap:0.25rem;margin:0;padding:0;list-style:none"

///|
const PaginationItemStyle : String = "display:block"

///|
const PaginationLinkResetStyle : String = "text-decoration:none"

///|
const PaginationPreviousStyle : String = "padding-inline-start:0.5rem"

///|
const PaginationNextStyle : String = "padding-inline-end:0.5rem"

///|
const PaginationChevronBoxStyle : String = "display:inline-flex;width:1rem;height:1rem;flex-shrink:0;align-items:center;justify-content:center"

///|
const PaginationChevronStyle : String = "display:block;width:0.4375rem;height:0.4375rem;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform-origin:center"

///|
const PaginationChevronPreviousStyle : String = "transform:rotate(135deg)"

///|
const PaginationChevronNextStyle : String = "transform:rotate(-45deg)"

///|
const PaginationEllipsisStyle : String = "display:inline-flex;width:2.25rem;height:2.25rem;align-items:center;justify-content:center;color:var(--rui-muted-foreground,oklch(0.556 0 0))"

///|
const PaginationDotsStyle : String = "display:block;width:0.1875rem;height:0.1875rem;border-radius:9999px;background:currentColor;box-shadow:-0.3125rem 0 currentColor,0.3125rem 0 currentColor"

///|
const PaginationScreenReaderOnlyStyle : String = "position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0"

///|
fn pagination_part_attrs(attrs : @html.Attrs?, slot : String) -> @html.Attrs {
  ui_attrs(attrs).data_set("slot", slot)
}

///|
fn pagination_state(is_active : Bool) -> String {
  if is_active {
    "active"
  } else {
    "inactive"
  }
}

///|
#cfg(target="js")
fn pagination_bind_disabled(attrs : @html.Attrs, disabled : Bool) -> Unit {
  if disabled {
    ignore(
      attrs.on_click(event => {
        event.prevent_default()
        @cmd.none
      }),
    )
  }
}

///|
#cfg(not(target="js"))
fn pagination_bind_disabled(attrs : @html.Attrs, disabled : Bool) -> Unit {
  ignore((attrs, disabled))
}

///|
/// Render the semantic navigation root for a pagination control.
pub fn[C : @html.IsChildren] pagination(
  aria_label? : String = "pagination",
  id? : String,
  class? : String,
  title? : String,
  attrs? : @html.Attrs,
  style? : Array[String] = [],
  children : C,
) -> @html.Html {
  let element_attrs = pagination_part_attrs(attrs, "pagination")
    .role("navigation")
    .aria_label(aria_label)
  @html.nav(
    style=ui_styles(
      [UiBoxSizing, UiFontSans, UiTextRendering, PaginationRootStyle],
      style,
    ),
    id?,
    class?,
    title?,
    attrs=element_attrs,
    children,
  )
}

///|
/// Render the list that contains pagination items.
pub fn[C : @html.IsChildren] pagination_content(
  id? : String,
  class? : String,
  title? : String,
  attrs? : @html.Attrs,
  style? : Array[String] = [],
  children : C,
) -> @html.Html {
  @html.ul(
    style=ui_styles([UiBoxSizing, PaginationContentStyle], style),
    id?,
    class?,
    title?,
    attrs=pagination_part_attrs(attrs, "pagination-content"),
    children,
  )
}

///|
/// Render one semantic list item in a pagination control.
pub fn[C : @html.IsChildren] pagination_item(
  id? : String,
  class? : String,
  title? : String,
  attrs? : @html.Attrs,
  style? : Array[String] = [],
  children : C,
) -> @html.Html {
  @html.li(
    style=ui_styles([UiBoxSizing, PaginationItemStyle], style),
    id?,
    class?,
    title?,
    attrs=pagination_part_attrs(attrs, "pagination-item"),
    children,
  )
}

///|
/// Render a native page anchor using the Vega button recipe.
///
/// Active links expose both `aria-current="page"` and stable data state.
pub fn[C : @html.IsChildren] pagination_link(
  href~ : String,
  is_active? : Bool = false,
  disabled? : Bool = false,
  size? : ButtonSize = Icon,
  aria_label? : String,
  target? : @html.Target = Self,
  rel? : String,
  download? : String,
  escape? : Bool = false,
  id? : String,
  class? : String,
  title? : String,
  attrs? : @html.Attrs,
  style? : Array[String] = [],
  children : C,
) -> @html.Html {
  let variant : ButtonVariant = if is_active { Outline } else { Ghost }
  let element_attrs = pagination_part_attrs(attrs, "pagination-link")
    .data_set("active", ui_bool(is_active))
    .data_set("state", pagination_state(is_active))
    .data_set("variant", button_variant_value(variant))
    .data_set("size", button_size_value(size))
  if is_active {
    ignore(element_attrs.aria_current("page"))
  }
  if disabled {
    ignore(
      element_attrs.aria_disabled("true").data_set("disabled", "").tabindex(-1),
    )
  }
  pagination_bind_disabled(element_attrs, disabled)
  if aria_label is Some(aria_label) {
    ignore(element_attrs.aria_label(aria_label))
  }
  @html.a(
    style=ui_styles(
      [
        UiBoxSizing,
        UiFontSans,
        UiTextRendering,
        UiTransition,
        ButtonBaseStyle,
        PaginationLinkResetStyle,
        button_variant_style(variant),
        button_size_style(size),
        ui_disabled_style(disabled),
      ],
      style,
    ),
    id?,
    class?,
    title?,
    href~,
    target~,
    rel?,
    download?,
    attrs=element_attrs,
    children,
    escape~,
  )
}

///|
/// Render a previous-page anchor with a dependency-free CSS chevron.
pub fn pagination_previous(
  href~ : String,
  disabled? : Bool = false,
  text? : String = "Previous",
  aria_label? : String = "Go to previous page",
  target? : @html.Target = Self,
  rel? : String,
  download? : String,
  escape? : Bool = false,
  id? : String,
  class? : String,
  title? : String,
  attrs? : @html.Attrs,
  style? : Array[String] = [],
) -> @html.Html {
  let element_attrs = ui_attrs(attrs).data_set("direction", "previous")
  pagination_link(
    href~,
    disabled~,
    size=Default,
    aria_label~,
    target~,
    rel?,
    download?,
    escape~,
    id?,
    class?,
    title?,
    attrs=element_attrs,
    style=ui_styles([PaginationPreviousStyle], style),
    [
      @html.span(
        style=[UiBoxSizing, PaginationChevronBoxStyle],
        attrs=@html.Attrs::build()
          .aria_hidden("true")
          .data_set("icon", "inline-start"),
        @html.span(
          style=[
            UiBoxSizing,
            PaginationChevronStyle,
            PaginationChevronPreviousStyle,
          ],
          @html.nothing,
        ),
      ),
      @html.span(text),
    ],
  )
}

///|
/// Render a next-page anchor with a dependency-free CSS chevron.
pub fn pagination_next(
  href~ : String,
  disabled? : Bool = false,
  text? : String = "Next",
  aria_label? : String = "Go to next page",
  target? : @html.Target = Self,
  rel? : String,
  download? : String,
  escape? : Bool = false,
  id? : String,
  class? : String,
  title? : String,
  attrs? : @html.Attrs,
  style? : Array[String] = [],
) -> @html.Html {
  let element_attrs = ui_attrs(attrs).data_set("direction", "next")
  pagination_link(
    href~,
    disabled~,
    size=Default,
    aria_label~,
    target~,
    rel?,
    download?,
    escape~,
    id?,
    class?,
    title?,
    attrs=element_attrs,
    style=ui_styles([PaginationNextStyle], style),
    [
      @html.span(text),
      @html.span(
        style=[UiBoxSizing, PaginationChevronBoxStyle],
        attrs=@html.Attrs::build()
          .aria_hidden("true")
          .data_set("icon", "inline-end"),
        @html.span(
          style=[
            UiBoxSizing,
            PaginationChevronStyle,
            PaginationChevronNextStyle,
          ],
          @html.nothing,
        ),
      ),
    ],
  )
}

///|
/// Render the collapsed-range marker used by long pagination controls.
pub fn pagination_ellipsis(
  label? : String = "More pages",
  id? : String,
  class? : String,
  title? : String,
  attrs? : @html.Attrs,
  style? : Array[String] = [],
) -> @html.Html {
  let element_attrs = pagination_part_attrs(attrs, "pagination-ellipsis")
    .role("presentation")
    .aria_hidden("true")
  @html.span(
    style=ui_styles([UiBoxSizing, PaginationEllipsisStyle], style),
    id?,
    class?,
    title?,
    attrs=element_attrs,
    [
      @html.span(
        style=[UiBoxSizing, PaginationDotsStyle],
        attrs=@html.Attrs::build().data_set("icon", "ellipsis"),
        @html.nothing,
      ),
      @html.span(style=[PaginationScreenReaderOnlyStyle], label),
    ],
  )
}