<template>
	<view>
		<!-- 结果列表 -->
		<view>
			<u-tag v-for="item in checkedOrgs" :key="item.name" :text="item.name" class="tag" />
			<u-tag v-for="item in checkedUsers" :key="item.realname" :text="item.realname" class="tag" type="success" />
			<view style="margin-left: 10px; color: #2979FF; display: inline-block;" @click="visible = true">
				{{ checkedOrgs.length || checkedUsers.length ? '重选' : '添加' }}
			</view>
		</view>
		<!-- 弹出 -->
		<u-popup v-model="visible" mode="bottom" @open="openPopup">
			<view id="top" style="padding-top: 5px;">
				<!-- 操作按钮 -->
				<view class="division" style="display: flex;padding-bottom: 5px;">
					<u-button size="mini" plain @click="cancel">取消</u-button>
					<view style="position: absolute; right: 10px;">
						<u-button size="mini" plain type="primary" @click="submit">
							确定（{{ checkedOrgs.length + checkedUsers.length }}）
						</u-button>
					</view>
				</view>
				<!-- 用户模糊搜索 -->
				<view v-if="type !== 'org'" style="padding: 0 10px;">
					<u-form-item left-icon="search">
						<u-input v-model="searchValue" clearable placeholder="搜索用户" @input="search" />
					</u-form-item>
				</view>
				<!-- 已选列表 -->
				<view class="division">
					<u-tag v-for="(item, index) in checkedOrgs" :key="item.name" :text="item.name" closeable class="tag"
						@close="remove(checkedOrgs,index)" />
					<u-tag v-for="(item, index)  in checkedUsers" :key="item.realname" :text="item.realname" closeable
						class="tag" type="success" @close="remove(checkedUsers,index)" />
				</view>
				<!-- 面包屑 -->
				<view class="division" v-if="!searchValue">
					<text v-for="(item, index) in breadList" :key="index" @click="goOrg(item)">
						<text v-if="index > 0">{{' '}} / {{' '}}</text>
						<text :style="{color: activateBread(index) ? '' : '#3370ff'}">{{ item.name }}</text>
					</text>
				</view>
			</view>
			<scroll-view :style="{height: `${rollHeight}px`}" scroll-y @scrolltolower="handleOnreachBottom">
				<!-- 组织架构 -->
				<view v-if="!searchValue" v-for="item in orgList" :key="item[orgPrimaryKey]" style="display: flex;">
					<view @click="isCheckedOrg(item)" style="margin-left: 10px;">
						<radio v-if="type !== 'user'" :value="item[orgPrimaryKey]" :checked="item._checked || false" />
						<u-icon name="list" />{{' '}} {{ item.name }}
					</view>
					<!-- 下级按钮 -->
					<view style="position: absolute; right: 10px; padding-left: 15px;" :key="item.loading"
						@click="nextLayer(item)">
						<u-icon name="arrow-right" />
					</view>
				</view>
				<!-- 人员 -->
				<view v-for="item in list" :key="item[primaryKey]">
					<view @click="isCheckedUser(item)" style="margin-left: 10px;">
						<radio :value="item[primaryKey]" :checked="item._checked || false" />
						<u-icon name="account-fill" />{{' '}} {{ item.realname }}
					</view>
				</view>
				<u-empty v-if="isEmpty">
					<u-button slot="bottom" size="mini" plain @click="callback">返回上级</u-button>
				</u-empty>
				<u-loadmore v-else-if="type !== 'org'" :status="status" :loadText='loadText' margin-top="24"
					margin-bottom="24" />
			</scroll-view>
		</u-popup>
	</view>
</template>

