<template>
	<page-meta>
		<navigation-bar :title="$tt('navBar.physicalModels')" title-align="center" background-color="#007AFF" />
	</page-meta>
	<view class="scene-model-wrap">
		<view class="container-wrap">
			<view class="group-wrap">
				<u-cell-group :border="false">
					<view class="cell-wrap" v-for="(item, index) in list" :key="index">
						<u-cell :border="false" isLink
							:arrow-direction="item.datatype.type === 'object' || item.datatype.type === 'array' ? 'left' : 'down'"
							@click="handleModel(item)">
							<view slot="title"> {{item.name}}</view>
						</u-cell>
					</view>
				</u-cell-group>
			</view>
		</view>
		<view class="other">
			<u-empty mode="data" :show="list.length === 0" marginTop="60" :text="$tt('scene.emptyData')"></u-empty>

			<!-- integer、decimal 类型 -->
			<u-popup :show="isInteger" :round="5" mode="bottom" bgColor="#eef3f7" :closeOnClickOverlay="false"
				@close="isInteger = false">
				<view class="integer-popup-wrap">
					<view class="nav">
						<text @click="isInteger = false">{{$tt('common.cancel')}}</text>
						<text @click="handleConfirmInteger">{{$tt('common.confirm')}}</text>
					</view>
					<view class="select-wrap">
						<view class="form-wrap" v-if="type === 'trigger'">
							<u--form labelPosition="left" labelWidth="80">
								<view class="form-item-wrap">
									<u-form-item :label="$tt('product.operator')" @click="isOperator = true">
										<u--input v-model="operators.name" border="none" inputAlign="right"
											:placeholder="$tt('product.selectOperator')" disabledColor="#fff" disabled
											:customStyle="{ marginRight: '20rpx' }" />
										<u-icon slot="right" name="arrow-right"></u-icon>
									</u-form-item>
								</view>
							</u--form>
						</view>
						<template v-if="operators.value !== 'between' && operators.value !== 'notBetween' ">
							<view class="num-wrap">
								<text class="num">{{value}}</text>
								<text class="unit">{{model.datatype.unit}}</text>
							</view>
							<view class="slider-wrap">
								<u-slider :min="model.datatype.min === undefined ? 0 : model.datatype.min"
									:max="model.datatype.max === undefined ? 100 : model.datatype.max"
									:step="model.datatype.step === undefined ? 1 : model.datatype.step"
									@input="handleSliderChange"></u-slider>
								<view class="limit">
									<text>
										{{`${model.datatype.min === undefined ? 0 : model.datatype.min} ${model.datatype.unit || ''}`}}
									</text>
									<text>
										{{`${model.datatype.max === undefined ? 0 : model.datatype.max} ${model.datatype.unit || ''}`}}
									</text>
								</view>
							</view>
						</template>
						<view v-else class="range-wrap">
							<u--input v-model="valueA" type="number" :placeholder="$tt('product.input')"
								border="surround"></u--input>
							<text style="padding: 0 20rpx;">-</text>
							<u--input v-model="valueB" type="number" :placeholder="$tt('product.input')"
								border="surround"></u--input>
							<text v-if="model.datatype.unit" style="margin-left: 20rpx;">{{model.datatype.unit}}</text>
						</view>
					</view>
				</view>
			</u-popup>

			<!-- bool 类型 -->
			<u-popup :show="isBool" :round="5" mode="bottom" bgColor="#eef3f7" :closeOnClickOverlay="false"
				@close="isBool = false">
				<view class="bool-popup-wrap">
					<view class="nav">
						<text @click="isBool = false">{{$tt('common.cancel')}}</text>
						<text @click="handleConfirmBool">{{$tt('common.confirm')}}</text>
					</view>
					<view class="radio-group-wrap">
						<u-radio-group v-model="value" :borderBottom="false" placement="column" iconPlacement="right">
							<view class="radio-wrap">
								<u-radio :label="$tt('product.on')" :name="1" iconSize="16"></u-radio>
							</view>
							<view class="radio-wrap">
								<u-radio :label="$tt('product.off')" :name="0" iconSize="16"></u-radio>
							</view>
						</u-radio-group>
					</view>
				</view>
			</u-popup>

			<!-- enum 类型 -->
			<u-popup :show="isEnum" :round="5" mode="bottom" bgColor="#eef3f7" :closeOnClickOverlay="false"
				@close="isEnum = false">
				<view class="enum-popup-wrap">
					<view class="nav">
						<text @click="isEnum = false">{{$tt('common.cancel')}}</text>
						<text @click="handleConfirmEnum">{{$tt('common.confirm')}}</text>
					</view>
					<view class="radio-group-wrap">
						<u-radio-group v-model="value" :borderBottom="false" placement="column" iconPlacement="right">
							<view class="radio-wrap" v-for="(item, index) in model.datatype.enumList" :key="index">
								<u-radio :label="item.text" :name="item.value" iconSize="16"></u-radio>
							</view>
						</u-radio-group>
					</view>
				</view>
			</u-popup>

			<!-- string 类型 -->
			<u-popup :show="isString" :round="5" mode="bottom" bgColor="#eef3f7" :closeOnClickOverlay="false"
				@close="isString = false">
				<view class="string-popup-wrap">
					<view class="nav">
						<text @click="isString = false">{{$tt('common.cancel')}}</text>
						<text @click="handleConfirmString">{{$tt('common.confirm')}}</text>
					</view>
					<view class="select-wrap">
						<view class="form-wrap" v-if="type === 'trigger'">
							<u--form labelPosition="left" labelWidth="80">
								<view class="form-item-wrap">
									<u-form-item :label="$tt('product.operator')" @click="isOperator = true">
										<u--input v-model="operators.name" border="none" inputAlign="right"
											:placeholder="$tt('product.selectOperator')" disabledColor="#fff" disabled
											:customStyle="{ marginRight: '20rpx' }" />
										<u-icon slot="right" name="arrow-right"></u-icon>
									</u-form-item>
								</view>
							</u--form>
						</view>
						<view class="input-wrap">
							<u--input v-model="value" :customStyle="{ padding: '24rpx' }"
								:placeholder="$tt('deviceDetail.inputMsg')" border="surround" fontSize="16"
								clearable></u--input>
						</view>
					</view>
				</view>
			</u-popup>
			<!-- 操作符 -->
			<u-popup :show="isOperator" :round="5" mode="bottom" :closeOnClickOverlay="true" zIndex="10076"
				@close="isOperator = false">
				<view class="operator-popup-wrap">
					<view class="cell-group-wrap">
						<u-cell-group :border="false">
							<view class="cell-wrap" v-for="(item,index) in oprGroup" :key="index"
								v-if="item.types.length === 0 || item.types.includes(model.datatype.type)">
								<u-cell :title="item.name" :name="item.value" :border="false"
									@click="handleConfirmOperator(item)"></u-cell>
							</view>
							<view class="cell-wrap">
								<u-cell :title="$tt('common.cancel')" name="cancel" :border="false"
									@click="handleConfirmOperator({ value: 'cancel' })"></u-cell>
							</view>
						</u-cell-group>
					</view>
				</view>
			</u-popup>
		</view>
	</view>
