<template>
	<el-drawer
		:model-value="visible"
		:title="isEdit ? t('pages.vectorStore.edit') : t('pages.vectorStore.create')"
		direction="rtl"
		size="640px"
		@update:model-value="$emit('update:visible', $event)"
	>
		<el-form ref="formRef" :model="form" :rules="formRules" label-position="top">
			<el-form-item :label="t('pages.vectorStore.name')" prop="name">
				<el-input v-model="form.name" :placeholder="t('pages.vectorStore.namePlaceholder')" autocomplete="off" />
			</el-form-item>

			<el-form-item :label="t('pages.vectorStore.engineType')" prop="engine_type">
				<el-select
					v-model="form.engine_type"
					:placeholder="t('pages.vectorStore.engineTypePlaceholder')"
					class="w-full"
					:disabled="isEdit"
					@change="handleEngineTypeChange"
				>
					<el-option
						v-for="item in engineTypes"
						:key="item.type"
						:label="item.display_name"
						:value="item.type"
					/>
				</el-select>
			</el-form-item>

			<template v-if="currentTypeConfig">
				<div class="section-title">{{ t('pages.vectorStore.connectionConfig') }}</div>
				<div class="form-grid">
					<el-form-item
						v-for="field in currentTypeConfig.connection_fields"
						:key="field.name"
						:label="field.description || field.name"
					>
						<el-switch
							v-if="field.type === 'boolean'"
							v-model="form.connection_config[field.name]"
							:disabled="isEdit && field.immutable"
						/>
						<el-input
							v-else
							v-model="form.connection_config[field.name]"
							:placeholder="field.default || field.description || field.name"
							:type="field.sensitive ? 'password' : 'text'"
							:show-password="field.sensitive"
							:autocomplete="field.sensitive ? 'new-password' : 'off'"
							:disabled="isEdit && field.immutable"
						/>
					</el-form-item>
				</div>

				<div class="section-title">{{ t('pages.vectorStore.indexConfig') }}</div>
				<div class="form-grid">
					<el-form-item
						v-for="field in currentTypeConfig.index_fields"
						:key="field.name"
						:label="field.description || field.name"
					>
						<el-switch
							v-if="field.type === 'boolean'"
							v-model="form.index_config[field.name]"
							:disabled="isEdit && field.immutable"
						/>
						<el-input
							v-else-if="field.type === 'number'"
							v-model.number="form.index_config[field.name]"
							:placeholder="String(field.default || '')"
							:disabled="isEdit && field.immutable"
						/>
						<el-select
							v-else-if="field.enum && field.enum.length"
							v-model="form.index_config[field.name]"
							:placeholder="field.description || field.name"
							class="w-full"
							:disabled="isEdit && field.immutable"
						>
							<el-option
								v-for="opt in field.enum"
								:key="opt"
								:label="opt"
								:value="opt"
							/>
						</el-select>
						<el-input
							v-else
							v-model="form.index_config[field.name]"
							:placeholder="field.default || field.description || field.name"
							:disabled="isEdit && field.immutable"
						/>
					</el-form-item>
				</div>
			</template>
		</el-form>

		<template #footer>
			<div class="drawer-footer">
				<el-button @click="$emit('update:visible', false)">{{ t('common.cancel') }}</el-button>
				<el-button type="primary" plain :loading="testingConnection" @click="handleTestConnection">
					{{ t('pages.vectorStore.testConnection') }}
				</el-button>
				<el-button type="primary" :loading="saving" @click="handleSave">
					{{ t('common.save') }}
				</el-button>
			</div>
		</template>
	</el-drawer>
</template>

<script setup lang="ts">
import { reactive, ref, computed, watch } from 'vue'
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
import { vector } from '@repo/api-service'
import { useI18n } from '@/composables/useI18n'
import type { EngineTypeConfig, VectorStoreItem } from './types'

const props = defineProps<{
	visible: boolean
	isEdit: boolean
	editId: string
	engineTypes: EngineTypeConfig[]
	initialData?: VectorStoreItem | null
}>()

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

const { t } = useI18n()

const formRef = ref<FormInstance>()
const saving = ref(false)
const testingConnection = ref(false)

const form = reactive({
	name: '',
	engine_type: '',
	connection_config: {} as Record<string, any>,
	index_config: {} as Record<string, any>
})

