<script lang="ts" setup generic="T extends {[key:string]:any}, P extends Path<T>">
import type { Path } from '@bagelink/vue'
import type { ComponentExposed } from 'vue-component-type-helpers'
import type { ModalFormOptions } from '../plugins/modalTypes'
import { Btn, Modal, BagelForm } from '@bagelink/vue'
import { ref } from 'vue'

// eslint-disable-next-line vue/prop-name-casing
const props = withDefaults(defineProps<ModalFormOptions<T>>(), {
	visible: true,
	dismissable: true,
})

const emit = defineEmits<{
	'update:modelValue': [value: T]
	'update:visible': [value: boolean]
}>()

const modal = ref<ComponentExposed<typeof Modal>>()

const formData = defineModel<T>('modelValue', {
	default: {} as Partial<T>,
})

type BagelFormT = ComponentExposed<typeof BagelForm<T, P>>

const form = ref<BagelFormT>()
const closeModal = () => modal.value?.closeModal()

const submitting = ref(false)

async function runSubmit() {
	if (submitting.value) { return }
	if (form.value?.validateForm() === false) { return }
	submitting.value = true
	try {
		await props.onSubmit?.(formData.value)
		closeModal()
	} catch (err: any) {
		submitting.value = false
		if (props.onError) {
			props.onError(err)
		} else {
			console.error('[ModalForm] Submit error:', err)
		}
	}
}

function runDelete() {
	props.onDelete?.(formData.value)
	closeModal()
}

function setFormValues(values: { [key: string]: any }) {
	Object.assign(formData, values)
}

defineExpose({ setFormValues })
</script>

<template>
	<Modal
		ref="modal" :side :width :visible="visible" :dismissable :title
		@update:visible="($event: boolean) => emit('update:visible', $event)"
	>
		<template #toolbar>
			<slot name="toolbar" />
		</template>
		<BagelForm
			v-if="visible" ref="form" v-model="formData" :schema="schema"
			@update:modelValue="emit('update:modelValue', $event)" @submit="runSubmit"
		/>
		<template v-if="onDelete || onSubmit" #footer>
			<div class="flex gap-0">
				<Btn thin flat :value="cancelText || 'Cancel'" @click="closeModal" />
				<Btn
					v-if="onDelete" thin icon="delete" flat :value="deleteText || 'Delete'" color="red"
					@click="runDelete"
				/>
			</div>
			<div class="flex gap-05">
				<Btn
					v-if="onDuplicate" outline class="px-1" icon="copy_all" flat :value="duplicateText || 'Duplicate'"
					@click="onDuplicate?.(formData)"
				/>
				<Btn v-if="onSubmit" :value="submitText || 'Submit'" @click="runSubmit" />
			</div>
		</template>
	</Modal>
</template>

<style scoped>
.modal-title {
	margin-top: 0.5rem;
}

@media screen and (max-width: 910px) {
	.modal-title {
		margin-top: 1rem;
	}
}
</style>
