<template>  
	<view class="uni-stat__select" :class="multiple?'multiple':''">
		<span v-if="label" class="uni-label-text hide-on-phone">{{label + '：'}}</span>
		<view class="uni-stat-box" :class="{'uni-stat__actived': current}">
			<view class="uni-select" :class="{'uni-select--disabled':disabled}">
				<view class="uni-select__input-box" @click="toggleSelector"> 
					<view>
						<view v-if="multiple" class="uni-select__flex">
							<view v-for="(item,index) in current" :key="item" class="uni-select__flex-item">
								<view class="flex">{{item}}<view @click.stop="clearTag(index)"><uni-icons type="ant-design:close-outlined" custom-prefix="antfont" color="#c0c4cc" size="12" /></view></view>
							</view> 
							<input class="uni-select__input-text" v-model="keyword" :placeholder="current.length>0 ?'':(placeholder||'请选择')"
							placeholder-class="uni-select__input-placeholder" :focus="showSelector" @input="searchData" @blur="onBlur" @focus="onFocus"/>
						</view>
						<view v-else-if="current && !multiple && !showSelector" class="uni-select__input-text">{{current}}</view>				
						<input v-if="!multiple" class="uni-select__input-text position" v-model="keyword" :placeholder="current ?'':(placeholder||'请选择')"
						placeholder-class="uni-select__input-placeholder" :focus="showSelector" @input="searchData" @blur="onBlur" @focus="onFocus"/>
					</view>
					 
					<view class="close-btn" v-if="(current&&!multiple || current.length>0&&multiple) && !disabled" @click.stop="clearVal" ><uni-icons type="clear" color="#c0c4cc" size="24"/></view>
					<uni-icons v-else-if="!multiple" :type="showSelector? 'top' : 'bottom'" size="14" color="#999" />
				</view>
				<view class="uni-select--mask" v-if="showSelector" @click="toggleSelector" />
				<view class="uni-select__selector" v-show="showSelector&&loadding">
					<view class="uni-popper__arrow"></view>
					<scroll-view scroll-y="true" class="uni-select__selector-scroll">
						<view class="uni-select__selector-empty" @click="toggleSelector" v-if="mixinDatacomResData.length === 0">
							<text>{{emptyTips}}</text>
						</view>
						<node-item v-else :value="dataValue" :multiple="multiple" :mixinDatacomResData="mixinDatacomResData" :level="1" @initchange="handleinit" @change="handleChange"></node-item>
					</scroll-view>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	import {getTreeInfo} from '@/common/api/system/dictionary/index.js';
	import {changeApiOptions } from '@/common/api/magic-api/useApiRequest.js';
	import NodeItem from './node-item.vue'
	export default {
			name: "uni-select-tree", 
			data() {
				return { 
					emptyTips: '无数据',
					dataValue:this.treeConfig.isMultiple?[]:'',
					current:this.treeConfig.isMultiple?[]:'',
					mixinDatacomResData: [], 
					loadding:true, 
					showSelector:false,
					keyword:'',
					channels:[],
					apiKey:'value',
					apiLabel:'label'
				};
			},
			components:{
				NodeItem
			},
			props: { 
				value: {
					type: [String, Number],
					default: ''
				},
				modelValue: {
					type: [String, Number],
					default: ''
				},
				label: {
					type: String,
					default: ''
				}, 
				childIcon: {
					type: String,
					default: ''
				},
	      disabled: {
					type: Boolean,
					default: false
				},
				parentIcon:{
					type: String,
					default: ''
				},
				treeConfig:{
					type: Object,
					default(){
						return {}
					}
				},  
				placeholder: String,
			},
			async created() {
				this.loadding=false;
				if(this.treeConfig?.id) { 
					let formState = await getTreeInfo({id:this.treeConfig.id});
					let config = JSON.parse(formState.data.config);
					if (formState.data.type == 1) { 
						let data  = [];
						config.staticData.forEach((element, index) => {
							let res = this.getItem(element, index, element.value);
							data.push(res);
						});
						this.channels=data;
						this.mixinDatacomResData = this.getDataList();
					} else {
						this.apiLabel=config.apiData.apiColumns[0].dataIndex
						this.apiKey=config.apiData.apiColumns[1].dataIndex
						let data  = [];
						let apiData = await changeApiOptions(config.apiData.apiConfig)  
						apiData.data.data.forEach((element, index) => {
							let res = this.getItem(element, index, element[this.apiKey]);
							data.push(res);
						});
						this.channels=data;
						this.mixinDatacomResData  = this.getDataList();
					}
				} 
				this.initData()
				this.loadding=true;
			},
			computed: { 
				multiple(){
					return this.treeConfig.isMultiple
				}
			},
			watch: { 
				 value(){
					 this.initData()
				 },
				 modelValue(){
					 this.initData()
				 }
			},
			methods: { 
				initData() {
					let defValue = '';
					this.dataValue =this.multiple?[]:''; 
					if (this.value || this.modelValue) {
						defValue = this.value || this.modelValue
					}
					if(defValue){
						this.dataValue = this.multiple ?defValue.split(','):defValue 
						this.current=this.multiple?defValue.split(','):defValue 
					}else{
						this.current=this.multiple?[]:''
					}
				},
				getDataList() {
					// 解除引用关系，破坏原引用关系，避免污染源数据 
					return JSON.parse(JSON.stringify(this.channels)) 
				},
				getItem(item, index, rowKey)  {
					let childrenArr  = [];
					if (item.children.length > 0) { 
						item.children.forEach((element, index2) => {
							let key = index + '---' + index2;
							let rowKey2 = rowKey + '---' + element[this.apiKey];
							childrenArr.push(this.getItem(element, key, rowKey2));
						});
					}  
					return { 
						label: item[this.apiLabel],
						index: index,
						key: rowKey, 
						collpse:item.children.length > 0?false:undefined,
						children: childrenArr,
					};
				},
				handleinit(item) { 
					if(this.multiple){ 
						if(!this.current.includes(item.label)) this.current.push(item.label)   
					}else{
						this.current = item.label; 
					}
				},
				handleChange(item) { 
					this.showSelector = false
					if(this.multiple){
						if(this.dataValue.includes(item.key)){
							let idx=this.dataValue.findIndex(o=>o==item.key)
							if(idx>=0) this.clearTag(idx)
						}else{
							this.current.push(item.label)
							this.dataValue.push(item.key)
							this.change(this.dataValue.join(','), item) 
						}
					}else{
						this.current = item.label;
						this.change(item.key, item)
					}
				},
				change(val,item) { 
					// TODO 兼容 vue2
					this.$emit("input", val);
					// TODO　兼容　vue3
					this.$emit("update:modelValue", val);
					this.$emit('change',val, item)
				},
				clearVal() {
					this.current=''
					this.dataValue=''
					this.change('') 
				}, 
				toggleSelector() {
					if (this.disabled) {
						return
					}
					this.showSelector = !this.showSelector
				},
				clearTag(idx){
					this.current.splice(idx,1)
					this.dataValue.splice(idx,1)
					this.change(this.dataValue.join(',')) 
				},
				searchData(event) {
					let value = event.detail.value; 
					this.mixinDatacomResData =this.getDataList()
					if(value){
						this.mixinDatacomResData =this.findVal(this.mixinDatacomResData,value) 
					} 
				}, 
				onBlur(){
					this.keyword ='';   
				},
				onFocus(){
					this.mixinDatacomResData =this.getDataList() 
				},
				findVal(arr,val){
					let newArr=[];
					arr.forEach(o=>{
						if(o.children?.length>0){
							let child=this.findVal(o.children,val)
							let obj={...o}
							if(child?.length>0){
								newArr.push(obj)
							}
						}else{
							if(o.label.includes(val)){
								newArr.push(o)
							}
						}
					})
					return newArr
				}
			}
		}
