import type { SetupContext } from 'vue'
import type {
  RuleItem,
  ValidateError,
  ValidateFieldsError,
} from '../../../libs/async-validator'
import type { FormComponentSize } from '../../../constants'
import type { Arrayable } from '../../../utils'
import type {
  FormItemProp,
  FormItemProps,
  FormItemValidateStates,
} from './form-item'
import type { FormEmits, FormProps } from './form'

export interface FormItemRule extends RuleItem {
  trigger?: Arrayable<string>
}
export type FormRules = Partial<Record<string, Arrayable<FormItemRule>>>

export type FormValidationResult = Promise<boolean>
export type FormValidationCallback = (
  isValid: boolean,
  invalidFields?: ValidateFieldsError
) => void

export interface FormValidateFailure {
  errors: ValidateError[] | null
  fields: ValidateFieldsError
}

export type FormContext = FormProps & {
  emits: SetupContext<FormEmits>['emit']

  //expose
  addField: (field: FormItemContext) => void
  removeField: (field: FormItemContext) => void
  resetFields: (props?: Arrayable<FormItemProp>) => void
  clearValidate: (props?: Arrayable<FormItemProp>) => void
  validateField: (
    props?: Arrayable<FormItemProp>,
    callback?: FormValidationCallback
  ) => FormValidationResult
}

export interface FormItemContext extends FormItemProps {
  size: FormComponentSize
  validateState: FormItemValidateStates
  hasLabel: boolean
  validate: (
    trigger: string,
    callback?: FormValidationCallback
  ) => FormValidationResult
  resetField: () => void
  clearValidate: () => void
}
