import * as React from "react"

import { Button } from "@/components/ui/button"
import { Spinner } from "@/components/ui/spinner"
import { cn } from "@/lib/utils"

type LoadingPosition = "start" | "end" | "center"

type LoadingButtonProps = React.ComponentProps<typeof Button> & {
  loading?: boolean
  loadingPosition?: LoadingPosition
  loadingIndicator?: React.ReactNode
  startIcon?: React.ReactNode
  endIcon?: React.ReactNode
}

function LoadingButton({
  loading = false,
  loadingPosition = "center",
  loadingIndicator,
  startIcon,
  endIcon,
  disabled,
  className,
  children,
  ...props
}: LoadingButtonProps) {
  const indicator = loadingIndicator ?? <Spinner className="size-4" />

  const showStart = loading && loadingPosition === "start"
  const showEnd = loading && loadingPosition === "end"
  const showCenter = loading && loadingPosition === "center"

  return (
    <Button
      className={cn(showCenter && "text-transparent", className)}
      disabled={disabled || loading}
      {...props}
    >
      {showCenter ? (
        <span className="pointer-events-none absolute inset-0 grid place-items-center">
          {indicator}
        </span>
      ) : null}

      {showStart ? (
        <span className="pointer-events-none">{indicator}</span>
      ) : startIcon ? (
        <span className="pointer-events-none">{startIcon}</span>
      ) : null}

      <span className={cn(showCenter && "pointer-events-none")}>{children}</span>

      {showEnd ? (
        <span className="pointer-events-none">{indicator}</span>
      ) : endIcon ? (
        <span className="pointer-events-none">{endIcon}</span>
      ) : null}
    </Button>
  )
}

export { LoadingButton }
export type { LoadingButtonProps, LoadingPosition }

