<template>
	<el-card class="codecount-container">
		<div slot="header" class="header">
			<span>代码运算</span>
			<div>
				<el-button type="primary" @click="runCodeHandle">运行</el-button>
				<el-button type="primary" plain @click="saveHandle" v-if="!isView">保存</el-button>
			</div>
		</div>
		<div class="bottom">
			<el-col :span="15" class="bottom-wrapper left-wrapper">
				<div class="code-editor">
					<code-mirror ref="codeRef" :code="runCode" @initResult="initResult"/>
				</div>
				<div class="code-result">
					<span>结果展示</span>
					<div class="code-result-wrapper" v-if="isShowResult">
						<data-table
							:data="runResultData"
						/>
					</div>
				</div>
			</el-col>
			<el-col :span="8" class="bottom-wrapper">
				<el-tabs>
					<el-tab-pane label="基础信息">
						<el-form
							ref="diaForm"
							label-position="left"
							inline
							label-width="80px"
							:model="formData"
							:disabled="isView"
						>
							<el-form-item label="指标名称" prop="edb_name">
								<el-input
									v-model="formData.edb_name"
									placeholder="指标名称"
									style="width:220px"
								/>
							</el-form-item>
							<el-form-item label="单位" prop="unit">
								<selectUnit 
									v-model="formData.unit" 
									style="width:220px"
								/>
							</el-form-item>
							<el-form-item label="频度" prop="frequency">
								<el-select 
								v-model="formData.frequency" 
								placeholder="请选择频度" 
								clearable 
								@change="changeTrade"
								style="width:220px">
									<el-option
										v-for="item in frequencyArr"
										:key="item"
										:label="item"
										:value="item">
									</el-option>
								</el-select>
							</el-form-item>
							<el-form-item label="指标目录" prop="menu">
								<el-cascader
								v-model="formData.menu"
								:options="menuOptions"
								:props="{
									label: 'ClassifyName',
									value: 'ClassifyId',
									children: 'Children',
								}"
								@change="menuChange"
								clearable
								style="width:220px"
								placeholder="请选择指标目录"/>
							</el-form-item>
						</el-form>
					</el-tab-pane>
					<el-tab-pane label="指标信息" v-if="!isView">
						<el-form
							label-position="left"
							inline
							label-width="100px"
						>
							<el-form-item label="数据来源">
								<el-select 
								v-model="fromType" 
								placeholder="请选择来源"
								style="width:220px"
								@change="changeTrade">
									<el-option
										v-for="item in allFromArr"
										:key="item.key"
										:label="item.name"
										:value="item.key">
									</el-option>
								</el-select>
							</el-form-item>
							<el-form-item label="指标名称/ID">
								<el-select
									v-model="search_txt"
									v-loadMore="searchLoad"
									ref="searchRef"
									:filterable="!search_txt"
									remote
									clearable
									placeholder="指标ID/指标名称"
									:remote-method="searchHandle"
									@click.native="inputFocusHandle"
									style="width:220px"
								>
									<i slot="prefix" class="el-input__icon el-icon-search"></i>
									<el-option
										v-for="item in searchOptions"
										:key="item.EdbInfoId"
										:label="eta_lang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName"
										:value="item.EdbInfoId"
									>
									</el-option>
								</el-select>

							</el-form-item>
						</el-form>
						<div class="search-result">
							<p>查询结果 <span style="color: #999;">（展示指标所在表结构及调取指标代码）</span></p>
							<template v-if="resultInfo.sheet_name">
								<table border>
									<thead>
										<tr>
											<td v-for="item in resultInfo.headers" :key="item">{{item}}</td>
										</tr>
									</thead>
									<tbody>
										<tr v-for="(item,index) in resultInfo.sheetArr" :key="item.key">
											<td :rowspan="resultInfo.sheetArr.length" v-if="index === 0">{{resultInfo.sheet_name}}</td>
											<td>{{item.key}}</td>
											<td>{{item.label}}</td>
										</tr>
									</tbody>
								</table>
								<div class="sql-code" v-html="resultInfo.sql_code"></div>
								<el-button type="primary" class="copy-btn" @click="copyCode" :data-clipboard-text="resultInfo.sql_code">复制代码</el-button>

							</template>
						</div>
					</el-tab-pane>
				</el-tabs>
			</el-col>
		</div>
	</el-card>
