'use client'

import type { ComponentProps } from 'react'

import type { GDSComponentProps } from '@graphprotocol/gds-css'

import { useCSSPropsPolyfill, useGDS } from '../hooks/index.ts'
import { cn, getCSSPropsAttributes } from '../utils/index.ts'
import { ButtonGroupMeta } from './ButtonGroup.meta.ts'

export interface ButtonGroupProps
  extends ComponentProps<'span'>, GDSComponentProps<typeof ButtonGroupMeta> {}

export function ButtonGroup({
  ref: passedRef,
  variant,
  size,
  orientation,
  fullWidth,
  className,
  style,
  children,
  ...props
}: ButtonGroupProps) {
  useGDS()

  const [cssPropsPolyfillPassedRef, cssPropsPolyfillAttributes, cssProps] = useCSSPropsPolyfill(
    ButtonGroupMeta,
    { variant, size, orientation, fullWidth },
    { ref: passedRef, returnPropValues: { fullWidth } },
  )

  return (
    <span
      ref={cssPropsPolyfillPassedRef}
      data-full-width={cssProps.fullWidth || undefined}
      className={cn(
        `gds-button-group root-block u:w-max u:max-w-full
        u:data-full-width:w-full
        i:h-max
        ${/* Pass props to nested buttons and button groups (and segmented controls if the current size is supported) */ ''}
        u:**:segmented-control:@prop-size-small/button-group:prop-size-small
        u:**:segmented-control:@prop-size-medium/button-group:prop-size-medium
        u:**:button-group:@prop-full-width-false/button-group:default-full-width-false
        u:**:button-group:@prop-full-width-true/button-group:default-full-width-true
        u:**:button-or-group:@prop-variant-inverse/button-group:default-variant-inverse
        u:**:button-or-group:@prop-variant-primary/button-group:default-variant-primary
        u:**:button-or-group:@prop-variant-secondary/button-group:default-variant-secondary
        u:**:button-or-group:@prop-variant-tertiary/button-group:default-variant-tertiary
        u:**:button-or-group:@prop-variant-danger/button-group:default-variant-danger
        u:**:button-or-group:@prop-variant-naked/button-group:default-variant-naked
        u:**:button-or-group:@prop-size-xsmall/button-group:prop-size-xsmall
        u:**:button-or-group:@prop-size-small/button-group:prop-size-small
        u:**:button-or-group:@prop-size-medium/button-group:prop-size-medium
        u:**:button-or-group:@prop-size-large/button-group:prop-size-large
        ${/* Ensure a button group nested in a horizontal button group grows like a button does */ ''}
        u:@prop-orientation-horizontal/button-group:grow
        u:@prop-orientation-horizontal/button-group:@prop-full-width-true/button-group:basis-0`,
        className,
      )}
      {...getCSSPropsAttributes(ButtonGroupMeta, { variant, size, orientation, fullWidth }, style)}
      {...cssPropsPolyfillAttributes}
      {...props}
    >
      <span
        /**
         * `not-in-button-group-[[data-gds-prop-polyfill-orientation=gds-horizontal]]` is used to
         * work around the fact that the CSS props polyfill doesn't support nested components. It's
         * not a perfect solution, because while it prevents classes with the
         * `@prop-orientation-vertical` variant from incorrectly affecting horizontal button groups
         * nested inside a vertical one, it also prevents them from correctly styling a vertical
         * button group that would be nested inside a horizontal one. Thankfully, that doesn't
         * really make sense, but the other way around does. So how do we style horizontal button
         * groups nested in vertical ones? Simply by not adding a similar `not-in-[...]` variant to
         * classes with the `@prop-orientation-horizontal` variant. As a result, those classes will
         * affect any button group inside a horizontal one, but that should be safe because as
         * mentioned, vertical in horizontal doesn't make sense.
         */
        className={`
          flex items-center gap-(--gds-button-group-gap)
          @prop-orientation-vertical/button-group:not-in-button-group-[[data-gds-prop-polyfill-orientation=gds-horizontal]]:flex-col
          i:*:@prop-orientation-vertical/button-group:not-in-button-group-[[data-gds-prop-polyfill-orientation=gds-horizontal]]:w-full
        `}
      >
        {children}
      </span>
    </span>
  )
}
