<template>
	<el-dialog
		:visible.sync="isOpenDialog"
		:close-on-click-modal="false"
		:modal-append-to-body="false"
		@close="cancelHandle"
		custom-class="dynamic-differ-dialog"
		center
		width="1090px"
		top="8vh"
		v-dialogDrag
	>
		<div slot="title" style="display: flex; align-items: center">
			<span style="font-size: 16px">{{ title }}</span>
		</div>
		<div class="dialog-main">
			<ul class="add-cont">
				<li class="add-li" v-for="(list, index) in addList" :key="index">
					<span class="li-tag">{{ list.tag }}</span>
					<el-select
						v-model="list.target"
						v-loadMore="searchLoad"
						:filterable="!list.target"
						clearable
						placeholder="请输入指标名称"
						style="width: 400px"
						@change="chooseTarget"
						@clear="clearHandle(index)"
						remote
						:remote-method="searchTarget"
						@click.native="inputFocusHandle"
					>
						<i slot="prefix" class="el-input__icon el-icon-search"></i>
						<el-option
							v-for="item in searchOptions"
							:key="item.EdbInfoId"
							:label="item.EdbName"
							:value="item.EdbInfoId"
						>
							<edbDetailPopover :info="item">
								<div slot="reference">{{item.EdbName}}</div>
							</edbDetailPopover>
						</el-option>
					</el-select>
					<i class="el-icon-tickets" style="color:#409EFF;font-size:18px" @click="$emit('lookHistory',list.target)" v-if="list.target"/>
					<i
						class="el-icon-error del-tag"
						v-if="index > 3"
						@click="delTarget(index)"
					/>
					<span class="target-date" v-if="list.start_date">{{
						`${list.start_date}至${list.end_date}`
					}}</span>
				</li>
			</ul>
			<span class="add-icon" @click="addTargetHandle">
				<i
					class="el-icon-circle-plus-outline"
					style="color: #5882ef; font-size: 16px"
				/>
				添加更多参数
			</span>
			<div class="computed-min">
				
				<div class="computed-section">
					<div>
						<label class="label">空值处理
							<el-tooltip placement="top">
								<div slot="content" v-html="formTips['null-val']" style="width:300px;line-height:20px;"/>
								<i class="el-icon-question"/>
							</el-tooltip>
						</label>
						<el-select
							v-model="nullValueForm.nullValueWay"
							placeholder="请选择"
						>
							<el-option
								v-for="item in nullWayOptions"
								:key="item.value"
								:label="item.label"
								:value="item.value"
							>
							</el-option>
						</el-select>
					</div>

					<div style="margin-left: 120px" v-if="showMaxNullDeal">
						<label class="label">MAX、MIN空值处理
							<el-tooltip placement="top">
								<div slot="content" v-html="formTips['max-null-val']" style="width:300px;line-height:20px;"/>
								<i class="el-icon-question"/>
							</el-tooltip>
						</label>
						<el-select
							v-model="nullValueForm.maxNullWay"
							placeholder="请选择"
						>
							<el-option label="等于0" :value="1" />
							<el-option label="跳过空值" :value="2" />
						</el-select>
					</div>

          <el-button type="primary" @click="getResult" style="margin-left: 10px">一键计算</el-button>
				</div>

				<div class="computed-section">
					<label class="label">计算公式
						<el-tooltip placement="top">
							<div slot="content" v-html="formTips['formula']" style="width:300px;line-height:20px;"/>
							<i class="el-icon-question"/>
						</el-tooltip>
					</label>

					<ul class="formula-list">
						<li style="margin-bottom: 15px;">
							<el-input placeholder="请输入公式" v-model="formulaList[0].formula" clearable style="width: 220px"/>
							
							<span v-if="formulaDateArr.length" class="date-section-text">{{formulaDateArr[formulaDateArr.length-1]}}(含)之后</span>

							<span class="example-txt">公式示例：A*0.5+B*C*1.2+120-MAX(A,B,C) &nbsp;函数支持：MAX(),MIN(),ln(A),log(a,A),abs(),exp(),pow(),round()</span>
						</li>

						<li class="formula-item" v-for="(item,index) in formulaList.slice(1)" :key="index+1">
							<el-input 
								placeholder="请输入公式" 
								v-model="item.formula" 
								clearable
								style="width: 220px"
							/>

							<el-date-picker
								v-model="item.date"
								type="date"
								value-format="yyyy-MM-dd"
								style="margin: 0 10px;width: 220px"
								placeholder="选择日期"
								@change="selectFormulaDate($event,item)"
							/>

							<i class="el-icon-circle-close" style="font-size:20px;" @click="removeFormulaItem(index+1)"/>

							<template v-if="formulaDateArr.length&&item.date">
								<span v-if="item.date===formulaDateArr[0]" class="date-section-text">{{formulaDateArr[0]}}之前</span>
								<span v-else class="date-section-text">{{formulaDateArr[formulaDateArr.findIndex(_ =>_ ===item.date)-1]}}(含)——{{item.date}}</span>
							</template>
						</li>
					</ul>
				</div>

				<el-button icon="el-icon-plus" style="margin-left:70px;" @click="addFormulaHandle">新增分段</el-button>
			</div>
      
      <el-table
        border
        :data="resultData"
				v-if="resultData.length"
        max-height="320"
      >
        <el-table-column
          v-for="item in tableColums"
          :key="item.label"
          :label="item.label"
          :width="item.widthsty"
          :min-width="item.minwidthsty"
          align="center"
        >
          <template slot-scope="scope">
            <span :style="scope.row.isPredict&&'color: orange'">{{ scope.row[item.key] }}</span>
          </template>
        </el-table-column>
					<div slot="empty" style="padding:20px 0 30px;">
						<tableNoData text="暂无指标" size="mini"/>
					</div>
      </el-table>
		</div>
		<div class="dia-bot">
			<el-button
				type="primary"
				style="margin-right: 20px"
				@click="saveHandle"
				>保存</el-button
			>
			<el-button type="primary" plain @click="cancelHandle">取消</el-button>
		</div>
	</el-dialog>
