<template>
	<movable-area :style="[getAreaStyle]">
		<movable-view v-for="(item, index) in list" :animation="animation" :direction="direction" :key="item.key"
			:damping="damping" :x="item.x" :y="item.y" :disabled="longpress ? disabled : false"
			@longpress="handleLongpress" @touchstart="handleDragStart(index)" @change="handleMoving"
			@touchend="handleDragEnd" :style="[getViewStyle]" class="base-drag-wrapper"
			:class="{ active: activeIndex === index }">

			<view class="drag-item">
				<view @longpress="toggleEdit" :class="['tab-item']">
					<image v-if="item.isLock" :src="icons.lock" class="right-icon" />
					<image v-if="!item.isLock && isActiveEdit" @click="deleteTab(item)" :src="icons.edit"
						class="right-icon" />
					<image @click="clickTap(item)" :src="item.iconUrl" class="icon" />
					<view>{{ item.name }}</view>
				</view>
			</view>
		</movable-view>
	</movable-area>
</template>

<script>
	import {
		QINIU_URL
	} from '@/common/constant'
	const ICONS = {
		lock: `${QINIU_URL}FgMCTZCySvEgLYgkzU65BUR4f4Ls`,
		edit: `${QINIU_URL}Fq3V1Zi5tKH7ibTwG1nO7N96CU8m`,
		add: `${QINIU_URL}FqLEWbMe8DcnQtNz6GdDDD87ObZK`,
		placeholder: `${QINIU_URL}FpKvfFNSDbx0d9RDwyGAQdFb7Kt6`
	}

	export default {
		props: {
			column: {
				type: Number,
				default: 3
			},
			value: {
				type: Array,
				default: () => []
			},
			width: {
				type: Number,
				default: 375
			},
			height: {
				type: String,
				default: '100px'
			},
			itemKey: {
				type: String,
				required: true
			},
			itemHeight: {
				type: String,
				default: '100px'
			},
			direction: {
				type: String,
				default: 'all',
				validator: value => {
					return ['all', 'vertical', 'horizontal', 'none'].includes(value);
				}
			},
			animation: {
				type: Boolean,
				default: true
			},
			damping: {
				type: Number,
				default: 20
			},
			longpress: {
				type: Boolean,
				default: true
			}
		},
		data() {
			const MAX_TAB_LEN = 4
			return {
				QINIU_URL,
				MAX_TAB_LEN,
				icons: ICONS,
				isActiveEdit: false,
				placeholderTab: {
					name: '',
					icon: ICONS.placeholder,
					isLock: false,
					isPlaceholder: true
				},
				list: [],
				disabled: true,
				activeIndex: -1,
				moveToIndex: -1,
				oldIndex: -1,
				tempDragInfo: {
					x: '',
					y: ''
				},
				cloneList: []
			};
		},
		computed: {
			getAreaStyle() {
				const width = this.getRealWidth(this.width);
				return {
					width: width + 'px',
					height: this.height !== 'auto' ? this.height : Math.round(this.list.length / this.column) * this
						.getItemHeight + 'px'
				};
			},
			getViewStyle() {
				const {
					itemHeight,
					getItemWidth
				} = this;
				return {
					width: getItemWidth + 'px',
					height: itemHeight
				};
			},
			getItemHeight() {
				return parseFloat(this.itemHeight);
			},
			getItemWidth() {
				if (this.column === 0) return;
				const width = this.getRealWidth(this.width);
				return (parseFloat(width) / this.column).toFixed(2);
			}
		},
		methods: {
			
			clickTap(item){
				this.$emit('changClick',item)
			},
			getMovableItem(tab) {
				return this.isActiveEdit && !tab.isLock && !tab.isPlaceholder
			},
			deleteTab(tab) {
				if (tab.isLock) return
				const index = this.list.findIndex(t => t.name === tab.name)
				if (index !== -1) {
					const removedTab = this.list.splice(index, 1)[0]
					this.cloneList.splice(index, 1)
					this.initList(this.cloneList);
					const endList = this.list.map(item => this.omit(item, ['x', 'y', 'key']));
					this.$emit('end', this.list, removedTab);
				}
			},
			addPlaceholders() {
				while (this.list.length < this.MAX_TAB_LEN) {
					this.list.push({
						...this.placeholderTab
					})
				}
			},
			toggleEdit(e) {
				this.isActiveEdit = !this.isActiveEdit
				this.$emit('toggleEdit', this.isActiveEdit);
			},
			//获取实际的宽度
			getRealWidth(width) {
				let pxValue = uni.upx2px(width);
				// console.log(pxValue)
				// if (width.includes('%')) {
				// 	const windowWidth = uni.getSystemInfoSync().windowWidth;
				// 	width = windowWidth * (parseFloat(width) / 100);
				// }
				return pxValue;
			},

			initList(list = []) {
				const newList = this.deepCopy(list);
				this.list = newList.map((item, index) => {
					const [x, y] = this.getPosition(index);
					return {
						...item,
						x,
						y,
						key: Math.random() + index
					};
				});
				this.cloneList = this.deepCopy(this.list);
			},

			//长按
			handleLongpress(index) {
				this.disabled = false;
			},

			//拖拽开始
			handleDragStart(index) {
				this.activeIndex = index;
				this.oldIndex = index;
			},

			//拖拽中
			handleMoving(e) {
				if (e.detail.source !== 'touch') return;
				const {
					x,
					y
				} = e.detail;
				Object.assign(this.tempDragInfo, {
					x,
					y
				});
				const currentX = Math.floor((x + this.getItemWidth / 2) / this.getItemWidth);
				const currentY = Math.floor((y + this.getItemHeight / 2) / this.getItemHeight);

				this.moveToIndex = Math.min(currentY * this.column + currentX, this.list.length - 1);

				if (this.oldIndex !== this.moveToIndex && this.oldIndex !== -1 && this.moveToIndex !== -1) {
					const newList = this.deepCopy(this.cloneList);
					newList.splice(this.moveToIndex, 0, ...newList.splice(this.activeIndex, 1));

					this.list.forEach((item, index) => {
						if (index !== this.activeIndex) {
							const itemIndex = newList.findIndex(val => val[this.itemKey] === item[this.itemKey]);
							[item.x, item.y] = this.getPosition(itemIndex);
						}
					});
					this.oldIndex = this.moveToIndex;
				}

			},

			//获取当前的位置
			getPosition(index) {
				const x = (index % this.column) * this.getItemWidth;
				const y = Math.floor(index / this.column) * this.getItemHeight;
				return [x, y];
			},

			//拖拽结束
			handleDragEnd(e) {
				if (this.disabled) return;
				if (this.moveToIndex !== -1 && this.activeIndex !== -1 && this.moveToIndex !== this.activeIndex) {
					this.cloneList.splice(this.moveToIndex, 0, ...this.cloneList.splice(this.activeIndex, 1));
				} else {
					this.$set(this.list[this.activeIndex], 'x', this.tempDragInfo.x);
					this.$set(this.list[this.activeIndex], 'y', this.tempDragInfo.y);
				}
				this.initList(this.cloneList);
				const endList = this.list.map(item => this.omit(item, ['x', 'y', 'key']));
				this.$emit('input', endList);
				this.$emit('end', endList);
				this.activeIndex = -1;
				this.oldIndex = -1;
				this.moveToIndex = -1;
				this.disabled = true;
			},

			deepCopy(source) {
				return JSON.parse(JSON.stringify(source));
			},

			/**
			 * 排除掉obj里面的key值
			 * @param {object} obj
			 * @param {Array|string} args
			 * @returns {object}
			 */
			omit(obj, args) {

				if (!args) return obj;
				const newObj = {};
				const isString = typeof args === 'string';
				const keys = Object.keys(obj).filter(item => {
					if (isString) {
						return item !== args;
					}
					return !args.includes(item);
				});

				keys.forEach(key => {
					if (obj[key] !== undefined) newObj[key] = obj[key];
				});
				return newObj;
			}
		},
		watch: {
			value: {
				handler() {
					this.initList(this.value);
				},
				immediate: true,
				deep: true
			}
		}
	};
