<template>
	<Dialog v-model="show" :options="{ size: '2xl' }">
		<template #body-title>
			<div class="text-xl font-semibold text-ink-gray-9">
				{{
					props.exerciseID === 'new'
						? __('Create Programming Exercise')
						: __('Edit Programming Exercise')
				}}
			</div>
		</template>
		<template #body-content>
			<div class="space-y-4">
				<FormControl
					v-model="exercise.title"
					:label="__('Title')"
					:required="true"
				/>
				<FormControl
					v-model="exercise.language"
					:label="__('Language')"
					type="select"
					:options="languageOptions"
					:required="true"
				/>
				<div>
					<div class="text-xs text-ink-gray-5 mb-2">
						{{ __('Problem Statement') }}
						<span class="text-ink-red-3">*</span>
					</div>
					<TextEditor
						:content="exercise.problem_statement"
						@change="(val: string) => (exercise.problem_statement = val)"
						:editable="true"
						:fixedMenu="true"
						editorClass="prose-sm max-w-none border-b border-x bg-surface-gray-2 rounded-b-md py-1 px-2 min-h-[7rem] max-h-[18rem] overflow-y-auto"
					/>
				</div>
				<ChildTable
					v-model="exercise.test_cases"
					:columns="testCaseColumns"
					:required="true"
					:addable="true"
					:deletable="true"
					:editable="true"
					:placeholder="__('Add Test Case')"
				/>
			</div>
		</template>
		<template #actions="{ close }">
			<div class="flex justify-end space-x-2">
				<router-link
					:to="{
						name: 'ProgrammingExerciseSubmission',
						params: {
							exerciseID: props.exerciseID,
							submissionID: 'new',
						},
					}"
				>
					<Button>
						{{ __('Test this Exercise') }}
					</Button>
				</router-link>
				<router-link
					:to="{
						name: 'ProgrammingExerciseSubmissions',
						params: { exerciseID: props.exerciseID },
					}"
				>
					<Button>
						{{ __('Check Submission') }}
					</Button>
				</router-link>
				<Button variant="solid" @click="saveExercise(close)">
					{{ __('Save') }}
				</Button>
			</div>
		</template>
	</Dialog>
</template>
<script setup lang="ts">
import {
	Button,
	createListResource,
	Dialog,
	FormControl,
	TextEditor,
	toast,
} from 'frappe-ui'
import { computed, ref, watch } from 'vue'
import { ProgrammingExercise, TestCase } from '@/types/programming-exercise'
import ChildTable from '@/components/Controls/ChildTable.vue'

const show = defineModel()
const exercises = defineModel<{
	data: ProgrammingExercise[]
	reload: () => void
	hasNextPage: boolean
	next: () => void
	setValue: {
		submit: (
			data: ProgrammingExercise,
			options?: { onSuccess?: () => void }
		) => void
	}
}>('exercises')
const exercise = ref<ProgrammingExercise>({
	title: '',
	language: 'Python',
	problem_statement: '',
	test_cases: [],
})
const languageOptions = [
	{ label: 'Python', value: 'Python' },
	{ label: 'JavaScript', value: 'JavaScript' },
	{ label: 'Java', value: 'Java' },
	{ label: 'C++', value: 'C++' },
]

const props = withDefaults(
	defineProps<{
		exerciseID: string
	}>(),
	{
		exerciseID: 'new',
	}
)

watch(
	() => props.exerciseID,
	() => {
		if (props.exerciseID != 'new') {
			setExerciseData()
			fetchTestCases()
		}
	}
)

const setExerciseData = () => {
	exercises.value?.data.forEach((ex) => {
		if (ex.name === props.exerciseID) {
			exercise.value = { ...ex }
		}
	})
}

const testCases = createListResource({
	doctype: 'LMS Test Case',
	fields: ['input', 'expected_output', 'name'],
	cache: ['testCases', props.exerciseID],
	parent: 'LMS Programming Exercise',
	onSuccess(data: TestCase[]) {
		exercise.value.test_cases = data
	},
})

const fetchTestCases = () => {
	testCases.update({
		filters: {
			parent: props.exerciseID,
		},
	})
	testCases.reload()
}

const saveExercise = (close: () => void) => {
	if (props.exerciseID == 'new') createNewExercise(close)
	else updateExercise(close)
}

const createNewExercise = (close: () => void) => {
	exercises.value.insert.submit(
		{
			...exercise.value,
		},
		{
			onSuccess() {
				close()
				exercises.value.reload()
				toast.success(__('Programming Exercise created successfully'))
			},
		}
	)
}

const updateExercise = (close: () => void) => {
	exercises.value.setValue.submit(
		{
			name: props.exerciseID,
			...exercise.value,
		},
		{
			onSuccess() {
				close()
				exercises.value.reload()
				toast.success(__('Programming Exercise updated successfully'))
			},
		}
	)
}

const testCaseColumns = computed(() => {
	return ['Input', 'Expected Output']
})
</script>
