'use client'

import type { ComponentProps, ReactNode } from 'react'

import type { GDSComponentProps } from '@graphprotocol/gds-css'
import { CheckIcon, MinusIcon } from '@graphprotocol/gds-react/icons'

import { useControlled, useGDS } from '../hooks/index.ts'
import { cn, splitProps } from '../utils/index.ts'
import { Checkable, type CheckableLabelProps } from './base/Checkable.tsx'
import type { CheckboxMeta } from './Checkbox.meta.ts'

export interface CheckboxProps
  extends
    Omit<ComponentProps<'input'>, 'checked' | 'defaultChecked' | 'onChange' | 'size' | 'type'>,
    GDSComponentProps<typeof CheckboxMeta> {
  name?: string | undefined
  value?: string | undefined
  checked?: boolean | 'indeterminate' | undefined
  defaultChecked?: boolean | 'indeterminate' | undefined
  onChange?: ((checked: boolean) => void) | undefined
  /** @default false */
  disabled?: boolean | undefined
  children?: ReactNode | undefined
}

export function CheckboxRoot({
  size,
  children: label,
  'aria-label': ariaLabel,
  'aria-labelledby': ariaLabelledBy,
  name,
  value,
  checked: controlledChecked,
  defaultChecked,
  onChange,
  disabled = false,
  className,
  ...props
}: CheckboxProps) {
  useGDS()

  const { rootProps, nestedProps } = splitProps(props)

  const [checked, setChecked] = useControlled(controlledChecked, defaultChecked ?? false, onChange)

  return (
    <Checkable
      size={size}
      label={label}
      aria-label={ariaLabel}
      aria-labelledby={ariaLabelledBy}
      name={name}
      value={value}
      checked={checked}
      disabled={disabled}
      className={cn('gds-checkbox', className)}
      {...rootProps}
      renderInput={(renderProps, { inputProps }) => (
        <Checkable.Box
          {...renderProps}
          className={cn(
            renderProps.className,
            `text-form-checked
            **:icon:transition-opacity
            @state-disabled/checkable:**:icon:opacity-disabled
            @prop-size-small/checkable:rounded-4
            @prop-size-small/checkable:**:icon:prop-size-2.5
            @prop-size-medium/checkable:rounded-4
            @prop-size-medium/checkable:**:icon:prop-size-3
            @prop-size-large/checkable:rounded-6
            @prop-size-large/checkable:**:icon:prop-size-3.5`,
          )}
        >
          <input
            {...inputProps}
            type="checkbox"
            onChange={(event) => setChecked(event.target.checked)}
            {...nestedProps}
          />
          <CheckIcon alt="" className="@state-not-checked/checkable:hidden" />
          <MinusIcon alt="" className="@state-not-indeterminate/checkable:hidden" />
        </Checkable.Box>
      )}
    />
  )
}
CheckboxRoot.displayName = 'Checkbox'

export interface CheckboxAreaProps extends CheckableLabelProps {}

export function CheckboxArea(props: CheckboxAreaProps) {
  return <Checkable.Label {...props} />
}
CheckboxArea.displayName = 'Checkbox.Area'
