<template>
	<draggable :list="data.fields" :scroll="true" animation="200" item-key="id" class="w100 h100"
			   :group="group" @update:list="fields = $event" @add="addComp" @sort="sortComp"
			   ghostClass="ghostClass" :class="{empty: data.fields.length === 0, layout: isRow}">
		<template #item="{ element, index }">
			<el-col :span="element.span || 24" class="col">
				<el-row v-if="element.name === 'layout'" class="item row" :class="{'active': field.element.id===element.id}"
						@click.stop="clickComp(element)" v-bind="element.props">
					<span class="name">{{ element.field_name }}</span>
					<drag :data="getChildrenData(element.children)" :field="field" :name="element.field_name" :is-row="true"/>
				</el-row>
				<item v-else class="item" :class="{'active': field.element.id===element.id}" :field="element"
					  @click.stop="clickComp(element)"/>
				<div v-if="field.element.id===element.id" class="tools-box">
					<el-icon size="22" class="icon-box remove" @click.stop="delComp(index)">
						<component :is="'pi-icon-shan-chu'"/>
					</el-icon>
					<el-icon size="20" class="icon-box copy ml5" @click.stop="copyComp(index)">
						<component :is="'pi-icon-fu-zhi'"/>
					</el-icon>
				</div>
			</el-col>
		</template>
	</draggable>
</template>

<script setup>
import draggable from 'vuedraggable'
import {nextTick, reactive} from "vue"
import item from "./item.vue"
import drag from "./drag.vue"
import tools from "@/utils/tools"
import FormBuild from "./formBuild"

const props = defineProps({
	data: {type: FormBuild, default: {}},
	field: {type: Object, default: {}},
	curKey: {type: String, default: ''},
	isRow: {type: Boolean, default: false},
	name: {type: String, default: 'page'}
})

const group = {name: props.name, pull: true, put: true}

// 排序
function sortComp(e) {
	let element = props.data.fields[e.newIndex]
	if (element) {
		props.field.element = element
	}
}

// 添加项时
function addComp(e) {
	let element = props.data.fields[e.newIndex]
	if (props.isRow) {
		element.span = 12
	}
	props.field.element = element
}

// 选中项
function clickComp(element) {
	if (props.field.element.id === element.id) {
		return;
	}
	props.field.element = element
}

// 删除字段
function delComp(index) {
	nextTick(() => {
		// 原数组长度
		const len = props.data.fields.length
		props.data.fields.splice(index, 1);
		let i = 0;
		if (len > 1) {
			if (index === 0) {
				i = 0;
			} else if (index === len - 1) {
				i = index - 1
			} else {
				i = index
			}
		}
		props.field.element = props.data.fields[i] || {}
	})
}

function copyComp(index) {
	nextTick(() => {
		// 复制当前元素到尾部
		const tmp = JSON.parse(JSON.stringify(props.data.fields[index]))
		tmp.field_name = increaseNum(tmp.field_name)
		tmp.id = increaseNum(tmp.id)
		props.data.config.counter++
		props.data.fields.push(tmp)
		// 将复制的元素移动到当前元素下边
		tools.array.zIndexTo(props.data.fields, props.data.fields.length - 1, index + 1)
		props.field.element = props.data.fields[index + 1]
	})
}

function increaseNum(str) {
	return str.replace(/(\d+)(?!.*\d)/, () => {
		return props.data.config.counter.toString();
	});
}

function getChildrenData(_data) {
	const _form = reactive(new FormBuild())
	_form.initData(props.data.config, _data)
	return _form
}
</script>

<style lang="scss" scoped>
:deep(.ghostClass) {
	.comp {
		display: none;
	}

	.tips {
		padding: 10px;
		border: 1px dashed var(--el-color-primary);
		text-align: center;
		color: var(--el-color-primary);
	}
}

:deep(.el-form-item,.el-form-item--default) {
	margin-bottom: 0 !important;
}

.w100 {
	width: 100%;
}

.h100 {
	height: 100%;
}

.empty {
	padding: 40px 0;
	display: block !important;
}

.layout {
	display: contents;
}

.active {
	border: 1px dashed #787be8 !important;
	color: #787be8;
}

.col {
	position: relative;
}

.item {
	padding: 12px 10px;
	border: 1px;
	border-radius: 3px;
	position: relative;
	margin-bottom: 18px !important;
}

.row {
	border: 1px dashed #c1c1c1;
	padding: 20px 12px;

	.name {
		position: absolute;
		top: 0;
		left: 0;
		font-size: 12px;
		color: #bbb;
		display: inline-block;
		padding: 0 6px;
	}
}

.tools-box {
	position: absolute;
	right: 10px;
	top: -16px;
	display: inline-block;
	padding: 5px;
	border-radius: 4px;

	.icon-box {
		cursor: pointer;
	}

	.icon-box.remove {
		color: var(--el-color-danger);
	}

	.icon-box.copy {
		color: var(--el-color-primary);
	}

	.ml5 {
		margin-left: 5px;
	}

	.disabled {
		cursor: no-drop;
		color: #c3c3c3;
	}
}
</style>
