"use client"

import { Slot } from "@radix-ui/react-slot"
import { Children, type ReactNode } from "react"
import { Button as ButtonRAC } from "react-aria-components"

import { buttonVariants } from "./variants"

import type { ButtonProps } from "./button"

// We wrap all text nodes to avoid having consumers manually wrap text nodes in spans.
// This is so that we can better support underline on buttons as Material Symbols
// are implemented as a font and therefore gets underline. Icons inside buttons
// should not get an underline.
function wrapTextNodes(children: ReactNode): ReactNode {
  return Children.map(children, (child) => {
    if (typeof child === "string") {
      return <span>{child}</span>
    }
    return child
  })
}

export default function Button(props: ButtonProps) {
  const {
    children,
    className,
    clean,
    intent,
    size,
    theme,
    fullWidth,
    wrapping,
    variant,
    ...restProps
  } = props

  const classNames = buttonVariants({
    className,
    clean,
    intent,
    size,
    theme,
    fullWidth,
    wrapping,
    variant,
  })

  const wrappedChildren =
    typeof children === "function" ? children : wrapTextNodes(children)

  if (restProps.asChild) {
    const { asChild, ...slotProps } = restProps
    return (
      <Slot className={classNames} {...slotProps}>
        {/* @ts-expect-error: Incorrect types for Slot */}
        {wrappedChildren}
      </Slot>
    )
  }

  const { asChild, onClick, disabled, ...racProps } = restProps
  return (
    <ButtonRAC
      className={classNames}
      isDisabled={disabled}
      onPress={onClick}
      {...racProps}
    >
      {wrappedChildren}
    </ButtonRAC>
  )
}
