import * as React from "react";
import { InputPrompt, InternalInputPrompt } from "./InputPrompt";
import {
  InternalMultipleChoicePrompt,
  MultipleChoicePrompt
} from "./MultipleChoicePrompt";
import {
  InputPromptData,
  MultipleChoicePromptData,
  PromptData,
  TrueFalsePromptData
} from "./QuizData";
import { InternalTrueFalsePrompt, TrueFalsePrompt } from "./TrueFalsePrompt";

export interface IPromptProps {
  children: React.ReactChild | React.ReactChild[];
}

export abstract class Prompt<P = {}> extends React.PureComponent<P> {
  static is(value: any): value is Prompt {
    return (
      React.isValidElement(value) &&
      (value.type === InputPrompt ||
        value.type === TrueFalsePrompt ||
        value.type === MultipleChoicePrompt)
    );
  }
}

export interface IInternalPromptProps {
  prompt: PromptData;
  input: any[];
  disabled?: boolean;
  update(fn: (state: any[]) => any[]): void;
}

export class InternalPrompt<
  P extends IInternalPromptProps
> extends React.PureComponent<P> {
  render(): React.ReactChild | React.ReactChild[] {
    if (TrueFalsePromptData.is(this.props.prompt)) {
      return <InternalTrueFalsePrompt {...(this.props as any)} />;
    } else if (MultipleChoicePromptData.is(this.props.prompt)) {
      return <InternalMultipleChoicePrompt {...(this.props as any)} />;
    } else if (InputPromptData.is(this.props.prompt)) {
      return <InternalInputPrompt {...(this.props as any)} />;
    } else {
      throw new TypeError("Invalid PromptData " + this.props.prompt);
    }
  }
}
