'use client'

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

import { useCSSPropsPolyfill, useGDS } from '../hooks/index.ts'
import { cn, getCSSPropsAttributes } from '../utils/index.ts'
import { MaybeButtonOrLink, type MaybeButtonOrLinkProps } from './base/MaybeButtonOrLink.tsx'
import { ClusterMeta } from './Cluster.meta.ts'

export declare namespace ClusterProps {
  interface ButtonProps
    extends GDSComponentProps<typeof ClusterMeta>, MaybeButtonOrLinkProps.ButtonProps {}
  interface LinkProps
    extends GDSComponentProps<typeof ClusterMeta>, MaybeButtonOrLinkProps.LinkProps {}
  interface OtherElementProps
    extends GDSComponentProps<typeof ClusterMeta>, MaybeButtonOrLinkProps.OtherElementProps {}
}

export type ClusterProps =
  | ClusterProps.ButtonProps
  | ClusterProps.LinkProps
  | ClusterProps.OtherElementProps

export function Cluster({
  ref: passedRef,
  shape,
  size,
  className,
  style,
  children,
  ...props
}: ClusterProps) {
  useGDS()

  const [cssPropsPolyfillPassedRef, cssPropsPolyfillAttributes] = useCSSPropsPolyfill(
    ClusterMeta,
    {
      shape,
      size,
    },
    { ref: passedRef },
  )

  return (
    <MaybeButtonOrLink
      ref={cssPropsPolyfillPassedRef}
      className={cn(
        `group/cluster gds-cluster root-block u:max-w-full u:shrink-0 u:outline-0
        u:not-clickable:cursor-default
        i:size-max`,
        className,
      )}
      {...getCSSPropsAttributes(ClusterMeta, { shape, size }, style)}
      {...cssPropsPolyfillAttributes}
      {...props}
    >
      <span
        className={`
          nested/cluster-paint pointer-events-none flex h-(--height) min-w-(--height) items-center justify-center bg-default
          font-medium text-default transition
          group-clickable-hover/cluster:bg-elevated
          group-clickable-focus-visible/cluster:outline
          group-clickable-active/cluster:bg-muted
          group-clickable-active/cluster:transition-none
          @prop-size-xsmall/cluster:px-1
          @prop-size-xsmall/cluster:text-10
          @prop-size-xsmall/cluster:[--height:--spacing(4)]
          @prop-size-small/cluster:px-1
          @prop-size-small/cluster:text-12
          @prop-size-small/cluster:[--height:--spacing(5)]
          @prop-size-medium/cluster:px-1.5
          @prop-size-medium/cluster:text-16
          @prop-size-medium/cluster:[--height:--spacing(6)]
          @prop-size-large/cluster:px-2
          @prop-size-large/cluster:text-20
          @prop-size-large/cluster:[--height:--spacing(8)]
          @prop-size-xlarge/cluster:px-2.5
          @prop-size-xlarge/cluster:text-24
          @prop-size-xlarge/cluster:[--height:--spacing(12)]
          @prop-shape-circle/cluster:rounded-full
          @prop-shape-rounded/cluster:rounded-4
          @prop-shape-rounded/cluster:@prop-size-xsmall/cluster:rounded-2
          @prop-shape-rounded/cluster:@prop-size-xlarge/cluster:rounded-8
        `}
      >
        <span className="truncate">{children}</span>
      </span>
    </MaybeButtonOrLink>
  )
}