</template>

<script>
import { dataBaseInterface } from '@/api/api.js';
import { unitArr } from '@/utils/defaultOptions';
import storage from '@/utils/storage.js';
import { allFromArr } from '../databaseComponents/util';
import codeMirror from './compoments/codeMirror';
import dataTable from './compoments/dataTable';
import { mapState } from 'vuex';
export default {
	name:'',
	components: { codeMirror,dataTable },
	computed: {
		...mapState({
			eta_lang: state => state.edb.eta_lang,	
		})
	},
	data () {
		return {
			isView: this.$route.query.isView ? true : false,
			formData: {},
			fromType:"",
			unitArr,
			allFromArr,//所有指标来源
			frequencyArr:['日度','周度','旬度','月度','季度','年度'],
			menuOptions:[],//目录数组

			search_txt: '',
			search_have_more: false,
			searchOptions:[],
			search_page: 1,
			current_search: '',

			isShowResult: false,
			runCode: '',
			runResultData:[],//运行结果

			resultInfo: {
				headers: ['表名','字段名','*字段说明'],
				sheetArr:[],
				sheet_name: '',
				sql_code: ''
			}
		};
	},
	watch: {
		//每搜索一次记录一次
		search_txt(newval) {
			if(!newval) return;

			let historySearch = storage.get('pycode_seachlist') || [];
			let obj = {
				EdbInfoId: newval,
				EdbName: this.searchOptions.find(_ => _.EdbInfoId===newval).EdbName
			}
			//有搜索记录删除上条
			let index = historySearch.findIndex(_ => _.EdbInfoId === newval)
			if(index !== -1) historySearch.splice(index, 1);
			historySearch.unshift(obj)

			storage.set('pycode_seachlist',historySearch,1)

			this.getEdbSheeetInfo(newval);

		}
	},
	methods: {

		/* 运行代码 */
		runCodeHandle: _.debounce(function() {
			if(!this.$refs.codeRef.codeContent) return this.$message.warning('请输入代码');

			this.isShowResult = false;

			const loading = this.$loading({
				lock: true,
				text: '运行中...',
				target:'.left-wrapper',
				spinner: 'el-icon-loading'
			});

			dataBaseInterface.runCode({
				PythonCode: encodeURIComponent(this.$refs.codeRef.codeContent)
			}).then(res => {
				
				loading.close();
				if(res.Ret !== 200) return
				this.$message.success('运行成功')

				const { date,value } = res.Data;
				const data_arr = []
				for(let i in date) {
					data_arr.push([date[i],value[i]])
				}
				this.runResultData = data_arr;
				this.isShowResult = true;
			})
		},200),

		/* 获取指标详情 */
		getEdbInfo() {
			if(!this.$route.query.edbid) return;
			dataBaseInterface.countCodeDetail({
				EdbInfoId: Number(this.$route.query.edbid)
			}).then(res => {
				if(res.Ret !== 200) return
				
				const { EdbInfoDetail,PythonCode } = res.Data;
				const { EdbName,ClassifyId,Frequency,Unit } = EdbInfoDetail;

				this.formData = {
					edb_name: EdbName,
					menu: ClassifyId,
					frequency: Frequency,
					unit: Unit
				}
				this.runCode = PythonCode
				
			})
		},

		/* 获取表结构 */
		getEdbSheeetInfo(EdbInfoId) {
			dataBaseInterface.edbSheetDetail({
				EdbInfoId
			}).then(res => {
				if(res.Ret !== 200) return
				
				const { ColumnList,TableName,TemplateStr } = res.Data;
				this.resultInfo.sheet_name = TableName;
				this.resultInfo.sql_code = decodeURIComponent(TemplateStr);
				this.resultInfo.sheetArr = ColumnList.map(_ => {
					let key = Object.keys(_)[0];
					return {
						key,
						label: _[key]
					}
				})

			})
		},

		/* code变化时重置结果展示 */
		initResult() {
			this.isShowResult = false
		},

		/* 复制代码 */
		copyCode() {
			var clipboard = new this.Clipboard('.copy-btn')
				clipboard.on('success', e => {
					this.$message.success('复制成功')
					e.clearSelection() // 释放内存
					clipboard.destroy()
				})
				// // 浏览器不支持
				clipboard.on('error', e => {
					this.$message.warning('浏览器暂不支持')
					// 释放内存
					clipboard.destroy()
				})
		},
		
		/* 保存代码 */
		async saveHandle() {
			if(!this.formData.edb_name || !this.formData.menu || !this.formData.frequency || !this.formData.unit) return this.$message.warning('请填写完整基础信息')
			if(!this.isShowResult) return this.$message.warning('请先运行代码')

			const loading = this.$loading({
				lock: true,
				text: '保存中...',
				target:'.codecount-container',
				spinner: 'el-icon-loading'
			});
			
			const { edb_name,menu,frequency,unit } = this.formData
			let params = {
				PythonCode: encodeURIComponent(this.$refs.codeRef.codeContent),
				EdbName: edb_name,
				Frequency: frequency,
				Unit: unit,
				ClassifyId: menu
			}
			
			const { Ret,Data } = this.$route.query.edbid ? await dataBaseInterface.editCountCode({ ...params,EdbInfoId: Number(this.$route.query.edbid) }) : await dataBaseInterface.addCountCode(params);
			
			loading.close();
			if( Ret !== 200 ) return 
			this.$message.success('保存成功')
			const { UniqueCode,EdbInfoId } = Data;

      this.$router.replace({path:'/database', query: {
        code: UniqueCode,
        id: EdbInfoId
      }});

		},

		/* 获取目录结构 */
		getMenu() {
			dataBaseInterface.menuList().then((res) => {
				if (res.Ret !== 200) return
					this.filterNodes(res.Data.AllNodes);
					this.menuOptions = res.Data.AllNodes || [];
			});
		},
		// 递归改变第三级目录结构
		filterNodes(arr) {
			arr.length &&
				arr.forEach((item) => {
					item.Children.length && this.filterNodes(item.Children);
					if (item.Level === 2) {
						delete item.Children;
					}
				});
		},

		/* 选择目录 */
		menuChange(val) {
			this.formData.menu = val.length ? val[val.length - 1] : '';
		},

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

		searchApi(query,page=1) {
			if(!query){ this.searchOptions = []; return }   
			dataBaseInterface.targetSearchByPage({
				KeyWord:query,
				CurrentIndex: page,
				Source: this.fromType || 0,
			}).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);

			})
		},

		/* 聚焦获取当前检索 */
		inputFocusHandle(e) {
			this.search_page = 1;
			this.current_search = e.target.value;
			this.searchOptions = this.fromType ? [] : storage.get('pycode_seachlist');
			// this.searchApi(this.current_search);
		},

		searchLoad() {
			if(!this.search_have_more) return;
			this.searchApi(this.current_search,++this.search_page);
		},
	},
	mounted() {
		this.getEdbInfo();
		this.getMenu();
	},
}
</script>
<style lang='scss' scoped>
*{ box-sizing: border-box;}
.codecount-container {
	.header {
		display: flex;
		justify-content: space-between;
		align-items: center;
		font-size: 16px;
	}
	.bottom {
		height: calc(100vh - 240px);
		.bottom-wrapper {
			padding: 20px;
			height: 100%;
			border: 1px solid #ECECEC;
			border-radius: 4px;
			&:first-child {
				margin-right: 20px;
				padding: 20px 0;
			}
			.code-editor {
				padding: 0 20px;
			}
			.code-result {
				border-top: 1px solid #ECECEC;
				margin-top: 20px;
				padding: 20px;
			}

			.search-result {
				border-top: 1px solid #ECECEC;
				padding: 20px 0;
				table {
					width: 100%;
					margin-top: 22px;
					td{ border-color: #DCDFE6; width: 33%; height: 36px;text-align: center;}
				}
				.sql-code {
					min-height: 100px;
					border: 1px solid #DCDFE6;
					border-top: none;
				}
				.copy-btn {
					display: block;
					margin: 20px auto;
				}
			}
		}
	}
}
</style>
<style lang="scss">
.codecount-container {
	.el-tabs__nav-wrap::after {
		background-color: #fff;
	}
}
</style>