import type { ChangeEvent, ReactNode, RefAttributes } from "react";
import type { DOMProps } from "../../types/dom";
import type { Validation } from "../../types";

export type CheckboxElementType = HTMLInputElement;

export interface CheckboxProps
  extends DOMProps, Validation, RefAttributes<CheckboxElementType> {
  className?: string;
  // The content to display as the label.
  label?: ReactNode;
  errorMessage?: string;
  /** The name of the input */
  name?: string;
  /** The current value (controlled). */
  value?: string;
  // Whether the input is disabled.
  isDisabled?: boolean;
  onChange?: (
    event: ChangeEvent<CheckboxElementType>,
    isLastItem?: boolean,
  ) => void;
  // The default value (uncontrolled).
  defaultSelected?: boolean;
  // Whether the input can be selected but not changed by the user.
  isReadOnly?: boolean;
  // Whether user input is required on the input before form submission.
  isRequired?: boolean;
  // Identifies the element that provides an error message for the object.
  "aria-errormessage"?: string;
  /**
   * Identifies the element (or elements) that describes the object.
   */
  "aria-describedby"?: string;
  /**
   * Whether the checkbox is the last item of a group.
   */
  isLastItem?: boolean;
  /**
   * **Internal:** Do not use
   */
  groupDisabled?: boolean;
  /**
   * Whether the checkbox is selected.
   */
  selected?: boolean;
}

export type CheckboxGroupElementType = HTMLDivElement;
interface CheckboxGroupPropsInternal
  extends DOMProps, Validation, RefAttributes<CheckboxGroupElementType> {
  children: ReactNode;
  className?: string;
  orientation?: "horizontal" | "vertical";
  // Defines number of items to be displayed on a single row when used with orientation="horizontal". Defaults to number of items in the group.
  itemsPerRow?: number;
  errorMessage?: string;
  onChange?: (values: string[]) => void;
  // Defines a string value that labels the current element.
  // "aria-label"?: string;
  // Identifies the element (or elements) that labels the current element.
  "aria-labelledby"?: string;
  // Identifies the element that provides an error message for the object.
  // "aria-errormessage"?: string;
  // Identifies the element (or elements) that describes the object.
  "aria-describedby"?: string;
  // Whether user input is required on the input before form submission.
  isRequired?: boolean;
  // Whether the input is disabled.
  isDisabled?: boolean;
  // Whether the input can be selected but not changed by the user.
  isReadOnly?: boolean;
  // The default value (uncontrolled).
  defaultValue?: string[];
  // The content to display as the label.
  label?: ReactNode;
  /**
   * The value of the radio button, used when submitting an HTML form.
   * See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio#Value).
   */
  value?: string;
  /**
   * This determines if the last item in the group should disable the other items when selected.
   */
  lastItemDisables?: boolean;
}

interface HorizontalCheckboxGroupProps extends CheckboxGroupPropsInternal {
  orientation?: "horizontal";
  itemsPerRow: number;
}

interface VerticalCheckboxGroupProps extends CheckboxGroupPropsInternal {
  orientation?: "vertical";
  itemsPerRow?: never;
}

export type CheckboxGroupProps =
  | HorizontalCheckboxGroupProps
  | VerticalCheckboxGroupProps;