const formRules: FormRules = {
	name: [{ required: true, message: t('pages.vectorStore.namePlaceholder'), trigger: 'blur' }],
	engine_type: [{ required: true, message: t('pages.vectorStore.engineTypePlaceholder'), trigger: 'change' }]
}

const currentTypeConfig = computed(() =>
	props.engineTypes.find((item) => item.type === form.engine_type) || null
)

function initFormByType(typeConfig: EngineTypeConfig) {
	const conn: Record<string, any> = {}
	for (const field of typeConfig.connection_fields) {
		conn[field.name] = field.default || ''
	}
	const idx: Record<string, any> = {}
	for (const field of typeConfig.index_fields) {
		if (field.type === 'number') {
			idx[field.name] = field.default ? Number(field.default) : 0
		} else {
			idx[field.name] = field.default || ''
		}
	}
	form.connection_config = conn
	form.index_config = idx
}

function handleEngineTypeChange() {
	const config = currentTypeConfig.value
	if (config) {
		initFormByType(config)
	}
}

function resetForm() {
	form.name = ''
	form.engine_type = ''
	form.connection_config = {}
	form.index_config = {}
	formRef.value?.resetFields()
}

function loadFromData(data: VectorStoreItem) {
	form.name = data.name
	form.engine_type = data.engine_type
	form.connection_config = { ...data.connection_config }
	form.index_config = { ...data.index_config }
}

watch(() => props.visible, (val) => {
	if (val) {
		if (props.isEdit && props.initialData) {
			loadFromData(props.initialData)
		} else {
			resetForm()
		}
	}
})

async function handleSave() {
	if (!formRef.value) return
	await formRef.value.validate()

	saving.value = true
	try {
		if (props.isEdit) {
			const res = await vector.postUpdate({ id: props.editId, name: form.name })
			if (res?.isSuccess) {
				ElMessage.success(t('pages.vectorStore.updateSuccess'))
				emit('update:visible', false)
				emit('saved')
			} else {
				ElMessage.error(t('pages.vectorStore.updateFailed'))
			}
		} else {
			const res = await vector.postCreate({
				name: form.name,
				engine_type: form.engine_type,
				connection_config: {
					addr: form.connection_config.addr || '',
					username: form.connection_config.username || '',
					password: form.connection_config.password || ''
				},
				index_config: {
					index_name: form.index_config.index_name || '',
					number_of_shards: Number(form.index_config.number_of_shards) || 1,
					number_of_replicas: Number(form.index_config.number_of_replicas) || 0
				}
			})
			if (res?.isSuccess) {
				ElMessage.success(t('pages.vectorStore.createSuccess'))
				emit('update:visible', false)
				emit('saved')
			} else {
				ElMessage.error(t('pages.vectorStore.createFailed'))
			}
		}
	} catch {
		ElMessage.error(props.isEdit ? t('pages.vectorStore.updateFailed') : t('pages.vectorStore.createFailed'))
	} finally {
		saving.value = false
	}
}

async function handleTestConnection() {
	if (!form.engine_type) {
		ElMessage.warning(t('pages.vectorStore.selectEngineTypeFirst'))
		return
	}
	testingConnection.value = true
	try {
		const res = await vector.postConnectTestConfig({
			engine_type: form.engine_type,
			connection_config: {
				addr: form.connection_config.addr || '',
				username: form.connection_config.username || '',
				password: form.connection_config.password || ''
			}
		})
		if (res?.isSuccess) {
			ElMessage.success(t('pages.vectorStore.testConfigSuccess'))
		} else {
			ElMessage.error(t('pages.vectorStore.testConfigFailed'))
		}
	} catch {
		ElMessage.error(t('pages.vectorStore.testConfigFailed'))
	} finally {
		testingConnection.value = false
	}
}
</script>

<style scoped lang="less">
.section-title {
	font-size: 14px;
	font-weight: 600;
	color: var(--text-primary);
	margin: 16px 0 12px;
	padding-bottom: 8px;
	border-bottom: 1px solid var(--border-light);
}

.form-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 0 12px;
}

.drawer-footer {
	display: flex;
	justify-content: flex-end;
	gap: 8px;
	flex-wrap: wrap;
}

@media (max-width: 960px) {
	.form-grid {
		grid-template-columns: minmax(0, 1fr);
	}
}
</style>