</script>

<style lang="scss" scoped>
	.drag-item {
		height: 100%;
		display: flex;
		align-items: center;
		justify-content: center;

		.tab-item {
			text-align: center;
			width: 100%;
			position: relative;
			margin-top: 24rpx;
			height: 100px;

			.right-icon {
				position: absolute;
				right: 20rpx;
				top: 0;
				width: 40rpx;
				height: 40rpx;
				z-index: 9;
			}

			.icon {
				width: 112rpx;
				height: 112rpx;
				margin-bottom: 20rpx;
			}

			.name {
				font-size: 28rpx;
				color: #060809;

				&.shake {
					animation: shake 0.2s ease-in-out infinite;
				}
			}
		}


	}

	.base-drag-wrapper {
		opacity: 1;
		z-index: 1;

		&.active {
			opacity: 0.7;
			transform: scale(1.3);
			z-index: 99;
		}
	}
</style>
<style lang="scss" scoped>
	@import "@/libs/css/layout.scss";

	.title {
		font-family: PingFangSC, PingFang SC;
		font-weight: 400;
		font-size: 36rpx;
		color: #060809;
		margin-bottom: 16rpx;
		padding-left: 40rpx;

		.sort-num {
			margin-left: 12rpx;
			width: 36rpx;
			font-family: Futura, Futura;
			font-size: 30rpx;
			color: #060809;
		}
	}

	.tab-item-container {
		display: flex;

		&.is-to-be-select {
			flex-wrap: wrap;
		}
	}


	.tips {
		font-size: 24rpx;
		color: #060809;
		text-align: center;
		margin-top: 32rpx;
	}

	.un-bind-btn {
		position: absolute;
		bottom: 56rpx;
		left: 50%;
		transform: translateX(-50%);
		width: 93%;
		padding: 24rpx;
		text-align: center;
		background: #E4E7EC;
		border-radius: 40rpx;
		font-family: PingFangSC, PingFang SC;
		font-weight: bold;
		font-size: 32rpx;
		color: #060809;

		&:active {
			opacity: .7;
		}
	}
</style>