</template>

<script>
import * as preDictEdbInterface  from '@/api/modules/predictEdbApi.js';
const tag_arr = [];
for(var i=0;i<26;i++) tag_arr.push(String.fromCharCode(65+i));
export default {
	name: '',
	props: {
		isOpenDialog: {
			type: Boolean,
		},
		title: {
			type: String,
			default: '设置环比增加值',
		},
		info: {
			type: Object,
		},
		edbList: {
			type: Array,
		},
	},
	computed: {
		/* max空值处理显示 当输入的公式包含MAX、MIN且空值处理为0时，输入公式失焦后出现右侧选项； */
		showMaxNullDeal() {
			let haveMaxOrMin = this.formulaList.some(_ => _.formula.toUpperCase().includes('MAX') || _.formula.toUpperCase().includes('MIN'))

			return haveMaxOrMin && this.nullValueForm.nullValueWay===4
		},

		formulaDateArr() {
			return this.formulaList.map(_ => _.date).filter(_ => _).sort((a,b) => new Date(a)-new Date(b))
		}
	},
	watch: {
		isOpenDialog(newval) {
			/* 回显 */
			if (this.edbList.length && newval) {
				this.addList = _.cloneDeep(this.edbList);
				const{ formulaList,nullValueWay,maxNullWay } = this.info;
				this.formulaList = JSON.parse(formulaList).map(_=>({
					formula: _.f,
					date: _.d
				}));

				this.nullValueForm = {
					nullValueWay,
					maxNullWay
				}

				this.searchOptions = this.edbList.map(item => ({
					EdbInfoId: item.target,
					EdbName: item.name,
				}))
			}
		},
	},
	data() {
		return {
			addList: [
				{
					tag: tag_arr[0],
					name: '',
					target: '',
					start_date: '',
					end_date: '',
				},
				{
					tag: tag_arr[1],
					name: '',
					target: '',
					start_date: '',
					end_date: '',
				},
				{
					tag: tag_arr[2],
					name: '',
					target: '',
					start_date: '',
					end_date: '',
				},
				{
					tag: tag_arr[3],
					name: '',
					target: '',
					start_date: '',
					end_date: '',
				},
			],
			searchOptions: [],
			formula: '', //计算公式
			dataloading: false,

			search_have_more: false,
			search_page: 1,
			current_search:'',

      tableColums: [
        {
					label: '日期',
					key: 'DataTime',
				},
				{
					label: '环比增加值',
					key: 'Value',
				},
      ],

			formulaList: [
				{ formula: '', }
			],
			nullValueForm: {
				nullValueWay: 0,
				maxNullWay: 1
			},//空值处理
			nullWayOptions: [
				{ label: '查找前后35天最近值',value: 0 },
				{ label: '不计算',value: 1 },
				{ label: '前值填充',value: 2 },
				{ label: '后值填充',value: 3 },
				{ label: '等于0',value: 4 },
			],
			formTips: {
				'null-val': `1、查找前后35天最近值：在参与计算的日期序列上某指标无值时，该指标往前/往后找距离最近的值作为当天的值进行计算，遍历允许跨年，往前最多35天，往后最多35天<br>
				2、不计算：只要有一个指标在某个日期没有值(即空值)，则计算指标在该日期没有值 <br>
				3、前值填充：空值优先以最近的前值填充，没有前值时，用后值填充 <br>
				4、后值填充：空值优先以最近的后值填充，没有前值时，用后值填充 <br>
				5、等于0：空值以0值参与计算 <br>
				注意：此处缺失值的处理，作用于数据全部时间段`,
				'max-null-val': `MAX、MIN公式中指标存在空值时按如下规则处理：<br>
				1、等于0，空值用0参与计算；<br>
				2、跳过空值，去除空值指标，剩余指标进行计算，若该日期所有指标均为空值，则该日期无值；`,
				'formula':`1、支持新增分段，实现不同分段使用不同的计算公式，若未新增分段，则所有日期序列用统一公式计算<br>
				2、新增分段需配置新公式和时间节点，在时间节点之前（不含）使用新公式，在时间节点之后（含）使用已配置公式，每个分段公式支持修改<br>
				3、分段时间节点不允许重复，不允许超出第一个指标的日期区间`
			},

      resultData: [],//
		};
	},
	methods: {

		/* 添加额外的指标列 */
		addTargetHandle() {
			let tag = this.addList[this.addList.length-1].tag;
			let index = tag_arr.findIndex(item => item === tag);
			const item = {
				tag: tag_arr[index+1],
				target: '',
				name: '',
				start_date: '',
				end_date: ''
			};
			this.addList.push(item);
		},

		/* 搜索指标 */
		searchTarget(query) {
			this.search_page = 1;
			this.current_search = query;
			this.searchApi(this.current_search);
		},

		/* 聚焦获取当前检索 */
		inputFocusHandle(e) {
			this.search_page = 1;
			this.current_search = e.target.value;
			this.searchApi(this.current_search);
		},

		searchApi(query,page=1) {
			preDictEdbInterface
          .edbSearch({
            Keyword: query,
            CurrentIndex: page
          })
          .then((res) => {
            if (res.Ret !== 200) return

						const { List,Paging } = res.Data;
						this.search_have_more = page < Paging.Pages;
						this.searchOptions = page === 1 ? List : this.searchOptions.concat(List);
          });
		},

		searchLoad() {
			if(!this.search_have_more) return;
			this.searchApi(this.current_search,++this.search_page)
		},

		/* 选中指标 显示开始日期结束日期 */
		chooseTarget(val) {
			if (val) {
				const choose_obj = this.searchOptions.find(
					(item) => item.EdbInfoId === val
				);
				this.addList.forEach((list) => {
					if (list.target === val) {
						list.name = choose_obj.EdbName;
						list.start_date = choose_obj.StartDate;
						list.end_date = choose_obj.EndDate;
					}
				});
			}
		},
		/* 清空指标和关联日期 */
		clearHandle(index) {
			this.addList[index].start_date = '';
			this.addList[index].end_date = '';
			this.addList[index].name = '';
		},
		// 删除指标
		delTarget(index) {
			this.addList.splice(index, 1);
		},
		saveHandle() {
			if (!this.formulaList[0].formula) return this.$message.warning('计算公式不能为空');
			// 指标id数组
      let target_arr = this.addList.filter(item => item.target);
			
			let formula = JSON.stringify(this.formulaList
				.filter((_,index) => index===0||(index>0&&_.formula&&_.date))
				.map(_ => ({f: _.formula,d: _.date}))
			)
			
			this.$emit('ensureBack',{arr:target_arr,formula,...this.nullValueForm})
			this.cancelHandle();
		},

		/* 获取数据 */
		async getResult() {
			if (!this.formulaList[0].formula) return this.$message.warning('计算公式不能为空');
			
			let EdbInfoIdArr = this.addList.filter(_ => _.target).map(_ => ({
				EdbInfoId: _.target,
				FromTag: _.tag
			}))
			const { nullValueWay,maxNullWay } = this.nullValueForm;
			let formula = JSON.stringify(this.formulaList
				.filter((_,index) => index===0||(index>0&&_.formula&&_.date))
				.map(_ => ({f: _.formula,d: _.date}))
			)

			const params = {
				RuleType: 9,
				EndDate: '',
				Value: formula,
				EmptyType: nullValueWay,
				MaxEmptyType: maxNullWay,
				EdbInfoIdArr
			}

			const { Ret,Data } = await preDictEdbInterface.getRuleNineData(params);
			if(Ret !== 200) return

			this.resultData = Data.DataList.map(_ => ({
				..._,
				isPredict: _.DataTimestamp > this.$moment(Data.LatestDate+' 8:00').valueOf()
			})) || [];
		},

		/* 新增公式分段 */
		addFormulaHandle() {
			let addItem = {
				formula: this.formulaList[this.formulaList.length-1].formula,
				date: ''
			}
			this.formulaList.push(addItem)
		},

		/* 移除公式 */
		removeFormulaItem(index) {
			this.formulaList.splice(index,1)
		},

		/* 选择日期 检验 */
		selectFormulaDate(val,item) {
			const { start_date,end_date } = this.addList[0];

			if(!start_date) return

			let dateStamp = new Date(val).getTime(), 
					startStamp = new Date(start_date).getTime(),
					endStamp = new Date(end_date).getTime();
			if (dateStamp > endStamp || dateStamp < startStamp) {
				item.date = '';
				return this.$message.warning('分段日期必须在第一个指标日期区间')
			}

			else if(this.formulaList.filter(_ => _.date===val).length>1) {
				item.date = '';
				return this.$message.warning('分段日期不可重复')
			}
		},
		
		init() {
			this.addList = [
				{
					tag: tag_arr[0],
					name: '',
					target: '',
					start_date: '',
					end_date: '',
				},
				{
					tag: tag_arr[1],
					name: '',
					target: '',
					start_date: '',
					end_date: '',
				},
				{
					tag: tag_arr[2],
					name: '',
					target: '',
					start_date: '',
					end_date: '',
				},
				{
					tag: tag_arr[3],
					name: '',
					target: '',
					start_date: '',
					end_date: '',
				},
			];
			this.searchOptions = [];
			this.formula = '';
			this.resultData = [];

			this.formulaList = [
				{ formula: '' }
			]
			this.nullValueForm = {
				nullValueWay: 0,
				maxNullWay: 1
			}
		},
		cancelHandle() {
			this.init();
			this.$emit('update:isOpenDialog',false);
		},
	},
	mounted() {},
};
</script>
<style lang="scss">
.dynamic-differ-dialog {
	overflow: hidden;
	div::-webkit-scrollbar {
		width: 6px !important;
	}
	.el-dialog__body {
		max-height: 700px;
		overflow: auto;
	}
	.dialog-main {
		padding: 25px 42px 25px 25px;
		.el-cascader .el-input {
			width: 340px;
		}
		.add-cont {
			display: flex;
			flex-wrap: wrap;
			justify-content: space-between;
			.add-li {
				position: relative;
				margin-bottom: 48px;
				.li-tag {
					font-size: 16px;
					margin-right: 8px;
				}
				.del-tag {
					position: absolute;
					right: -30px;
					top: 12px;
					font-size: 16px;
					cursor: pointer;
				}
				.target-date {
					color: #5882ef;
					position: absolute;
					bottom: -25px;
					left: 24px;
				}
			}
		}
		.add-icon {
			font-size: 16px;
			color: #5882ef;
			cursor: pointer;
		}
		.computed-min {
			margin: 50px 0;
			.example-txt {
				display: block;
				margin-top: 10px;
			}
			.computed-section {
				display: flex;
				margin-top: 20px;
			}
			.label {
				padding:10px 10px 10px 0;
			}
			.formula-item {
				display: flex;
				align-items: center;
				margin-bottom: 15px;
			}
			.date-section-text {
				margin-left: 15px;
			}
		}
	}
	.dia-bot {
		padding-bottom: 40px;
		display: flex;
		justify-content: center;
	}
}
</style>
