import {
  TextTypeKnob,
  NumberTypeKnob,
  ColorTypeKnob,
  BooleanTypeKnob,
  ObjectTypeKnob,
  SelectTypeKnob,
  RadiosTypeKnob,
  ArrayTypeKnob,
  DateTypeKnob,
  ButtonTypeOnClickProp,
  FileTypeKnob,
  OptionsTypeKnob,
  KnobType,
} from './components/types';

export type Mutable<T> = {
  -readonly [P in keyof T]: T[P] extends readonly (infer U)[] ? U[] : T[P];
};

type KnobPlus<T extends KnobType, K> = K & {
  type: T;
  groupId?: string;
  disableDebounce?: boolean;
  disableForceUpdate?: boolean;
};

export type Knob<T extends KnobType = any> = T extends 'text'
  ? KnobPlus<T, Pick<TextTypeKnob, 'value'>>
  : T extends 'boolean'
  ? KnobPlus<T, Pick<BooleanTypeKnob, 'value'>>
  : T extends 'number'
  ? KnobPlus<T, Pick<NumberTypeKnob, 'value' | 'range' | 'min' | 'max' | 'step'>>
  : T extends 'color'
  ? KnobPlus<T, Pick<ColorTypeKnob, 'value'>>
  : T extends 'object'
  ? KnobPlus<T, Pick<ObjectTypeKnob<any>, 'value'>>
  : T extends 'select'
  ? KnobPlus<T, Pick<SelectTypeKnob, 'value' | 'options'> & { selectV2: true }>
  : T extends 'radios'
  ? KnobPlus<T, Pick<RadiosTypeKnob, 'value' | 'options'>>
  : T extends 'array'
  ? KnobPlus<T, Pick<ArrayTypeKnob, 'value' | 'separator'>>
  : T extends 'date'
  ? KnobPlus<T, Pick<DateTypeKnob, 'value'>>
  : T extends 'files'
  ? KnobPlus<T, Pick<FileTypeKnob, 'value' | 'accept'>>
  : T extends 'button'
  ? KnobPlus<T, { value?: never; callback: ButtonTypeOnClickProp; hideLabel: true }>
  : T extends 'options'
  ? KnobPlus<T, Pick<OptionsTypeKnob<any>, 'options' | 'value' | 'optionsObj'>>
  : never;

export { KnobType };
