import { cn } from "#lib/utils.ts";
import { sidebar as styles } from "./classes.ts";

export interface Input extends Marko.Input<"div"> {
  /** Expanded/collapsed state, provided by the provider's @sidebar body. Default: true. */
  open?: boolean;
  side?: "left" | "right";
  variant?: "sidebar" | "floating" | "inset";
  collapsible?: "offcanvas" | "icon" | "none";
  content?: Marko.Body;
}

<const/{
  open,
  side = "left",
  variant = "sidebar",
  collapsible = "offcanvas",
  class: className,
  content,
  ...rest
}=input/>

<const/state=((open ?? true) ? "expanded" : "collapsed")/>
<const/isFloatingOrInset=(variant === "floating" || variant === "inset")/>

<if=(collapsible === "none")>
  <div
    ...rest
    data-slot="sidebar"
    class=cn(styles.rootFixed, className)
  >
    <${content}/>
  </div>
</if>
<else>
  <div
    class=styles.wrapper
    data-state=state
    data-collapsible=(state === "collapsed" ? collapsible : "")
    data-variant=variant
    data-side=side
    data-slot="sidebar"
  >
    // This is what handles the sidebar gap on desktop
    <div
      data-slot="sidebar-gap"
      class=cn(
        styles.gap,
        isFloatingOrInset ? styles.gapFloatingIcon : styles.gapDefaultIcon,
      )
    />
    <div
      ...rest
      data-slot="sidebar-container"
      data-side=side
      class=cn(
        styles.container,
        // Adjust the padding for floating and inset variants.
        isFloatingOrInset ? styles.containerFloating : styles.containerDefault,
        className,
      )
    >
      <div
        data-sidebar="sidebar"
        data-slot="sidebar-inner"
        class=styles.inner
      >
        <${content}/>
      </div>
    </div>
  </div>
</else>
