<template>
	<view class="tui-drag__wrap" :list="list" :style="{ height: getHeight + 'rpx' }" :basedata="baseData" :change:list="handler.listObserver"
	 :change:basedata="handler.baseDataObserver">
		<!-- #ifdef MP-WEIXIN -->
		<view class="tui-drag__item" v-for="(item, index) in list" :key="item.id" :data-index="index" :style="{ width: 100 / columns + '%', height: itemHeight + 'rpx' }"
		 @longpress="handler.longPress" :data-basedata="baseData" :data-edit="isEdit" @touchstart="handler.touchStart"
		 :catch:touchmove="dragging?handler.touchMove:''" :catch:touchend="dragging?handler.touchEnd:''">
			<slot :entity="item.data" :fixed="item.fixed" :index="index" :height="itemHeight" :isEdit="isEdit"></slot>
		</view>
		<!-- #endif -->

		<!-- #ifndef MP-WEIXIN -->
		<view class="tui-drag__item" v-for="(item, index) in list" :key="item.id" :data-index="index" :style="{ width: 100 / columns + '%', height: itemHeight + 'rpx' }"
		 @longpress="handler.longPress" :data-basedata="baseData" :data-edit="isEdit" @touchstart="handler.touchStart"
		 @touchmove="handler.touchMove" @touchend="handler.touchEnd">
			<slot :entity="item.data" :fixed="item.fixed" :index="index" :height="itemHeight" :isEdit="isEdit"></slot>
		</view>
		<!-- #endif -->
	</view>
</template>
<script src="./tui-drag.wxs" lang="wxs" module="handler"></script>
<script>
	export default {
		name:'tuiDrag',
		props: {

			/*
			  数据源
			  约定属性 fixed（是否固定，表示此内容不可拖拽，也不可换位置）
			*/
			listData: {
				type: Array,
				default () {
					return [];
				}
			},
			// 列数
			columns: {
				type: Number,
				default: 3
			},
			// 顶部固定高度
			topSize: {
				type: Number,
				default: 0
			},
			// 底部固定高度
			bottomSize: {
				type: Number,
				default: 0
			},
			// 每个 item 高度, 用于计算 item-wrap 高度 rpx
			itemHeight: {
				type: Number,
				default: 0
			},
			// 页面滚动高度
			scrollTop: {
				type: Number,
				default: 0
			},
			//编辑状态：为true时才可拖拽
			isEdit: {
				type: Boolean,
				default: true
			}
		},
		data() {
			return {
				/* 未渲染数据 */
				baseData: {},
				platform: '', // 平台信息
				listWxs: [], // wxs 传回的最新 list 数据
				rows: 4, // 行数

				/* 渲染数据 */
				list: [], // 渲染数据列
				dragging: false
			};
		},
		watch: {
			listData(val){
				this.list = []
				setTimeout(() => {
					this.init()
				}, 0);
			},
			columns(val) {
				this.list = []
				setTimeout(() => {
					this.init()
				}, 0);
			}
		},
		computed: {
			getHeight() {
				return this.rows * this.itemHeight;
			}
		},
		mounted() {
			this.init();
		},
		methods: {
			vibrate() {
				// #ifndef H5
				if (this.platform !== 'devtools') uni.vibrateShort();
				// #endif
			},
			pageScroll(e) {
				uni.pageScrollTo({
					scrollTop: e.scrollTop,
					duration:0
				});
			},
			drag(e) {
				this.dragging = e.dragging;
			},
			listChange(e) {
				this.listWxs = e.list;
			},
			itemClick(e) {
				let index = e.currentTarget.dataset.index;
				let item = this.listWxs[index];

				this.$emit('click', {
					key: item.realKey,
					data: item.data,
					extra: e.detail
				});
			},
			unique(n = 6) {
				let rnd = '';
				for (let i = 0; i < n; i++) rnd += Math.floor(Math.random() * 10);
				return 'tui_' + new Date().getTime() + rnd;
			},
			/**
			 *  初始化获取 dom 信息
			 */
			initDom() {
				let {
					windowWidth,
					windowHeight,
					platform
				} = uni.getSystemInfoSync();
				let remScale = (windowWidth || 375) / 375;

				this.platform = platform;

				let baseData = {};
				baseData.windowHeight = windowHeight;
				baseData.realTopSize = (this.topSize * remScale) / 2;
				baseData.realBottomSize = (this.bottomSize * remScale) / 2;
				baseData.columns = this.columns;
				baseData.rows = this.rows;

				const query = uni.createSelectorQuery().in(this);
				query.select('.tui-drag__item').boundingClientRect();
				query.select('.tui-drag__wrap').boundingClientRect();
				query.exec(res => {
					if (res && res.length > 0 && res[0] && res[0].width) {
						baseData.itemWidth = res[0].width;
						baseData.itemHeight = res[0].height;
						baseData.wrapLeft = res[1].left;
						baseData.wrapTop = res[1].top + this.scrollTop;
						this.dragging = false;
						this.baseData = baseData;
					}
				});
			},
			/**
			 *  初始化函数
			 *  {listData, topSize, bottomSize, itemHeight} 参数改变需要手动调用初始化方法
			 */
			init() {
				// 初始必须为true以绑定wxs中的函数,
				this.dragging = true;
				let delItem = item => {
					let obj={...item}
					let fixed = obj.fixed || false;
					delete obj["fixed"];
					return {
						id: this.unique(),
						fixed: fixed,
						data: { 
							...obj
						}
					};
				};
				let listData = this.listData,
					_list = [];
				// 遍历数据源增加扩展项, 以用作排序使用
				listData.forEach((item, index) => {
					_list.push(delItem(item));
				});

				let i = 0,
					columns = this.columns;
				let list = (_list || []).map((item, index) => {
					item.realKey = i++; // 真实顺序
					item.sortKey = index; // 整体顺序
					item.tranX = `${(item.sortKey % columns) * 100}%`;
					item.tranY = `${Math.floor(item.sortKey / columns) * 100}%`;
					return item;
				});
				this.rows = Math.ceil(list.length / columns);
				this.list = list;
				console.log(list)
				this.listWxs = list;
				if (list.length === 0) return;

				// 异步加载数据时候, 延迟执行 initDom 方法, 防止无法正确获取 dom 信息
				setTimeout(() => this.initDom(), 1000);
			},
			sort_end(e) {
				this.$emit('sortend', {
					listData: e.listData
				});
			},
			change(e) {
				this.$emit('change', {
					listData: e.listData
				});
			}
		}
	};
</script>

<style scoped>
	.tui-drag__wrap {
		position: relative;
	}

	.tui-drag__wrap .tui-drag__item {
		position: absolute;
		z-index: 2;
		top: 0;
		left: 0;
	}

	.tui-drag__transition {
		transition: transform 0.35s !important;
	}

	.tui-drag__wrap .tui-drag__current {
		z-index: 10 !important;
	}

	.tui-drag__wrap .tui-drag__fixed {
		z-index: 1 !important;
	}
</style>
