'use client';

import type * as React from 'react';
import { hasReactNode } from '@vkontakte/vkjs';
import { useMergeProps } from '../../hooks/useMergeProps';
import { warnOnce } from '../../lib/warnOnce';
import { withLabelClickWrapper } from '../../lib/withLabelClickWrapper';
import type { HasDataAttribute, HasRootRef } from '../../types';
import { SelectionControl } from '../SelectionControl/SelectionControl';
import { SelectionControlLabel } from '../SelectionControl/SelectionControlLabel/SelectionControlLabel';
import type { TappableOmitProps } from '../Tappable/Tappable';
import { CheckboxInput, type CheckboxInputProps } from './CheckboxInput/CheckboxInput';
import { CheckboxSimple } from './CheckboxSimple/CheckboxSimple';

const warn = warnOnce('Checkbox');

export interface CheckboxProps
  extends Pick<
      CheckboxInputProps,
      | 'indeterminate'
      | 'defaultIndeterminate'
      | 'IconOnCompact'
      | 'IconOnRegular'
      | 'IconOffCompact'
      | 'IconOffRegular'
      | 'IconIndeterminate'
      | 'getRef'
    >,
    Pick<
      React.ComponentProps<'input'>,
      | 'checked'
      | 'defaultChecked'
      | 'disabled'
      | 'readOnly'
      | 'required'
      | 'autoFocus'
      | 'name'
      | 'value'
      | 'form'
      | 'onChange'
      | 'onFocus'
      | 'onBlur'
    >,
    Omit<
      React.LabelHTMLAttributes<HTMLLabelElement>,
      'onChange' | 'onFocus' | 'onBlur' | 'slotProps'
    >,
    HasRootRef<HTMLLabelElement>,
    Pick<
      TappableOmitProps,
      'hoverMode' | 'activeMode' | 'hasHover' | 'hasActive' | 'focusVisibleMode'
    > {
  /**
   * Свойства, которые можно прокинуть внутрь компонента:
   * - `root`: свойства для прокидывания в корень компонента;
   * - `input`: свойства для прокидывания в скрытый `input`.
   */
  slotProps?:
    | {
        root?:
          | ((Omit<React.LabelHTMLAttributes<HTMLLabelElement>, 'children'> &
              HasRootRef<HTMLLabelElement> &
              HasDataAttribute) &
              HasDataAttribute)
          | undefined;
        input?:
          | (React.ComponentProps<'input'> & HasRootRef<HTMLInputElement> & HasDataAttribute)
          | undefined;
      }
    | undefined;
  /**
   * Подпись под основным текстом.
   */
  description?: React.ReactNode | undefined;
  /**
   * Контент, идущий за основным текстом.
   */
  titleAfter?: React.ReactNode | undefined;
  /**
   * Отключает отступы у чекбокса. При использовании этого свойства, значение по умолчанию для свойств `hoverMode` и `activeMode` становится `"opacity"`.
   */
  noPadding?: boolean | undefined;
}

const CheckboxComponent = ({
  // CheckboxProps
  getRef,
  description,
  titleAfter,
  noPadding,
  children,

  // CheckboxInputProps
  indeterminate,
  defaultIndeterminate,
  IconOnCompact,
  IconOnRegular,
  IconOffCompact,
  IconOffRegular,
  IconIndeterminate,

  // Tappable props
  hoverMode,
  activeMode,
  hasHover,
  hasActive,
  focusVisibleMode,

  // Input props
  checked,
  defaultChecked,
  disabled,
  readOnly,
  required,
  autoFocus,
  id,
  name,
  value,
  form,
  onChange,
  onFocus,
  onBlur,

  slotProps,
  ...restProps
}: CheckboxProps): React.ReactNode => {
  const { onClick, ...rootRest } = useMergeProps(restProps, slotProps?.root);

  const inputRest = useMergeProps(
    {
      getRootRef: getRef,
      checked,
      defaultChecked,
      disabled,
      readOnly,
      required,
      autoFocus,
      id,
      name,
      value,
      form,
      onChange,
      onFocus,
      onBlur,
    },
    slotProps?.input,
  );

  return (
    <SelectionControl
      disabled={inputRest.disabled}
      hoverMode={hoverMode}
      activeMode={activeMode}
      hasHover={hasHover}
      hasActive={hasActive}
      focusVisibleMode={focusVisibleMode}
      noPadding={noPadding}
      onClick={withLabelClickWrapper(onClick)}
      {...rootRest}
    >
      <CheckboxInput
        indeterminate={indeterminate}
        defaultIndeterminate={defaultIndeterminate}
        IconIndeterminate={IconIndeterminate}
        IconOnCompact={IconOnCompact}
        IconOnRegular={IconOnRegular}
        IconOffCompact={IconOffCompact}
        IconOffRegular={IconOffRegular}
        slotProps={{ input: inputRest }}
      />
      <SelectionControlLabel titleAfter={titleAfter} description={description}>
        {children}
      </SelectionControlLabel>
    </SelectionControl>
  );
};

/**
 * @see https://vkui.io/components/checkbox
 */
export const Checkbox = (props: CheckboxProps): React.ReactNode => {
  if (process.env.NODE_ENV === 'development' && props.getRef) {
    warn('Свойство `getRef` устаревшее, используйте `slotProps={ input: { getRootRef: ... } }`');
  }

  const simple = !(hasReactNode(props.children) || hasReactNode(props.description));
  if (simple) {
    return <CheckboxSimple {...props} />;
  }

  return <CheckboxComponent {...props} />;
};

Checkbox.Input = CheckboxInput;
