'use client'

import type { ComponentProps, ReactNode } from 'react'

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

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

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

export function SwitchRoot({
  size,
  children: label,
  'aria-label': ariaLabel,
  'aria-labelledby': ariaLabelledBy,
  name,
  value,
  checked: controlledChecked,
  defaultChecked,
  onChange,
  disabled = false,
  className,
  ...props
}: SwitchProps) {
  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-switch', className)}
      {...rootProps}
      renderInput={(renderProps, { inputProps }) => (
        <Checkable.Box
          {...renderProps}
          className={cn(
            renderProps.className,
            `rounded-full
            @prop-size-small/checkable:w-7
            @prop-size-medium/checkable:w-9
            @prop-size-large/checkable:w-11`,
          )}
        >
          <span
            className={`
              grid size-full grid-cols-[0fr_min-content] transition-[grid-template-columns]
              @state-checked/checkable:grid-cols-[1fr_min-content]
            `}
          >
            <input
              {...inputProps}
              type="checkbox"
              role="switch"
              onChange={(event) => setChecked(event.target.checked)}
              {...nestedProps}
            />
            <span
              className={`
                col-2 aspect-square h-full rounded-full bg-form-handle-default
                transition-[background-color,scale,aspect-ratio]
                @state-checked/checkable:bg-form-handle-checked
                @state-active/checkable:aspect-3/2
                @state-active/checkable:scale-80
                @state-disabled/checkable:bg-form-handle-disabled
                @state-checked/checkable:@state-disabled/checkable:bg-form-handle-checked-disabled
              `}
            />
          </span>
        </Checkable.Box>
      )}
    />
  )
}
SwitchRoot.displayName = 'Switch'

export interface SwitchAreaProps extends CheckableLabelProps {}

export function SwitchArea(props: SwitchAreaProps) {
  return <Checkable.Label {...props} />
}
SwitchArea.displayName = 'Switch.Area'