</template>

<script>
	import {
		getCacheThingsModel
	} from '@/apis/modules/device.js';
	import {
		navigateBackTo
	} from '@/utils/common.js';

	export default {
		data () {
			return {
				type: 'trigger',
				editIndex: null, // null 代表新增
				parentId: null,
				list: [], // 属性
				isInteger: false, // 整型
				oprGroup: [{
						types: [],
						name: '等于（=）',
						value: '=',
					},
					{
						types: [],
						name: '不等于（!=）',
						value: '!=',
					},
					{
						types: ['integer', 'decimal'],
						name: '大于（>）',
						value: '>',
					},
					{
						types: ['integer', 'decimal'],
						name: '小于（<）',
						value: '<',
					},
					{
						types: ['integer', 'decimal'],
						name: '大于等于（>=）',
						value: '>=',
					},
					{
						types: ['integer', 'decimal'],
						name: '小于等于（<=）',
						value: '<=',
					},
					{
						types: ['integer', 'decimal'],
						name: '在...之间（between）',
						value: 'between',
					},
					{
						types: ['integer', 'decimal'],
						name: '不在...之间（notBetween）',
						value: 'notBetween',
					},
					{
						types: ['string'],
						name: '包含（contain）',
						value: 'contain',
					},
					{
						types: ['string'],
						name: '不包含（notContain）',
						value: 'notContain',
					}
				],
				operators: {}, // 对象
				isOperator: false, // 操作符
				isBool: false,
				isEnum: false, // 枚举
				isString: false,
				model: {
					datatype: {},
				},
				value: null, // 属性值
				valueA: null,
				valueB: null,
				trigger: {},
				action: {},
			};
		},
		onLoad (option) {
			const {
				type,
				data,
				editIndex
			} = option;
			this.type = type;
			this.editIndex = Number(editIndex);
			if (data) {
				this.list = JSON.parse(data);
			} else {
				if (type === 'trigger') {
					this.trigger = uni.getStorageSync('trigger');
					const {
						productId
					} = this.trigger;
					this.productId = productId;
					this.$nextTick(() => {
						this.getModelDatas();
					})
				} else {
					this.action = uni.getStorageSync('action');
					const {
						productId
					} = this.action;
					this.productId = productId;
					this.$nextTick(() => {
						this.getModelDatas();
					})
				}
			};
		},
		methods: {
			// 获取区设备列表
			getModelDatas () {
				getCacheThingsModel(this.productId)
					.then(res => {
						if (res.code === 200) {
							let data = JSON.parse(res.data);
							this.list = this.formatArrayIndex(data);
						} else {
							uni.showToast({
								icon: 'none',
								title: res.msg
							});
						}
					})
					.catch(err => {
						console.log(err);
					});
			},
			// 物模型格式化处理
			formatArrayIndex (data) {
				let obj = {
					...data
				};
				for (let o in obj) {
					obj[o] = obj[o].map((item) => {
						item = {
							...item,
							level: 'parent'
						};
						if (item.datatype.type === 'array') {
							let arrayModel = [];
							for (let k = 0; k < item.datatype.arrayCount; k++) {
								let index = k > 9 ? String(k) : '0' + k;
								if (item.datatype.arrayType === 'object') {
									arrayModel.push({
										id: index,
										name: item.name + ' ' + (k + 1),
										level: 'index',
										datatype: {
											type: item.datatype.arrayType,
											params: item.datatype.params
										},
									});
								} else {
									arrayModel.push({
										id: index,
										name: item.name + ' ' + (k + 1),
										level: 'index',
										datatype: {
											type: item.datatype.arrayType,
										},
									});
								}
							}
							item.datatype.arrayModel = arrayModel;
						}
						return item;
					});
				}
				const ap = this.type;
				let list = [];
				if (this[ap].type == 1) {
					list = obj.properties || [];
				} else if (this[ap].type == 2) {
					list = obj.functions || [];
				} else if (this[ap].type == 3) {
					list = obj.events || [];
				}
				if (ap === 'action') {
					list = list.filter((item) => {
						if (item.datatype.params && item.datatype.params.length !== 0) {
							item.datatype.params = item.datatype.params.filter((item) => item.isMonitor == 0 &&
								item
								.isReadonly == 0);
						}
						return item.isMonitor == 0 && item.isReadonly == 0;
					});
				}
				return list;
			},
			// 选中选择
			handleModel (item) {
				this.model = item;
				// 存储 parentId 和 arrayIndex
				let action = uni.getStorageSync(this.type);
				if (item.level === 'parent') {
					action = {
						...action,
						parentId: item.id,
						parentName: item.name,
						arrayIndex: '',
						arrayIndexName: ''
					};
				}
				if (item.level === 'index') {
					action = {
						...action,
						arrayIndex: item.id,
						arrayIndexName: item.name
					};
				}
				uni.setStorageSync(this.type, action);
				// 根据类型弹出对应框
				this.operators = {};
				const {
					datatype
				} = item;
				const {
					type,
					params,
					arrayModel
				} = datatype;
				this.value = null;
				if (type === 'integer' || type === 'decimal') {
					this.isInteger = true;
					this.value = datatype.min ? datatype.min : 0;
					this.valueA = null;
					this.valueB = null;
				} else if (type === 'bool') {
					this.isBool = true;
				} else if (type === 'enum') {
					this.isEnum = true;
				} else if (type === 'string') {
					this.isString = true
				} else if (type === 'object') {
					uni.$u.route('/pagesA/scene/product/model', {
						type: this.type,
						data: JSON.stringify(params),
						editIndex: this.editIndex
					});
				} else if (type === "array") {
					uni.$u.route('/pagesA/scene/product/model', {
						type: this.type,
						data: JSON.stringify(arrayModel),
						editIndex: this.editIndex
					});
				}
			},
			// 操作符选择{{$tt('common.confirm')}}
			handleConfirmOperator (item) {
				if (item.value !== 'cancel') {
					this.operators = item;
				}
				this.isOperator = false;
			},
			// slider 负数会有问题，所以采用这方式
			handleSliderChange (value) {
				if (this.model.datatype.step) {
					const str = this.model.datatype.step.toString();
					const places = str.match(/\.(\d+)/);
					const num = places ? places[1].length : 0;
					this.value = value.toFixed(num);
				} else {
					this.value = value;
				}
			},
			// 整型、浮点型
			handleConfirmInteger () {
				const {
					id,
					name
				} = this.model;
				if (this.type === 'trigger' && Object.keys(this.operators).length === 0) {
					uni.showToast({
						icon: 'none',
						title: this.$tt('product.selectOperator')
					});
					return;
				};
				let value = '';
				if (this.operators.value !== 'between' && this.operators.value !== 'notBetween') {
					if (this.value === this.model.datatype.min || !this.value) {
						uni.showToast({
							icon: 'none',
							title: this.$tt('product.inputValue')
						});
						return;
					};
					value = this.value;
				} else {
					if (!this.valueA || !this.valueB) {
						uni.showToast({
							icon: 'none',
							title: this.$tt('product.inputValue')
						});
						return;
					}
					value = this.valueA + '-' + this.valueB;
				}
				const {
					tempId,
					tempName
				} = this.getModelIdAndName(id, name);
				const model = {
					id: tempId,
					name: tempName,
					value: value,
				};
				this.setModelData(model);
				this.isInteger = false;
				uni.setStorageSync('callback', true);
				navigateBackTo('/pagesA/scene/detail');
			},
			//  bool 类型
			handleConfirmBool () {
				const {
					id,
					name
				} = this.model;
				if (this.value === null) {
					uni.showToast({
						icon: 'none',
						title: this.$tt('product.selectValue')
					});
					return;
				};
				const {
					tempId,
					tempName
				} = this.getModelIdAndName(id, name);
				const model = {
					id: tempId,
					name: tempName,
					value: this.value,
				};
				this.setModelData(model);
				this.isBool = false;
				uni.setStorageSync('callback', true);
				navigateBackTo('/pagesA/scene/detail');
			},
			// enum 类型
			handleConfirmEnum () {
				const {
					id,
					name
				} = this.model;
				if (!this.value) {
					uni.showToast({
						icon: 'none',
						title: this.$tt('product.selectValue')
					});
					return;
				};
				const {
					tempId,
					tempName
				} = this.getModelIdAndName(id, name);
				const model = {
					id: tempId,
					name: tempName,
					value: this.value,
				};
				this.setModelData(model);
				this.isEnum = false;
				uni.setStorageSync('callback', true);
				navigateBackTo('/pagesA/scene/detail');
			},
			// string 类型
			handleConfirmString () {
				const {
					id,
					name
				} = this.model;
				if (this.type === 'trigger' && Object.keys(this.operators).length === 0) {
					uni.showToast({
						icon: 'none',
						title: this.$tt('product.selectOperator')
					});
					return;
				};
				if (!this.value) {
					uni.showToast({
						icon: 'none',
						title: this.$tt('product.inputValue')
					});
					return;
				};
				const {
					tempId,
					tempName
				} = this.getModelIdAndName(id, name);
				const model = {
					id: tempId,
					name: tempName,
					value: this.value,
				};
				this.setModelData(model);
				this.isString = false;
				uni.setStorageSync('callback', true);
				navigateBackTo('/pagesA/scene/detail');
			},
			// 获取model的id和name
			getModelIdAndName (id, name) {
				let tempId = id;
				let tempName = name;
				const {
					parentId,
					parentName,
					arrayIndex,
					arrayIndexName
				} = uni.getStorageSync(this.type);
				if (arrayIndex) {
					if (arrayIndex === id) { // 数组
						tempId = `array_${arrayIndex}_${parentId}`;
						tempName = parentName;
					} else { // 数组对象
						tempId = `array_${arrayIndex}_${id}`;
					}
				} else {
					tempId = id;
				}
				return {
					tempId,
					tempName
				}
			},
			// 存储数据
			setModelData (data) {
				let action = uni.getStorageSync(this.type);
				const {
					id,
					name,
					value
				} = data;
				action = {
					...action,
					id,
					name,
					value
				};
				if (this.type === 'trigger') {
					action = {
						...action,
						operator: this.operators.value || ''
					};
				}
				uni.setStorageSync(this.type, action);
				// 更新或者插入新的触发或者执行
				let {
					triggers,
					actions,
					...res
				} = uni.getStorageSync('sceneData');
				if (Number.isNaN(this.editIndex) || this.editIndex === null) {
					if (this.type === 'trigger') {
						triggers.push(action);
					} else {
						actions.push(action);
					}
					uni.setStorageSync('sceneData', {
						triggers,
						actions,
						...res
					});
				} else {
					if (this.type === 'trigger') {
						let list = triggers.map((item, i) => {
							if (i == this.editIndex) {
								return action
							} else {
								return item
							}
						});
						uni.setStorageSync('sceneData', {
							triggers: [...list],
							actions,
							...res
						});
					} else {
						let list = actions.map((item, i) => {
							if (i == this.editIndex) {
								return action
							} else {
								return item
							}
						});
						uni.setStorageSync('sceneData', {
							triggers,
							actions: [...list],
							...res
						});
					}
				}
			}
		}
	};
