<script setup lang="ts">
import { computed, watch } from 'vue'
import NodeRuntimeConfig from '@/nodes/_base/NodeRuntimeConfig.vue'
import { useSetterModel } from '@/nodes/src/_shared/useSetterModel'
import SecretInput from '@/features/secretInput/SecretInput.vue'
import VarInput from '../_base/VarInput.vue'
import { nodeMap } from '../src'

interface CustomNodeOption {
	label?: string
	value?: string | number | boolean
}

interface CustomNodeParameter {
	name?: string
	label?: string
	description?: string
	type?: string
	required?: boolean
	defaultValue?: unknown
	placeholder?: string
	min?: number
	max?: number
	options?: CustomNodeOption[]
}

const props = defineProps<{
	data: Record<string, any>
}>()

const emit = defineEmits<{
	update: [data: Record<string, any>]
}>()

const formData = useSetterModel<Record<string, any>>(props, emit)
console.log(111, formData, nodeMap)
const parameters = computed<CustomNodeParameter[]>(
	() => nodeMap?.[formData.value?.nodeType]?.parameters || []
)

const normalizeType = (type?: string) => {
	const raw = `${type || ''}`.toLowerCase()
	if (['text-input', 'text', 'string', 'input'].includes(raw)) return 'text-input'
	if (['secret-input', 'password'].includes(raw)) return 'secret-input'
	if (['text-area', 'textarea'].includes(raw)) return 'text-area'
	if (['number', 'int', 'integer', 'float', 'double'].includes(raw)) return 'number'
	if (['select', 'enum'].includes(raw)) return 'select'
	if (['checkbox', 'switch', 'boolean', 'bool'].includes(raw)) return 'checkbox'
	if (raw === 'edg-link') return 'edg-link'
	return 'text-input'
}

const normalizeDefaultValue = (parameter: CustomNodeParameter) => {
	const type = normalizeType(parameter.type)
	if (parameter.defaultValue !== undefined) {
		return parameter.defaultValue
	}
	if (type === 'checkbox') return false
	if (type === 'number') return undefined
	return ''
}

watch(
	parameters,
	(newParameters) => {
		for (const parameter of newParameters) {
			const key = parameter.name
			if (!key) continue
			if (normalizeType(parameter.type) === 'edg-link') continue

			formData.value[key] = normalizeDefaultValue(parameter)
		}
	},
	{ immediate: true, deep: true }
)

const getSelectOptions = (parameter: CustomNodeParameter): CustomNodeOption[] => {
	if (!Array.isArray(parameter.options)) return []
	return parameter.options
		.map((item) => ({
			label: item?.label ?? `${item?.value ?? ''}`,
			value: item?.value ?? item?.label ?? ''
		}))
		.filter((item) => item.label !== undefined)
}

const getLabel = (parameter: CustomNodeParameter) => parameter.label || parameter.name || 'param'

const getParameterValue = (parameter: CustomNodeParameter) => {
	const key = parameter.name
	if (!key) return undefined
	return formData.value?.[key]
}

const setParameterValue = (parameter: CustomNodeParameter, value: unknown) => {
	const key = parameter.name
	if (!key) return

	formData.value[key] = value
}
</script>

<template>
	<el-scrollbar class="w-full box-border">
		<el-form label-position="top" label-width="120px" class="p-12px">
			<el-form-item
				v-for="parameter in parameters"
				:key="parameter.name || parameter.label"
				:required="!!parameter.required"
			>
				<template #label>
					<div class="w-full flex items-center justify-between beautify">
						<label class="text-14px font-bold text-gray-700">{{ getLabel(parameter) }}</label>
					</div>
					<div v-if="parameter.description" class="text-12px text-gray-500">
						{{ parameter.description }}
					</div>
				</template>
				<!-- <el-alert
					v-if="isEdgeLink(parameter)"
					type="info"
					show-icon
					:closable="false"
					:title="parameter.description || 'Edge-link output, no value input needed'"
				/> -->

				<VarInput
					v-if="normalizeType(parameter.type) === 'text-input'"
					:model-value="getParameterValue(parameter)"
					:placeholder="parameter.placeholder || ''"
					@update:model-value="setParameterValue(parameter, $event)"
				/>

				<SecretInput
					v-else-if="normalizeType(parameter.type) === 'secret-input'"
					:model-value="getParameterValue(parameter) as any"
					:placeholder="parameter.placeholder || ''"
					@update:model-value="setParameterValue(parameter, $event)"
				/>

				<VarInput
					v-else-if="normalizeType(parameter.type) === 'text-area'"
					:model-value="getParameterValue(parameter)"
					:placeholder="parameter.placeholder || ''"
					:rows="3"
					@update:model-value="setParameterValue(parameter, $event)"
				/>

				<el-input-number
					v-else-if="normalizeType(parameter.type) === 'number'"
					:model-value="getParameterValue(parameter)"
					:min="parameter.min"
					:max="parameter.max"
					controls-position="right"
					style="width: 100%"
					@update:model-value="setParameterValue(parameter, $event)"
				/>

				<el-select
					v-else-if="normalizeType(parameter.type) === 'select'"
					:model-value="getParameterValue(parameter)"
					style="width: 100%"
					@update:model-value="setParameterValue(parameter, $event)"
				>
					<el-option
						v-for="option in getSelectOptions(parameter)"
						:key="`${parameter.name}-${option.value}`"
						:label="option.label"
						:value="option.value"
					/>
				</el-select>

				<el-switch
					v-else-if="normalizeType(parameter.type) === 'checkbox'"
					:model-value="Boolean(getParameterValue(parameter))"
					@update:model-value="setParameterValue(parameter, $event)"
				/>

				<el-input
					v-else
					:model-value="getParameterValue(parameter)"
					:placeholder="parameter.placeholder || ''"
					@update:model-value="setParameterValue(parameter, $event)"
				/>

				<div v-if="parameter.description" class="text-12px text-gray-500 mt-6px">
					{{ parameter.description }}
				</div>
			</el-form-item>
		</el-form>

		<NodeRuntimeConfig v-model="formData" class="px-12px" />
	</el-scrollbar>
</template>
