/**
 * Defines which type of content a Step returns.
 * Add an entry here when you define a step
 */
export type StepDefinition = {
  FILE_IMPORT: {
    returnType: string
    metadata: {
      caption: string
      acceptedFileTypes: string
    }
  } // String content of the file
  TARGET_MY_COLLECTION: {
    returnType: number
    metadata: {
      caption: string
    }
  } // folderPath
  URL_IMPORT: {
    returnType: string
    metadata: {
      caption: string
      placeholder: string
    }
  } // String content of the url
}

export type StepReturnValue = StepDefinition[keyof StepDefinition]["returnType"]

/**
 * Defines what the data structure of a step
 */
export type Step<T extends keyof StepDefinition> =
  StepDefinition[T]["metadata"] extends never
    ? {
        name: T
        caption?: string
        metadata: undefined
      }
    : {
        name: T
        caption?: string
        metadata: StepDefinition[T]["metadata"]
      }

/**
 * The return output value of an individual step
 */
export type StepReturnType<T> = T extends Step<infer U>
  ? StepDefinition[U]["returnType"]
  : never

export type StepMetadata<T> = T extends Step<infer U>
  ? StepDefinition[U]["metadata"]
  : never

/**
 * Defines the value of the output list generated by a step
 */
export type StepsOutputList<T> = {
  [K in keyof T]: StepReturnType<T[K]>
}

type StepFuncInput<T extends keyof StepDefinition> =
  StepDefinition[T]["metadata"] extends never
    ? {
        stepName: T
        caption?: string
      }
    : {
        stepName: T
        caption?: string
        metadata: StepDefinition[T]["metadata"]
      }

/** Use this function to define a step */
export const step = <T extends keyof StepDefinition>(input: StepFuncInput<T>) =>
  <Step<T>>{
    name: input.stepName,
    metadata: (input as any).metadata ?? undefined,
    caption: input.caption,
  }
