import {Module} from ".";

export type Exam = ReadingExam | ListeningExam | WritingExam | SpeakingExam | LevelExam;

export interface ReadingExam {
	parts: ReadingPart[];
	id: string;
	module: "reading";
	minTimer: number;
	type: "academic" | "general";
	isDiagnostic: boolean;
}

export interface ReadingPart {
	text: {
		title: string;
		content: string;
	};
	exercises: Exercise[];
}

export interface LevelExam {
	module: "level";
	id: string;
	exercises: Exercise[];
	minTimer: number;
	isDiagnostic: boolean;
}

export interface ListeningExam {
	parts: ListeningPart[];
	id: string;
	module: "listening";
	minTimer: number;
	isDiagnostic: boolean;
}

export interface ListeningPart {
	audio: {
		source: string;
		repeatableTimes: number; // *The amount of times the user is allowed to repeat the audio, 0 for unlimited
	};
	exercises: Exercise[];
}

export interface UserSolution {
	id?: string;
	solutions: any[];
	module?: Module;
	exam?: string;
	type: string;
	score: {
		correct: number;
		total: number;
		missing: number;
	};
	exercise: string;
}

export interface WritingExam {
	module: "writing";
	id: string;
	exercises: Exercise[];
	minTimer: number;
	isDiagnostic: boolean;
}

interface WordCounter {
	type: "min" | "max";
	limit: number;
}

export interface SpeakingExam {
	id: string;
	module: "speaking";
	exercises: Exercise[];
	minTimer: number;
	isDiagnostic: boolean;
}

export type Exercise =
	| FillBlanksExercise
	| TrueFalseExercise
	| MatchSentencesExercise
	| MultipleChoiceExercise
	| WriteBlanksExercise
	| WritingExercise
	| SpeakingExercise
	| InteractiveSpeakingExercise;

export interface Evaluation {
	comment: string;
	overall: number;
	task_response: {[key: string]: number};
	misspelled_pairs?: {correction: string | null; misspelled: string}[];
}

interface InteractiveSpeakingEvaluation extends Evaluation {
	perfect_answer_1?: string;
	perfect_answer_2?: string;
	perfect_answer_3?: string;
}

interface CommonEvaluation extends Evaluation {
	perfect_answer?: string;
	perfect_answer_1?: string;
}

export interface WritingExercise {
	id: string;
	type: "writing";
	prefix: string; //* The information about the task, like the amount of time they should spend on it
	suffix: string;
	prompt: string; //* The context given to the user containing what they should write about
	wordCounter: WordCounter; //* The minimum or maximum amount of words that should be written
	attachment?: {
		url: string;
		description: string;
	}; //* The url for an image to work as an attachment to show the user
	userSolutions: {
		id: string;
		solution: string;
		evaluation?: CommonEvaluation;
	}[];
}

export interface SpeakingExercise {
	id: string;
	type: "speaking";
	title: string;
	text: string;
	prompts: string[];
	video_url: string;
	userSolutions: {
		id: string;
		solution: string;
		evaluation?: CommonEvaluation;
	}[];
}

export interface InteractiveSpeakingExercise {
	id: string;
	type: "interactiveSpeaking";
	title: string;
	text: string;
	prompts: {text: string; video_url: string}[];
	userSolutions: {
		id: string;
		solution: {question: string; answer: string}[];
		evaluation?: InteractiveSpeakingEvaluation;
	}[];
}

export interface FillBlanksExercise {
	prompt: string; // *EXAMPLE: "Complete the summary below. Click a blank to select the corresponding word for it."
	type: "fillBlanks";
	id: string;
	words: string[]; // *EXAMPLE: ["preserve", "unaware"]
	text: string; // *EXAMPLE: "They tried to {{1}} burning"
	allowRepetition: boolean;
	solutions: {
		id: string; // *EXAMPLE: "1"
		solution: string; // *EXAMPLE: "preserve"
	}[];
	userSolutions: {
		id: string; // *EXAMPLE: "1"
		solution: string; // *EXAMPLE: "preserve"
	}[];
}

export interface TrueFalseExercise {
	type: "trueFalse";
	id: string;
	prompt: string; // *EXAMPLE: "Select the appropriate option."
	questions: TrueFalseQuestion[];
	userSolutions: {id: string; solution: "true" | "false" | "not_given"}[];
}

export interface TrueFalseQuestion {
	id: string; // *EXAMPLE: "1"
	prompt: string; // *EXAMPLE: "What does her briefcase look like?"
	solution: "true" | "false" | "not_given"; // *EXAMPLE: "True"
}

export interface WriteBlanksExercise {
	prompt: string; // *EXAMPLE: "Complete the notes below by writing NO MORE THAN THREE WORDS in the spaces provided."
	maxWords: number; // *EXAMPLE: 3 - The maximum amount of words allowed per blank, 0 for unlimited
	type: "writeBlanks";
	id: string;
	text: string; // *EXAMPLE: "The Government plans to give ${{14}}"
	solutions: {
		id: string; // *EXAMPLE: "14"
		solution: string[]; // *EXAMPLE: ["Prescott"] - All possible solutions (case sensitive)
	}[];
	userSolutions: {
		id: string;
		solution: string;
	}[];
}

export interface MatchSentencesExercise {
	type: "matchSentences";
	id: string;
	prompt: string;
	userSolutions: {question: string; option: string}[];
	sentences: {
		id: string;
		sentence: string;
		solution: string;
		color: string;
	}[];
	allowRepetition: boolean;
	options: {
		id: string;
		sentence: string;
	}[];
}

export interface MultipleChoiceExercise {
	type: "multipleChoice";
	id: string;
	prompt: string; // *EXAMPLE: "Select the appropriate option."
	questions: MultipleChoiceQuestion[];
	userSolutions: {question: string; option: string}[];
}

export interface MultipleChoiceQuestion {
	variant: "image" | "text";
	id: string; // *EXAMPLE: "1"
	prompt: string; // *EXAMPLE: "What does her briefcase look like?"
	solution: string; // *EXAMPLE: "A"
	options: {
		id: string; // *EXAMPLE: "A"
		src?: string; // *EXAMPLE: "https://i.imgur.com/rEbrSqA.png" (only used if the variant is "image")
		text?: string; // *EXAMPLE: "wallet, pens and novel" (only used if the variant is "text")
	}[];
}
