<script setup lang="ts" generic="T extends Record<string, any>">
import type { SchemaDefinition } from '../form-flow/form-flow'
/**
 * DialogForm - Form dialog using FormFlow schema
 *
 * Wraps Dialog with FormFlow for schema-driven forms.
 * Returns { action, data } when closed.
 */
import type { DialogWidth, DialogPosition, DialogAction } from './dialogTypes'
import { ref, computed } from 'vue'
import Btn from '../components/Btn.vue'
import FormFlow from '../form-flow/FormFlow.vue'
import { useI18n } from '../i18n'
import Dialog from './Dialog.vue'

const props = withDefaults(defineProps<{
	open: boolean
	title?: string
	width?: DialogWidth
	position?: DialogPosition
	dismissable?: boolean
	schema: SchemaDefinition
	modelValue?: T
	onSubmit?: (data: T) => Promise<void> | void
	onDelete?: (data: T) => Promise<void> | void
	submitText?: string
	cancelText?: string
	deleteText?: string
}>(), {
	width: 'm',
	position: 'center',
	dismissable: true,
})

const emit = defineEmits<{
	'update:open': [value: boolean]
	'resolve': [result: { action: DialogAction, data: T }]
}>()

const { $t } = useI18n()

// Form state - use Record<string, any> internally for FormFlow compatibility
const formData = ref<Record<string, any>>({ ...(props.modelValue || {}) })
const isSubmitting = ref(false)
const isDeleting = ref(false)
const error = ref<string | null>(null)

// Ref to FormFlow for validation
const formFlowRef = ref<{ validate: () => boolean }>()

const hasDeleteHandler = computed(() => typeof props.onDelete === 'function')

async function handleSubmit() {
	if (isSubmitting.value) return

	// Validate form before submitting
	if (!formFlowRef.value?.validate()) {
		error.value = $t('dialogForm.validationError')
		return
	}

	error.value = null
	isSubmitting.value = true

	try {
		if (props.onSubmit) {
			await props.onSubmit(formData.value as T)
		}
		emit('resolve', { action: 'submit', data: formData.value as T })
		emit('update:open', false)
	} catch (err: unknown) {
		error.value = err instanceof Error ? err.message : $t('dialogForm.errorOccurred')
	} finally {
		isSubmitting.value = false
	}
}

async function handleDelete() {
	if (isDeleting.value || !props.onDelete) return

	error.value = null
	isDeleting.value = true

	try {
		await props.onDelete(formData.value as T)
		emit('resolve', { action: 'delete', data: formData.value as T })
		emit('update:open', false)
	} catch (err: unknown) {
		error.value = err instanceof Error ? err.message : $t('dialogForm.errorOccurred')
	} finally {
		isDeleting.value = false
	}
}

function handleCancel() {
	emit('resolve', { action: 'cancel', data: formData.value as T })
	emit('update:open', false)
}

function handleClose() {
	// When dialog closes via backdrop/ESC, treat as cancel
	emit('resolve', { action: 'cancel', data: formData.value as T })
}
</script>

<template>
	<Dialog
		:open="open" :title="title" :width="width" :position="position" :dismissable="dismissable"
		@update:open="$emit('update:open', $event)" @close="handleClose"
	>
		<!-- Error message -->
		<div v-if="error" class="dialog-form-error bg-red-30 color-red radius-1 mb-1 txt14 px-1 py-075">
			{{ error }}
		</div>

		<!-- Form fields -->
		<FormFlow ref="formFlowRef" v-model="formData" :schema="schema" @submit="handleSubmit" />

		<template #footer>
			<!-- Delete button (left side) -->
			<Btn
				v-if="hasDeleteHandler" color="red" flat :loading="isDeleting" :disabled="isSubmitting" class="me-auto"
				@click="handleDelete"
			>
				{{ deleteText || $t('dialogForm.delete') }}
			</Btn>

			<div class="flex-grow-1" />

			<!-- Cancel button -->
			<Btn flat :disabled="isSubmitting || isDeleting" @click="handleCancel">
				{{ cancelText || $t('dialogForm.cancel') }}
			</Btn>

			<!-- Submit button -->
			<Btn color="primary" :loading="isSubmitting" :disabled="isDeleting" @click="handleSubmit">
				{{ submitText || $t('dialogForm.save') }}
			</Btn>
		</template>
	</Dialog>
</template>
