<template>
	<scroll-view class="mini-spec" scroll-y="true" show-scrollbar="false">
		<view class="spec-item" v-for="(item,i) in demoData" :key="i">
			<view class="spec-title">{{ item }}</view>
			<!--多个选项-->
			<view class="spec-list">
				<view class="spec-value" v-for="(sku,index) in showSpec[item]" :key="index" @tap="chooseSpec(item, sku)"
					:class="[{active:selectedArr[item] === sku}]">
					<!-- wx:class="{{ { theme_main_bk:selectedArr[item] === sku , no:filters.noActive(notSelectable,sku)} }}" -->
					{{ sku }}
				</view>
			</view>
		</view>
	</scroll-view>
</template>
<script lang='ts'>
	import {
		Component,
		Prop,
		Watch,
		Emit,
		Vue
	} from 'vue-property-decorator';
	@Component({})
	export default class MiniSpec extends Vue {
		proContent: any = null;
		showSpec: any = {}; // 用于展示的规格选项
		reSku: Array < any >= []; // 重组后的sku-->[{path: "三人份-BT辣-羊肉-炒",sku: "000UNLI4"}]
		selectedArr: Array < any >= []; // 所有选中的规格与key的组合
		notSelectable: Array < any >= [];
		allPath: any = {};
		keys: string = ""; // 所有可选属性行
		selectedCache: Array < any >= []; // 已选中的缓存
		spliter: string = "-"; // 分隔符
		curtSelect: string = ""; // 当前选中的规格

		@Prop({
			default: {}
		}) specData: any;
		@Prop({
			default: false
		}) sellOut!: boolean;

		get demoData() {
			return Object.keys(this.showSpec) || [];
		}

		@Watch('specData', {
			deep: true,
			immediate: true,
		})
		specDataChange(val: any) {
			this.proContent = val;
			this.proContent.skuList.length && this.initData();
		}


		initData() {
			// 售罄不执行
			if (this.sellOut) {
				return;
			}
			//proContent未准备好 不执行
			if (!this.proContent) return;
			// 单规格未设置'默认'规格时，不执行
			if (!this.proContent.skuList[0].attrs) return;
			// 暂时不过滤库存为0 的商品
			// this.filterNullSku();

			// 过滤 keys 可选的规格名称 ['款式','口味']
			this.keys = this.filterKeys(this.proContent);
			// console.log('this.keys------>', this.keys);

			// 展示给用户的规格选项
			this.showSpec = this.getshowSpec(this.proContent.skuList);
			// console.log("this.showSpec------>", this.showSpec);

			// this.reSku ==》[{path:'大-不辣',sku:111},{path:'大-辣',sku:111}]
			this.reSku = this.combineAttr(this.proContent.skuList);
			// console.log('this.reSku------>', this.reSku)

			this.buildResult(this.reSku);

			// 只有一个sku时默认选中所有选项
			const oneSku = this.proContent.skuList.length === 1;
			// 开局选中
			let skuItem = this.proContent.skuList;
			console.log('选中的规格', this.selectedArr)
			for (let k in this.selectedArr) {
				skuItem[0].attrs.map((sku: any) => {
					if (sku.keyName == k) {
						this.selectedArr[k] = sku.value;
					}
				});
			}
			this.updateStatus(this.getSelectedItem());
			this.getChoose()
		}

		filterKeys(proContent: any): any {
			// let keys =[]
			// proContent.skuList.map((item,index)=>{
			//      item.attrs.map(res=> keys.push(res.keyName))
			// })
			// keys = [...new Set(keys)]
			//  return keys
			// console.log("proContent", proContent);
			let keys: Array < any >= [];
			(proContent.skuList[0] as any).attrs.map((res: any) => keys.push(res.keyName));
			keys = [...new Set(keys)];
			return keys;
		}

		// 属性点击事件
		chooseSpec(skey: any, sval: any) {
			// skey->选中的规格key,sval->选中的规格值
			// this.curtSelect = sval;
			// console.log(!this.notSelectable.includes(sval))
			if (!this.notSelectable.includes(sval)) {
				if (this.selectedArr[skey] === sval) {
					// this.selectedArr[skey] = "";
					this.$set(this.selectedArr, skey, '')
				} else {
					// this.selectedArr[skey] = sval;
					this.$set(this.selectedArr, skey, sval)
				}
				this.updateStatus(this.getSelectedItem());
				// this.$emit('getChoose', this.selectedArr);
				this.getChoose()
			}
		}


		// // 将sku stock为0的sku过滤掉  一个sku的不过滤了
		// filterNullSku() {
		// 	if (this.proContent && this.proContent.skuList.length > 1) {
		// 		let sku = {};
		// 		sku = this.proContent.skuList.filter((item) => item.stock > 0);
		// 		this.proContent.skuList = sku;
		// 	}
		// }

		// 将商品数据中的 sku 用 key 过滤出所有可选的商品规格
		getshowSpec(skuList: any) {
			let keys = this.keys;
			let jsons: any = {};
			let select: any = {};
			for (let key_val of keys) {
				jsons[key_val] = [];
				select[key_val] = "";

				for (let j = 0; j < skuList.length; j++) {
					for (let i = 0; i < keys.length; i++) {
						if (
							skuList[j].attrs[i].keyName &&
							skuList[j].attrs[i].keyName === key_val
						) {
							jsons[key_val].push(skuList[j].attrs[i].value);
						}
					}
				}
			}

			for (let i in jsons) {
				jsons[i] = [...new Set(jsons[i])];
			}
			this.selectedArr = select; // 后面储存已选属性要用到 {颜色:'',尺寸: ''...}
			// console.log('this.selectedArr------>', this.selectedArr);

			return jsons;
		}

		// 计算组合数据
		combineAttr(skuList: any) {
			let allKeys: Array < any >= [];
			skuList.map((res: any) => {
				let values: Array < any > = [];
				res.attrs.forEach((key: any) => {
					values.push(key.value);
				});
				allKeys.push({
					path: values.join(this.spliter),
					kid: res.kid,
				});
			});
			return allKeys;
		}




		/**
		 * 生成所有子集是否可选、库存状态 map
		 *  items =》 [{path:'大-不辣',sku:111},{path:'大-辣',sku:111}]
		 *  allKeys =>["大-辣", "大-不辣", "中-不辣", "中-辣", "小-辣", "小-不辣"]
		 *  return  =>{ 不辣：{skus:[123,12323]}}
		 */
		buildResult(items: any) {
			this.allPath = {};
			let allKeys = items.map((res: any) => res.path);
			for (let i = 0; i < allKeys.length; i++) {
				let sku: string = items[i].kid;
				let values: Array < any > = allKeys[i].split(this.spliter);
				let allSets = this.powerset(values);
				// 每个组合的子集
				// 清空allpath,zcj
				// this.allPath = {};
				for (let j = 0; j < allSets.length; j++) {
					let set = allSets[j];
					let key = set.join(this.spliter);
					if (this.allPath[key]) {
						this.allPath[key].skus.push(sku);
					} else {
						this.allPath[key] = {
							skus: [sku],
						};
					}
				}
			}
			// console.log('this.allPath------>', this.allPath);
		}

		powerset(arr: any) {
			let ps: any = [
				[]
			];
			for (let i = 0; i < arr.length; i++) {
				for (let j = 0, len = ps.length; j < len; j++) {
					ps.push(ps[j].concat(arr[i]));
				}
			}
			return ps;
		}

		// 过滤分隔符
		trimSpliter(str: any) {
			// ⊙abc⊙ => abc
			// ⊙a⊙⊙b⊙c⊙ => a⊙b⊙c
			let reLeft = new RegExp("^" + this.spliter + "+", "g");
			let reRight = new RegExp(this.spliter + "+$", "g");
			let reSpliter = new RegExp(this.spliter + "+", "g");
			return str
				.replace(reLeft, "")
				.replace(reRight, "")
				.replace(reSpliter, this.spliter);
		}

		// 获取当前选中的属性 =>['大','不辣']
		getSelectedItem() {
			let result: any = [];
			result = Object.values(this.selectedArr);
			return result;
		}


		// 更新所有属性状态
		updateStatus(selected: any) {
			this.notSelectable = [];
			for (let i = 0, len = this.keys.length; i < len; i++) {
				let key: any = this.keys[i];
				let data: any = this.showSpec[key];
				// console.log('data',data);
				let copy: any = selected.slice();
				// console.log('copy',copy);
				for (let j = 0; j < data.length; j++) {
					let item: any = data[j];
					if (selected[i] === item) continue;
					copy[i] = item;
					let curr = this.trimSpliter(copy.join(this.spliter));
					if (!this.allPath[curr]) {
						this.notSelectable.push(item);
						// console.log("this.notSelectable------>", this.notSelectable);
					}
				}
			}

			if (!this.getSelectedItem().includes("")) {
				let choSku: any = this.getSelectedItem().join(this.spliter);
				// console.log(choSku);
				// console.log("findSku1", this.allPath[choSku]);
				this.findSku(this.allPath[choSku].skus[0])
			}
		}



		// emit===================================
		@Emit('getChoose')
		getChoose() {
			return this.selectedArr
		}

		@Emit('findSku')
		findSku(value: any) {
			return value
		}


	}
</script>

<style lang='scss' scoped>
	.mini-spec {
		max-height: vw(200);
		overflow-y: scroll;

		@include hide-scrollbar() .spec-item {
			@include word-vw(14, $gray3);

			.spec-title {
				@include word-vw(16, $gray3);
				line-height: vw(40);
			}

			.spec-list {
				display: flex;
				flex-wrap: wrap;
				margin-top: vw(6);

				.spec-value {
					min-width: vw(100);
					max-width: vw(345);
					@include ellipsis();

					height: vw(32);
					line-height: vw(32);
					padding: 0 vw(10);
					box-sizing: border-box;
					text-align: center;
					@include word-vw(14, $gray3);
					background: #fff;
					border-radius: vw(8);
					margin-right: vw(18);
					margin-bottom: vw(16);

					&.active {
						/* background: #fff; */
						color: #E33C64;
						/* background-color: $bk-color; */
						/* border: vw(1) solid $main-color; */
					}

					&.no {
						color: $gray9;
						background: #EFEFEF;
					}
				}

				.spec-value:last-child {
					margin-right: 0;
				}
			}
		}
	}
</style>