</script>

<style>
	page {
		height: 100%;
		background: #eef3f7;
	}
</style>
<style lang="scss" scoped>
	.scene-model-wrap {
		.container-wrap {
			.group-wrap {
				margin: 30rpx;
				background: #fff;
				border-radius: 12rpx;

				.cell-wrap {
					padding: 7rpx 0;
					border-bottom: 1rpx solid #F1F2F5;
				}
			}
		}

		.other {
			.integer-popup-wrap {
				padding: 30rpx;

				.nav {
					display: flex;
					flex-direction: row;
					justify-content: space-between;
					align-items: center;
					font-size: 32rpx;
					margin-bottom: 34rpx;
				}

				.select-wrap {
					background-color: #fff;
					border-radius: 10rpx;
					padding: 40rpx 20rpx;

					.form-wrap {
						.form-item-wrap {
							padding: 4rpx 20rpx;
						}
					}

					.num-wrap {
						position: relative;
						margin-top: 60rpx;
						text-align: center;

						.num {
							font-size: 80rpx;
						}

						.unit {
							position: absolute;
							top: 50%;
							margin-top: -23rpx;
							font-size: 32rpx;
							color: #868686;
							margin-left: 60rpx;
						}
					}

					.slider-wrap {
						.limit {
							font-size: 28rpx;
							color: #868686;
							display: flex;
							flex-direction: row;
							justify-content: space-between;
							padding: 0 30rpx;
						}
					}

					.range-wrap {
						display: flex;
						flex-direction: row;
						align-items: center;
						margin-top: 30rpx;
					}
				}
			}

			.operator-popup-wrap {
				padding: 10rpx 0 20rpx;

				.cell-group-wrap {
					background: #eef3f7;

					.cell-wrap {
						text-align: center;
						background: #fff;
						padding: 10rpx;
						border-bottom: 1rpx solid #F1F2F5;

						&:last-child {
							margin-top: 15rpx;
						}
					}
				}
			}

			.bool-popup-wrap,
			.enum-popup-wrap {
				padding: 30rpx;

				.nav {
					display: flex;
					flex-direction: row;
					justify-content: space-between;
					align-items: center;
					font-size: 32rpx;
					margin-bottom: 34rpx;
				}

				.radio-group-wrap {
					background-color: #fff;
					border-radius: 10rpx;

					.radio-wrap {
						padding: 40rpx;

						&:not(:last-child) {
							border-bottom: 1rpx solid #F1F2F5;
						}
					}
				}
			}

			.string-popup-wrap {
				padding: 30rpx;

				.nav {
					display: flex;
					flex-direction: row;
					justify-content: space-between;
					align-items: center;
					font-size: 32rpx;
					margin-bottom: 34rpx;
				}

				.select-wrap {
					background-color: #fff;
					border-radius: 10rpx;
					padding: 40rpx 20rpx;

					.form-wrap {
						.form-item-wrap {
							padding: 4rpx 20rpx;
						}
					}

					.input-wrap {
						margin: 32rpx 12rpx 20rpx;
					}

				}
			}
		}
	}
</style>