'use client';

import * as React from 'react';
import { useStableCallback } from '@base-ui/utils/useStableCallback';
import { useBaseUiId } from "../utils/useBaseUiId.js";
const EMPTY = [];
export function useCheckboxGroupParent(params) {
  const {
    allValues = EMPTY,
    value = EMPTY,
    onValueChange: onValueChangeProp
  } = params;
  const uncontrolledStateRef = React.useRef(value);
  const disabledStatesRef = React.useRef(new Map());
  const [status, setStatus] = React.useState('mixed');
  const id = useBaseUiId();
  const checked = value.length === allValues.length;
  const indeterminate = value.length !== allValues.length && value.length > 0;
  const onValueChange = useStableCallback(onValueChangeProp);
  const getParentProps = React.useCallback(() => ({
    id,
    indeterminate,
    checked,
    // TODO: custom `id` on child checkboxes breaks this
    // https://github.com/mui/base-ui/issues/2691
    'aria-controls': allValues.map(v => `${id}-${v}`).join(' '),
    onCheckedChange(_, eventDetails) {
      const uncontrolledState = uncontrolledStateRef.current;

      // None except the disabled ones that are checked, which can't be changed.
      const none = allValues.filter(v => disabledStatesRef.current.get(v) && uncontrolledState.includes(v));
      // "All" that are valid:
      // - any that aren't disabled
      // - disabled ones that are checked
      const all = allValues.filter(v => !disabledStatesRef.current.get(v) || disabledStatesRef.current.get(v) && uncontrolledState.includes(v));
      const allOnOrOff = uncontrolledState.length === all.length || uncontrolledState.length === 0;
      if (allOnOrOff) {
        if (value.length === all.length) {
          onValueChange(none, eventDetails);
        } else {
          onValueChange(all, eventDetails);
        }
        return;
      }
      if (status === 'mixed') {
        onValueChange(all, eventDetails);
        setStatus('on');
      } else if (status === 'on') {
        onValueChange(none, eventDetails);
        setStatus('off');
      } else if (status === 'off') {
        onValueChange(uncontrolledState, eventDetails);
        setStatus('mixed');
      }
    }
  }), [allValues, checked, id, indeterminate, onValueChange, status, value.length]);
  const getChildProps = React.useCallback(childValue => ({
    checked: value.includes(childValue),
    onCheckedChange(nextChecked, eventDetails) {
      const newValue = value.slice();
      if (nextChecked) {
        newValue.push(childValue);
      } else {
        newValue.splice(newValue.indexOf(childValue), 1);
      }
      uncontrolledStateRef.current = newValue;
      onValueChange(newValue, eventDetails);
      setStatus('mixed');
    }
  }), [onValueChange, value]);
  return React.useMemo(() => ({
    id,
    indeterminate,
    getParentProps,
    getChildProps,
    disabledStatesRef
  }), [id, indeterminate, getParentProps, getChildProps]);
}