import type {
  CascaderProps,
  CascaderSlots,
  CheckboxGroupProps,
  DatePickerProps,
  DatePickerSlots,
  FormInst,
  FormItemGiProps,
  FormProps,
  GridProps,
  InputNumberProps,
  InputNumberSlots,
  InputProps,
  InputSlots,
  RadioGroupProps,
  SelectProps,
  SelectSlots,
  TimePickerProps,
  TimePickerSlots,
  TreeSelectProps,
  TreeSelectSlots,
} from "naive-ui";
import type { Component, Ref, VNode } from "vue";
import type { JSX } from "vue/jsx-runtime";

/**
 * 表单对象
 */
export type FormModelValue = { [k in string]: any };

/**
 * 组件默认插槽
 */
type DefaultSlots = {
  default: () => any;
};

type CompPropsAndSlots<P, S> = {
  props: P;
  slots: S;
};

/**
 * 支持的组件列表
 */
export type Fm = {
  custom: CompPropsAndSlots<any, any>;
  input: CompPropsAndSlots<InputProps, InputSlots>;
  inputNumber: CompPropsAndSlots<InputNumberProps, InputNumberSlots>;
  radioGroup: CompPropsAndSlots<RadioGroupProps, DefaultSlots>;
  checkboxGroup: CompPropsAndSlots<CheckboxGroupProps, DefaultSlots>;
  select: CompPropsAndSlots<SelectProps, SelectSlots>;
  treeSelect: CompPropsAndSlots<TreeSelectProps, TreeSelectSlots>;
  cascader: CompPropsAndSlots<CascaderProps, CascaderSlots>;
  datePicker: CompPropsAndSlots<DatePickerProps, DatePickerSlots>;
  timePicker: CompPropsAndSlots<TimePickerProps, TimePickerSlots>;
};

/**
 * 选项
 */
type OptionType =
  | (SelectNodeVo<any> | TreeNodeVo<any>)[]
  | Ref<SelectNodeVo<any>[] | TreeNodeVo<any>[]>;

type BaseFormProItemProps<ModelValue> = FormItemGiProps & {
  /**
   * 描述说明
   */
  remarkRender?: JSX.Element;
  /**
   * 配置项
   */
  options?: OptionType;
  /**
   * 当type为custom时 render函数跟defineComponent 只应该存在一个 render函数无状态 defineComponent有状态
   * @param modelValue 回传表单对象
   */
  customRender?: (modelValue: ModelValue) => VNode;
  defineComponent?: Component<{ modelValue: ModelValue }>;
};

/**
 * 表单项配置
 */
export type FormProItemProps<
  ModelValue,
  TK extends keyof Fm
> = BaseFormProItemProps<ModelValue> & {
  type: TK;
  componentsProps?: Fm[TK]["props"];
  componentsSlots?: Fm[TK]["slots"];
};

/**
 * 表单组件配置
 */
export type FormItemOptions<ModelValue> = {
  [key in keyof ModelValue]: {
    [T in keyof Fm]: FormProItemProps<ModelValue, T>;
  }[keyof Fm];
};

/**
 * 表单配置
 */
export type FormProProps<ModalValue = {}> = FormProps & {
  value: FormModelValue;
  "onUpdate:value": Function;
  onUpdateValue: Function;
  gridProps?: GridProps;
  formItemOptions?: FormItemOptions<ModalValue>;
};

/**
 * 表单实例
 */
export type FormProInst<ModalValue extends FormModelValue = {}> = {} & FormInst;
