<template>
	<view class="dynamic-form">
		<view v-for="(field, index) in fields" :key="field.id || index" class="form-item"
			:class="{ 'form-item-up': isUpType(field.type) }">
			<view class="form-header">
				<text class="form-label" :class="{ required: field.is_required == 1 }">{{ field.label }}</text>
				<text v-if="field.tips" class="form-tips">{{ field.tips }}</text>
			</view>
			<view class="form-control">
				<!-- 单行文本 -->
				<form-item-text v-if="field.type === 'text'" :value="formData[field.key]"
					:placeholder="field.placeholder" @input="onInput(field.key, $event)" />
				<!-- 多行文本 -->
				<form-item-textarea v-else-if="field.type === 'textarea'" :value="formData[field.key]"
					:placeholder="field.placeholder" @input="onInput(field.key, $event)" />
				<!-- 数字输入 -->
				<form-item-number v-else-if="field.type === 'number'" :value="formData[field.key]"
					:placeholder="field.placeholder" @input="onInput(field.key, $event)" />
				<!-- 多图上传 -->
				<form-item-image v-else-if="field.type === 'image_multi'" :value="formData[field.key]"
					:maxCount="field.maxCount || 9" @input="onInput(field.key, $event)" />
				<!-- 视频上传 -->
				<form-item-video v-else-if="field.type === 'video'" :value="formData[field.key]"
					@input="onInput(field.key, $event)" />
				<!-- 下拉选择 -->
				<form-item-select v-else-if="field.type === 'select'" :value="formData[field.key]"
					:options="field.options" :placeholder="field.placeholder" @input="onInput(field.key, $event)" />
				<!-- 单选 -->
				<form-item-radio v-else-if="field.type === 'single_select'" :value="formData[field.key]"
					:options="field.options" @input="onInput(field.key, $event)" />
				<!-- 多选 -->
				<form-item-checkbox v-else-if="field.type === 'multi_select'" :value="formData[field.key]"
					:options="field.options" @input="onInput(field.key, $event)" />
				<!-- 图文编辑器 -->
				<form-item-richtext v-else-if="field.type === 'richtext_editor'" :value="formData[field.key]"
					@input="onInput(field.key, $event)" />
			</view>
		</view>
	</view>
</template>

<script>
import FormItemText from './FormItemText.vue';
import FormItemTextarea from './FormItemTextarea.vue';
import FormItemNumber from './FormItemNumber.vue';
import FormItemImage from './FormItemImage.vue';
import FormItemVideo from './FormItemVideo.vue';
import FormItemSelect from './FormItemSelect.vue';
import FormItemRadio from './FormItemRadio.vue';
import FormItemCheckbox from './FormItemCheckbox.vue';
import FormItemRichtext from './FormItemRichtext.vue';

export default {
	name: 'DynamicForm',
	components: {
		FormItemText,
		FormItemTextarea,
		FormItemNumber,
		FormItemImage,
		FormItemVideo,
		FormItemSelect,
		FormItemRadio,
		FormItemCheckbox,
		FormItemRichtext
	},
	props: {
		fields: {
			type: Array,
			default: function () {
				return [];
			}
		},
		value: {
			type: Object,
			default: function () {
				return {};
			}
		}
	},
	data: function () {
		return {
			formData: {}
		};
	},
	watch: {
		value: {
			handler: function (val) {
				this.formData = Object.assign({}, val);
			},
			immediate: true,
			deep: true
		},
		fields: {
			handler: function (val) {
				var self = this;
				if (val && val.length > 0) {
					val.forEach(function (field) {
						if (self.formData[field.key] === undefined) {
							self.$set(self.formData, field.key, self.getDefaultValue(field.type));
						}
					});
				}
			},
			immediate: true
		}
	},
	methods: {
		isUpType: function (type) {
			return type === 'image_multi' || type === 'video';
		},
		getDefaultValue: function (type) {
			if (type === 'multi_select') {
				return [];
			}
			if (type === 'image_multi') {
				return [];
			}
			return '';
		},
		onInput: function (key, val) {
			this.$set(this.formData, key, val);
			this.$emit('input', Object.assign({}, this.formData));
		},
		validate: function () {
			for (var i = 0; i < this.fields.length; i++) {
				var field = this.fields[i];
				if (field.is_required == 1) {
					var val = this.formData[field.key];
					if (val === undefined || val === null || val === '' || (Array.isArray(val) && val.length === 0)) {
						uni.showToast({
							title: '请填写' + field.label,
							icon: 'none'
						});
						return false;
					}
				}
			}
			return true;
		},
		getData: function () {
			return Object.assign({}, this.formData);
		}
	}
};
</script>

<style scoped>
.dynamic-form {
	width: 100%;
}

.form-item {
	background-color: #fff;
	padding: 24rpx;
	display: flex;
	flex-flow: row nowrap;
	justify-content: space-between;
	align-items: center;
	box-sizing: border-box;
	border-radius: 10rpx;
	margin-bottom: 24rpx;
}

.form-item-up {
	flex-flow: column nowrap;
	justify-content: space-between;
	align-items: flex-start;
}

.form-header {
	display: flex;
	align-items: center;
	margin-bottom: 16rpx;
}

.form-label {
	font-size: 28rpx;
	color: #333333;
}

.form-label.required::before {
	content: '*';
	color: #e8101e;
	margin-right: 4rpx;
}

.form-tips {
	font-size: 24rpx;
	color: #999999;
	margin-left: 10rpx;
}

.form-control {
	width: 100%;
	flex: 1;
}
</style>
