export type Validator =
  | {
      type: "email",
      text: string
    }
  | {
      type: "expression",
      expression: string,
      text: string
    }
  | {
      type: "numeric",
      minValue?: number,
      maxValue?: number,
      text: string
    }
  | {
      type: "text",
      minLength?: number,
      maxLength?: number,
      allowDigits?: boolean,
      text: string
    }
  | {
      type: "regex",
      regex: string,
      text: string
    }
  | {
      type: "answercount",
      text: string,
      minCount?: number,
      maxCount?: number
    }

export type BaseQuestion = {|
  name: string,
  title: string,
  isRequired?: boolean,
  hasOther?: boolean,
  description?: string,
  visibleIf?: string,
  defaultAnswer?: any,
  validators?: Array<Validator>
|}

export type QuestionChoice =
  | {
      value: string,
      text: string
    }
  | string

export type TextQuestion = {
  ...BaseQuestion,
  type: "text" | "multiline-text"
}

export type USRegionQuestion = {
  ...BaseQuestion,
  type: "us-region" | "multiple-us-region" | "us-state" | "multiple-us-state"
}

export type RadioGroupQuestion = {
  ...BaseQuestion,
  type: "radiogroup",
  choices: Array<QuestionChoice>
}

export type CheckboxQuestion = {
  ...BaseQuestion,
  type: "checkbox",
  choices: Array<QuestionChoice>
}

export type DropdownQuestion = {
  ...BaseQuestion,
  type: "dropdown",
  choices: Array<QuestionChoice>
}

export type MultipleDropdownQuestion = {
  ...BaseQuestion,
  type: "multiple-dropdown",
  choices: Array<QuestionChoice>
}

export type ImagePickerQuestion = {
  ...BaseQuestion,
  type: "imagepicker",
  choices: Array<QuestionChoice>
}

export type ChoiceRankerQuestion = {
  ...BaseQuestion,
  type: "choiceranker",
  choices: Array<QuestionChoice>,
  choicesAtOnce: number,
  trials: number
}

export type DynamicMatrixQuestion = {
  ...BaseQuestion,
  type: "matrixdynamic",
  choices: Array<QuestionChoice>,
  columns: Array<{
    name: string,
    title?: string,
    cellType: "dropdown" | "checkbox" | "text" | "autocomplete",
    choices: Array<QuestionChoice>,
    hasOther?: boolean
  }>
}

export type BooleanQuestion = {
  ...BaseQuestion,
  type: "boolean"
}

export type MatrixQuestion = {
  ...BaseQuestion,
  type: "matrix",
  columns: Array<QuestionChoice>,
  rows: Array<QuestionChoice>
}

export type MatrixDropdownQuestion = {
  ...BaseQuestion,
  choices: Array<QuestionChoice>,
  columns: Array<Question>,
  rows: Array<QuestionChoice>
}

export type RatingQuestion = {
  ...BaseQuestion,
  type: "rating",
  rankings?: number,
  rateValues?: Array<QuestionChoice>,
  minRateDescription?: string,
  midRateDescription?: string,
  maxRateDescription?: string
}

export type FileQuestion = {
  ...BaseQuestion,
  type: "file",
  maxSize?: number
}

export type SliderQuestion = {
  ...BaseQuestion,
  type: "slider",
  min: number,
  max: number,
  step?: number
}

export type CommentQuestion = {
  ...BaseQuestion,
  type: "comment"
}

export type APIAutocompleteQuestion = {
  ...BaseQuestion,
  type: "autocomplete",
  requestUrl: string
}

export type Question =
  | RadioGroupQuestion
  | CheckboxQuestion
  | DropdownQuestion
  | ImagePickerQuestion
  | ChoiceRankerQuestion
  | BooleanQuestion
  | MatrixQuestion
  | MatrixDropdownQuestion
  | RatingQuestion
  | CommentQuestion

export type Page = {
  elements: Array<Question>
}

export type SurveyMaterialFormat = {
  expressionLanguage: "surveyjs",
  ...
    | {| questions: Array<Question> |}
    | {|
        pages: Array<Page>
      |}
}

export type AutocompleteRequestFunction = (
  url: string,
  value: string
) => Array<{ value: string, label: string, subLabel?: string }>

export default SurveyMaterialFormat