</script>

<style  lang="scss">
	$uni-base-color: #6a6a6a !default;
	$uni-main-color: #333 !default;
	$uni-secondary-color: #909399 !default;
	$uni-border-3: #e5e5e5;
	.relative{
		position: relative;
	}
	.checked{
		position: absolute;
		top: 5px;
		right: 10px;
	}
	.flex{
		display:flex
	}
	/* #ifndef APP-NVUE */
	@media screen and (max-width: 500px) {
		.hide-on-phone {
			display: none;
		}
	}
	
	/* #endif */
	.uni-stat__select {
		display: flex;
		align-items: center; 
		cursor: pointer;
		width: 100%;
		flex: 1;
		box-sizing: border-box;
	}
	
	.uni-stat-box {
		width: 100%;
		flex: 1;
	}
	
	.uni-stat__actived {
		width: 100%;
		flex: 1; 
	}
	
	.uni-label-text {
		font-size: 14px;
		font-weight: bold;
		color: $uni-base-color;
		margin: auto 0;
		margin-right: 5px;
	}
	
	.uni-select {
		font-size: 14px;
		border: 1px solid $uni-border-3;
		box-sizing: border-box;
		border-radius: 4px;
		padding: 0 5px;
		padding-left: 10px;
		position: relative;
		/* #ifndef APP-NVUE */
		display: flex;
		user-select: none;
		/* #endif */
		flex-direction: row;
		align-items: center;
		border-bottom: solid 1px $uni-border-3;
		width: 100%;
		flex: 1;
		height: 35px;
	
		&--disabled {
			background-color: #f5f7fa;
			cursor: not-allowed;
		}
	}
	.multiple{
		.uni-select{
			padding: 0 4px;
		}
		.uni-select,
		.uni-select__input-box{
			height: auto;
			min-height: 35px;
		} 
		.uni-select__input-placeholder{
			padding-left: 6px;
		}
	}
	
	.uni-select__input-box {
		height: 35px;
		position: relative;
		/* #ifndef APP-NVUE */
		display: flex;
		/* #endif */
		flex: 1;
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
	}
	
	.uni-select__input {
		flex: 1;
		font-size: 14px;
		height: 22px;
		line-height: 22px;
	}
 
	.uni-select__selector {
		/* #ifndef APP-NVUE */
		box-sizing: border-box;
		/* #endif */
		position: absolute;
		top: calc(100% + 12px);
		left: 0;
		width: 100%;
		background-color: #FFFFFF;
		border: 1px solid #EBEEF5;
		border-radius: 6px;
		box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
		z-index: 4;
		padding: 4px 0;
	}
	
	.uni-select__selector-scroll {
		/* #ifndef APP-NVUE */
		max-height: 200px;
		box-sizing: border-box;
		/* #endif */
	}
	
	.uni-select__selector-empty,
	.uni-select__selector-item {
		/* #ifndef APP-NVUE */
		display: flex;
		cursor: pointer;
		/* #endif */
		line-height: 35px;
		font-size: 14px;
		text-align: center;
		/* border-bottom: solid 1px $uni-border-3; */
		padding: 0px 10px;
	}
	
	.uni-select__selector-item:hover {
		background-color: #f9f9f9;
	}
	
	.uni-select__selector-empty:last-child,
	.uni-select__selector-item:last-child {
		/* #ifndef APP-NVUE */
		border-bottom: none;
		/* #endif */
	}
	
	.uni-select__selector__disabled {
		opacity: 0.4;
		cursor: default;
	}
	
	/* picker 弹出层通用的指示小三角 */
	.uni-popper__arrow,
	.uni-popper__arrow::after {
		position: absolute;
		display: block;
		width: 0;
		height: 0;
		border-color: transparent;
		border-style: solid;
		border-width: 6px;
	}
	
	.uni-popper__arrow {
		filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
		top: -6px;
		left: 10%;
		margin-right: 3px;
		border-top-width: 0;
		border-bottom-color: #EBEEF5;
	}
	
	.uni-popper__arrow::after {
		content: " ";
		top: 1px;
		margin-left: -6px;
		border-top-width: 0;
		border-bottom-color: #fff;
	}
	 
	.uni-select__input-text {
		display: inline;
		flex: 1;
		height: 30px;
		line-height: 30px;
		width: 100%;
		color: $uni-main-color;
		white-space: nowrap;
		text-overflow: ellipsis;
		-o-text-overflow: ellipsis;
		overflow: hidden;
		&.position{
			position: absolute;
			left: 0;
			top:2.5px;
			width: calc(100% - 30px);
		}
	}
	.uni-select__flex{
		display: flex;
		flex-wrap: wrap;
		&-item{
			background: rgba(0, 0, 0, 0.06);
			padding: 4px;
			border-radius: 4px;
			margin-right: 4px;
			margin-top: 2px;
			margin-bottom: 2px;
		}
	}
	
	.uni-select__input-placeholder {
		color: $uni-base-color;
		font-size: 12px;
	}
	
	.uni-select--mask {
		position: fixed;
		top: 0;
		bottom: 0;
		right: 0;
		left: 0;
	}
	.close-btn{
		position: absolute;
		top:1px;
		bottom: 1px;
		right:0;
		z-index: 3;
		background: #fff;
		display: flex;
		align-items: center;
	}
</style>