<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, useBagel, BagelForm } from '@bagelink/vue'

// eslint-disable-next-line vue/prop-name-casing
const props = defineProps<ModalFormOptions<T>>()

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

const bagel = useBagel()

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?.closeModal()

let submitting = $ref(false)

async function runSubmit() {
	if (submitting) return
	if (form?.validateForm() === false) return
	submitting = true
	try {
		await props.onSubmit?.(formData.value)
		closeModal()
	} catch (err: any) {
		submitting = false
		if (props.onError) props.onError(err)
		else bagel.onError?.(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)"
	>
		<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>