<script>
	import list from '@/mixins/list'
	import {
		dibootApi
	} from '@/utils/dibootApi'
	export default {
		name: "di-person-picker",
		mixins: [list],
		props: {
			// 类型
			type: {
				// 用户选择、组织机构选择、人员架构混选
				type: 'user' | 'org' | 'default',
				default: 'default'
			},
			// 初始值 （type为 'user' | 'org' 时应，初始值应为对应的对象列表；type为 'default' 时，初始值应为 { orgs?: 组织对象列表, users?: 用户对象列表 }  ）
			initValue: {
				type: Array | Object,
				default: () => []
			}
		},
		data() {
			return {
				visible: false,
				confirmLoading: false,
				getListFromMixin: false,
				baseApi: '/workflow/userGroup',
				listApi: 'userList',
				queryParam: {
					orgId: '0'
				},
				oldQueryParam: null,
				searchValue: '',
				orgPrimaryKey: 'id',
				breadList: [{
					id: '0',
					name: '组织结构',
					children: []
				}],
				checkedOrgs: [],
				checkedUsers: [],
				oldCheckedOrgs: [],
				oldCkedUsers: [],
				topHeight: 50,
				windowHeight: 500
			};
		},
		created() {
			switch (this.type) {
				case 'user':
					this.checkedUsers = this.initValue
					break
				case 'org':
					this.checkedOrgs = this.initValue
					break
				default:
					this.checkedOrgs = this.initValue.orgs || []
					this.checkedUsers = this.initValue.users || []
			}

			// 获取组织数据
			dibootApi.get(`${this.baseApi}/orgTree`).then(res => {
				if (res.ok) {
					this.breadList[0].children = this.dataFilter(res.data, this.checkedOrgs)
				} else {
					this.showToast(res.msg)
				}
			})

			// 获取人员信息
			this.type !== 'org' && this.getList(true)

			// 获取屏幕可用高度
			let self = this;
			uni.getSystemInfo({
				success: function(res) {
					self.windowHeight = res.windowHeight
				}
			});
		},
		computed: {
			// 滚动区域高度
			rollHeight() {
				return this.windowHeight - this.topHeight
			},
			orgList() {
				return this.breadList[this.breadList.length - 1].children || []
			},
			isEmpty() {
				return this.orgList.length + ((this.list || []).length || 0) === 0
			}
		},
		watch: {
			visible(value) {
				value && this.calcHeight()
			}
		},
		methods: {
			async calcHeight() {
				await this.$nextTick();
				uni.createSelectorQuery().in(this).select('#top').boundingClientRect(data => {
					this.topHeight = data.height
				}).exec()
			},
			openPopup() {
				this.oldCheckedOrgs = this.$u.deepClone(this.checkedOrgs)
				this.oldCheckedUsers = this.$u.deepClone(this.checkedUsers)
			},
			activateBread(index) {
				return this.breadList.length - 1 === index
			},
			isCheckedOrg(item) {
				if (this.type === 'user') return
				item._checked = !item._checked
				if (item._checked)
					this.checkedOrgs.push(item)
				else
					this.checkedOrgs.splice(this.checkedOrgs.indexOf(item), 1);
				this.calcHeight()
			},
			isCheckedUser(item) {
				item._checked = !item._checked
				if (item._checked)
					this.checkedUsers.push(item)
				else
					this.checkedUsers.splice(this.checkedUsers.indexOf(item), 1);
				this.calcHeight()
			},
			async nextLayer(item) {
				item.loading = true
				this.$forceUpdate()
				this.queryParam.orgId = item[this.orgPrimaryKey]
				this.type !== 'org' && await this.getList(true)
				this.breadList.push(item)
				item.loading = false
				this.$forceUpdate()
				this.calcHeight()
			},
			goOrg(item) {
				this.breadList.splice(this.breadList.indexOf(item) + 1)
				if (this.type !== 'org') {
					this.list = []
					this.queryParam.orgId = item[this.orgPrimaryKey]
					this.getList(true)
				}
				this.calcHeight()
			},
			callback() {
				this.goOrg(this.breadList[this.breadList.length - 2])
			},
			remove(list, index) {
				list.splice(index, 1)[0]._checked = false
				this.calcHeight()
			},
			submit() {
				switch (this.type) {
					case 'user':
						const userIds = this.checkedUsers.map(e => e[this.primaryKey])
						this.$emit('input', userIds)
						this.$emit('change', userIds)
						break
					case 'org':
						const orgIds = this.checkedOrgs.map(e => e[this.orgPrimaryKey])
						this.$emit('input', orgIds)
						this.$emit('change', orgIds)
						break
					default:
						const data = {
							orgs: this.checkedOrgs,
							users: this.checkedUsers
						}
						this.$emit('input', data)
						this.$emit('change', data)
				}
				this.visible = false
			},
			cancel() {
				this.visible = false
				this.checkedOrgs = this.$u.deepClone(this.oldCheckedOrgs)
				this.checkedUsers = this.$u.deepClone(this.oldCheckedUsers)
			},
			// 数据过滤（用于回显选项）
			dataFilter(data, list) {
				if (list.length === 0) return data
				data.forEach(item => {
					const index = list.findIndex(e => e[this.primaryKey] === item[this.primaryKey])
					index >= 0 && (item._checked = true) && list.splice(index, 1, item);
					item.children != null && this.dataFilter(item.children, list)
				});
				this.$forceUpdate()
				return data
			},
			/**
			 * 获取数据列表
			 */
			async getList(replace = false) {
				try {
					this.status = 'loading'
					const res = await dibootApi.get(this.listApi ? `${this.baseApi}/${this.listApi}` :
						`${this.baseApi}/list`, this.queryParam)
					if (res.code === 0) {
						const data = this.dataFilter(res.data, this.checkedUsers)
						this.list = replace ? data : this.list.concat(data)
						this.page = res.page
						this.page.pageIndex++
					} else {
						this.showToast(res.msg)
					}
				} catch (e) {
					//TODO handle the exception
				} finally {
					this.triggered = false
					this.status = (this.list || []).length == this.page.totalCount ? 'nomore' : 'loadmore'
				}
			},
			// 搜索用户（附带防抖）
			search(value) {
				clearTimeout(this.searchDebounce);
				this.searchDebounce = setTimeout(() => {
					if (value) {
						if (this.oldQueryParam == null) this.oldQueryParam = this.$u.deepClone(this.queryParam)
						this.queryParam = {
							realname: value
						}
						this.getList(true)
					} else {
						this.queryParam = this.$u.deepClone(this.oldQueryParam)
						this.oldQueryParam = null
						this.handlePullDownRefresh()
					}
					this.$forceUpdate()
				}, 300)
			}
		}
	}
</script>

<style scoped>
	.division {
		padding-left: 10px;
		border-bottom-style: solid;
		border-width: 1px;
		border-color: #cccccc;
	}

	.tag+.tag {
		margin-left: 5px;
	}
</style>
