<template>
	<div id="southdirection-box">
		<div class="device-config">
			<h2>设备配置</h2>
			<div class="btn-list">
				<div class="btn-list-left">
					<el-button type="primary" @click="addDeviceConfig">新增配置</el-button>
					<!--          <el-button type="danger" @click="getDeviceConfig">删除</el-button>-->
				</div>
				<div class="btn-list-right">
					<el-button type="primary" style="margin-right: 10px" @click="exportDeviceConfigXlsx">导出</el-button>
					<!--          <el-button type="primary" @click="getDeviceConfig">导入</el-button>-->
					<el-upload action="#" :auto-upload="false" :on-change="handleFileChange" :show-file-list="false" style="margin-right: 10px">
						<el-button type="primary">导入</el-button>
					</el-upload>
					<el-button type="primary" @click="getDeviceConfig">获取配置</el-button>
					<el-button type="primary" @click="setDeviceConfig">设置配置</el-button>
				</div>
			</div>
			<div class="table-box">
				<el-table
					ref="deviceConfigTableRef"
					highlight-current-row
					:data="deviceConfigList"
					border
					height="187"
					:style="{ width: tabelBox + 'px', background: '#f2f2f2' }"
					empty-text="配置为空"
					row-key="index"
					@row-click="deviceConfigClick"
				>
					<el-table-column type="index" label="序号" align="center" width="60" />
					<el-table-column prop="equipId" label="设备ID">
						<template #default="scope">
							<el-input v-model="scope.row.equipId" placeholder="请输入设备ID" />
						</template>
					</el-table-column>
					<el-table-column prop="equipName" label="设备名">
						<template #default="scope">
							<el-input v-model="scope.row.equipName" placeholder="请输入设备名" />
						</template>
					</el-table-column>
					<el-table-column prop="protocol.libName" label="协议类型">
						<template #default="scope">
							<el-select v-model="scope.row.protocol.libName" placeholder="请选择协议类型">
								<el-option v-for="item in protocolList" :key="item.value" :label="item.label" :value="item.value" />
							</el-select>
						</template>
					</el-table-column>
					<el-table-column prop="interfaceParams.link" label="设备连接" />
					<el-table-column prop="protocol.params.linkPar" label="设备地址">
						<template #default="scope">
							<el-input v-model="scope.row.protocol.params.linkPar" placeholder="请输入设备地址" />
						</template>
					</el-table-column>
					<el-table-column label="高级选项" width="208">
						<template #default="scope">
							<el-button link type="primary" size="small" @click="openConnectModel(scope.row)">连接配置</el-button>
							<el-button link type="primary" size="small" @click="openCollectionModel(scope.row)">采集配置</el-button>
							<el-button link type="danger" size="small" @click="delDeviceConfig(scope.$index)">删除</el-button>
						</template>
					</el-table-column>
				</el-table>
			</div>
		</div>
		<div class="data-config">
			<h2>数据源配置 {{ activeDeviceConfig.equipId }}</h2>
			<div class="btn-list">
				<div class="btn-list-left">
					<el-button type="primary" @click="addDeviceDataConfig">新增配置</el-button>
					<!--          <el-button type="danger" @click="getDeviceConfig">删除</el-button>-->
				</div>
				<div class="btn-list-right">
					<el-button type="primary" style="margin-right: 10px" @click="exportDeviceDataConfigXlsx">导出</el-button>
					<el-upload action="#" :auto-upload="false" :on-change="handleFileChange" :show-file-list="false">
						<el-button type="primary">导入</el-button>
					</el-upload>
				</div>
			</div>
			<div class="table-box">
				<el-table
					ref="deviceDataTableRef"
					:data="activeDeviceConfig.properties"
					border
					size="small"
					height="100%"
					:style="{ width: tabelBox + 'px' }"
					empty-text="配置为空"
				>
					<el-table-column type="index" label="序号" align="center" width="60" fixed />
					<el-table-column prop="id" label="数据ID" fixed align="center">
						<template #default="scope">
							<el-input v-model="scope.row.id" placeholder="请输入数据ID" />
						</template>
					</el-table-column>
					<el-table-column prop="dataName" label="数据名" fixed align="center">
						<template #default="scope">
							<el-input v-model="scope.row.dataName" placeholder="请输入数据名" />
						</template>
					</el-table-column>
					<el-table-column prop="dataAddress" label="数据地址" align="center">
						<template #default="scope">
							<el-input v-model="scope.row.dataAddress" placeholder="请输入数据地址" />
						</template>
					</el-table-column>
					<el-table-column prop="dataDesc" label="描述" align="center">
						<template #default="scope">
							<el-input v-model="scope.row.dataDesc" placeholder="请输入描述" />
						</template>
					</el-table-column>
					<el-table-column prop="dataDisplay" label="数据类型" width="120" align="center">
						<template #default="scope">
							<el-select v-model="scope.row.dataDisplay" placeholder="请选择数据类型" @change="changedataDisplay($event, scope.$index)">
								<el-option v-for="item in dataTypeArray" :key="item.type" :value="item.type">{{ item.type }}</el-option>
								<!--                <el-option value="bool">bool</el-option>-->
								<!--                <el-option value="int8">int8</el-option>-->
								<!--                <el-option value="uint8">uint8</el-option>-->
								<!--                <el-option value="int16">int16</el-option>-->
								<!--                <el-option value="uint16">uint16</el-option>-->
								<!--                <el-option value="float">float</el-option>-->
								<!--                <el-option value="int32">int32</el-option>-->
								<!--                <el-option value="uint32">uint32</el-option>-->
								<!--                <el-option value="int64">int64</el-option>-->
								<!--                <el-option value="uint64">uint64</el-option>-->
								<!--                <el-option value="double">double</el-option>-->
								<!--                <el-option value="char">char</el-option>-->
								<!--                <el-option value="string">string</el-option>-->
								<!--                <el-option value="int16_AB">int16_AB</el-option>-->
								<!--                <el-option value="int16_BA">int16_BA</el-option>-->
								<!--                <el-option value="uint16_AB">uint16_AB</el-option>-->
								<!--                <el-option value="uint16_BA">uint16_BA</el-option>-->
								<!--                <el-option value="float_ABCD">float_ABCD</el-option>-->
								<!--                <el-option value="float_BADC">float_BADC</el-option>-->
								<!--                <el-option value="float_CDAB">float_CDAB</el-option>-->
								<!--                <el-option value="float_DCBA">float_DCBA</el-option>-->
								<!--                <el-option value="int32_ABCD">int32_ABCD</el-option>-->
								<!--                <el-option value="int32_BADC">int32_BADC</el-option>-->
								<!--                <el-option value="int32_CDAB">int32_CDAB</el-option>-->
								<!--                <el-option value="int32_DCBA">int32_DCBA</el-option>-->
								<!--                <el-option value="uint32_ABCD">uint32_ABCD</el-option>-->
								<!--                <el-option value="uint32_BADC">uint32_BADC</el-option>-->
								<!--                <el-option value="uint32_CDAB">uint32_CDAB</el-option>-->
								<!--                <el-option value="uint32_DCBA">uint32_DCBA</el-option>-->
							</el-select>
						</template>
					</el-table-column>
					<el-table-column prop="datalen" label="长度(字节)" width="120" align="center">
						<template #default="scope">
							<el-input v-model="scope.row.datalen" type="number" :disabled="!scope.row.datalenShow" placeholder="请输入长度(字节)" />
						</template>
					</el-table-column>
					<el-table-column prop="dataUnit" label="单位" width="70" align="center">
						<template #default="scope">
							<el-input v-model="scope.row.dataUnit" placeholder="请输入单位" />
						</template>
					</el-table-column>
					<el-table-column prop="authority" label="读写权限" width="90" align="center">
						<template #default="scope">
							<el-select v-model="scope.row.authority" placeholder="请选择读写权限">
								<el-option value="RW">RW</el-option>
								<el-option value="OR">OR</el-option>
								<el-option value="OW">OW</el-option>
							</el-select>
						</template>
					</el-table-column>
					<el-table-column prop="proportion" label="比例" width="70" align="center">
						<template #default="scope">
							<el-input v-model="scope.row.proportion" placeholder="请输入比例" />
						</template>
					</el-table-column>
					<el-table-column prop="offset" label="偏置" width="60" align="center">
						<template #default="scope">
							<el-input v-model="scope.row.offset" placeholder="请输入偏置" />
						</template>
					</el-table-column>
					<el-table-column prop="northCalcParam.decimal.numBits" label="小数位" width="60" align="center">
						<template #default="scope">
							<el-input v-model="scope.row.northCalcParam.decimal.numBits" placeholder="请输入小数位" />
						</template>
					</el-table-column>
					<el-table-column prop="northCalcParam.decimal.way" label="取整" align="center">
						<template #default="scope">
							<el-select v-model="scope.row.northCalcParam.decimal.way" placeholder="请选择取整">
								<el-option value="rounding" label="四舍五入"></el-option>
								<el-option value="flooring" label="全舍"></el-option>
								<el-option value="ceiling" label="全入"></el-option>
							</el-select>
						</template>
					</el-table-column>
					<el-table-column prop="driveFlag.isConclude_R" label="块读" width="50" align="center">
						<template #default="scope">
							<!--              <el-select v-model="scope.row.driveFlag.isConclude_R" placeholder="请选择块读">-->
							<!--                <el-option value="true">Yes</el-option>-->
							<!--                <el-option value="false">No</el-option>-->
							<!--              </el-select>-->
							<el-switch v-model="scope.row.driveFlag.isConclude_R" />
						</template>
					</el-table-column>
					<el-table-column prop="driveFlag.isConclude_W" label="块写" width="50" align="center">
						<template #default="scope">
							<!--              <el-select v-model="scope.row.driveFlag.isConclude_W" placeholder="请选择块写">-->
							<!--                <el-option value="true">Yes</el-option>-->
							<!--                <el-option value="false">No</el-option>-->
							<!--              </el-select>-->
							<el-switch v-model="scope.row.driveFlag.isConclude_W" />
						</template>
					</el-table-column>
					<el-table-column prop="taskId" label="任务ID" align="center">
						<template #default="scope">
							<el-select v-model="scope.row.taskId" placeholder="请选择任务ID" @change="changeTaskId($event, scope.$index)">
								<el-option v-for="(item, index) in taskList" :key="index" :value="item.taskId" :label="item.taskId"></el-option>
							</el-select>
						</template>
					</el-table-column>
					<el-table-column prop="uploadMode" label="上报策略" align="center">
						<template #default="scope">
							<!--              <el-select v-model="scope.row.uploadMode" placeholder="请选择上报策略">-->
							<!--                <el-option :value="item.uploadMode" v-for="(item,index) in taskList" :key="index" :label="item.uploadMode"></el-option>-->
							<!--              </el-select>-->
							<el-autocomplete
								v-model="scope.row.uploadMode"
								:fetch-suggestions="querySearch"
								clearable
								class="inline-input w-50"
								placeholder="请选择上报策略"
							/>
						</template>
					</el-table-column>
					<el-table-column label="操作" width="55" fixed="right" align="center">
						<template #default="scope">
							<el-button link type="danger" size="small" @click.stop="delDeviceDataConfig(scope.$index)">删除</el-button>
						</template>
					</el-table-column>
				</el-table>
			</div>
		</div>

		<el-dialog v-model="collectionModelShow" title="采集配置" width="500" :before-close="handleClose">
			<el-form ref="collectionRef" :model="collectionForm" label-width="auto" status-icon>
				<el-form-item label="启动">
					<el-switch v-model="collectionForm.collectConf.isRunCmd" />
				</el-form-item>
				<el-row>
					<el-col :span="12">
						<el-form-item label="轮询周期(ms)">
							<el-input v-model="collectionForm.collectConf.pollingCycleTime_ms" type="number" placeholder="请输入轮询周期(ms)" />
						</el-form-item>
					</el-col>
					<el-col :span="12" class="text-center">
						<el-form-item label="读通信最大时长(ms)">
							<el-input v-model="collectionForm.collectConf.allowTimeOut.read" type="number" placeholder="请输入读通信最大时长(ms)" />
						</el-form-item>
					</el-col>
				</el-row>
				<el-row>
					<el-col :span="12">
						<el-form-item label="通信间隔(ms)">
							<el-input v-model="collectionForm.collectConf.intervalTime_ms" type="number" placeholder="请输入通信间隔(ms)" />
						</el-form-item>
					</el-col>
					<el-col :span="12" class="text-center">
						<el-form-item label="写通信最大时长(ms)">
							<el-input v-model="collectionForm.collectConf.allowTimeOut.write" type="number" placeholder="请输入写通信最大时长(ms)" />
						</el-form-item>
					</el-col>
				</el-row>
				<el-form-item label="异常允许最大次数">
					<el-input v-model="collectionForm.collectConf.abnormalMax" type="number" placeholder="请输入异常允许最大次数" />
				</el-form-item>
				<el-form-item label="读归纳布尔量最大长度">
					<el-input v-model="collectionForm.inductionParam.maxLenBlock_read.boolArea" type="number" placeholder="请输入读归纳布尔量最大长度" />
				</el-form-item>
				<el-form-item label="读归纳字节最大长度">
					<el-input v-model="collectionForm.inductionParam.maxLenBlock_read.charArea" type="number" placeholder="请输入读归纳字节最大长度" />
				</el-form-item>
				<el-form-item label="写归纳布尔量最大长度">
					<el-input v-model="collectionForm.inductionParam.maxLenBlock_write.boolArea" type="number" placeholder="请输入写归纳布尔量最大长度" />
				</el-form-item>
				<el-form-item label="写归纳字节最大长度">
					<el-input v-model="collectionForm.inductionParam.maxLenBlock_write.charArea" type="number" placeholder="请输入写归纳字节最大长度" />
				</el-form-item>
			</el-form>
			<template #footer>
				<div class="dialog-footer">
					<el-button @click="collectionModelShow = false">取消</el-button>
					<el-button type="primary" @click="editCollection"> 确认 </el-button>
				</div>
			</template>
		</el-dialog>
		<!--  串口连接配置  -->
		<el-dialog v-model="dlt645ModelShow" title="连接配置" width="500">
			<el-form ref="dlt645Ref" :model="dlt645Form" label-width="auto" status-icon>
				<el-form-item label="端口" prop="port" required>
					<el-select v-model="dlt645Form.port" placeholder="选择端口" style="flex: 1">
						<el-option v-for="(item, index) in serialportList" :key="index" :label="item" :value="item" />
					</el-select>
					<el-button style="margin-left: 10px" type="primary" @click="getSerialPortList">获取端口列表</el-button>
				</el-form-item>
				<el-form-item label="波特率" prop="baudrate" required>
					<el-select v-model="dlt645Form.baudrate" placeholder="选择波特率">
						<el-option label="4800" value="4800" />
						<el-option label="9600" value="9600" />
						<el-option label="19200" value="19200" />
						<el-option label="43000" value="43000" />
						<el-option label="56000" value="56000" />
						<el-option label="115200" value="115200" />
					</el-select>
				</el-form-item>
				<el-form-item label="数据位" prop="databits" required>
					<el-select v-model="dlt645Form.databits" placeholder="选择数据位">
						<el-option label="5" value="5" />
						<el-option label="6" value="6" />
						<el-option label="7" value="7" />
						<el-option label="8" value="8" />
					</el-select>
				</el-form-item>
				<el-form-item label="停止位" prop="stopbits" required>
					<el-select v-model="dlt645Form.stopbits" placeholder="选择停止位">
						<el-option label="1" value="1" />
						<el-option label="1.5" value="15" />
						<el-option label="2" value="2" />
					</el-select>
				</el-form-item>
				<el-form-item label="校验位" prop="parity" required>
					<el-select v-model="dlt645Form.parity" placeholder="选择校验位">
						<el-option label="None" value="N" />
						<el-option label="Odd" value="O" />
						<el-option label="Even" value="E" />
						<!--            <el-option label="Mark" value="M" />-->
						<!--            <el-option label="Space" value="S" />-->
					</el-select>
				</el-form-item>
			</el-form>
			<template #footer>
				<div class="dialog-footer">
					<el-button @click="dlt645ModelShow = false">取消</el-button>
					<el-button type="primary" @click="editDlt645(dlt645Ref)"> 确认 </el-button>
				</div>
			</template>
		</el-dialog>
		<!--  TCP连接配置  -->
		<el-dialog v-model="tcpModelShow" title="连接配置" width="500">
			<el-form ref="tcpRef" :model="tcpForm" :rules="tcpFormRules" label-width="auto" status-icon>
				<el-form-item label="设备地址" prop="link" required>
					<el-input v-model="tcpForm.link" placeholder="请输入ip地址+端口：如192.168.0.1:80" />
				</el-form-item>
			</el-form>
			<template #footer>
				<div class="dialog-footer">
					<el-button @click="tcpModelShow = false">取消</el-button>
					<el-button type="primary" @click="editTcp(tcpRef)"> 确认 </el-button>
				</div>
			</template>
		</el-dialog>
	</div>
</template>

<script setup>
import { reactive, ref, onMounted, onUnmounted, watch } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { guidGenerator } from '/@/utils/function.js';
// 导入依赖
import FileSaver from 'file-saver';
import * as XLSX from 'xlsx';
import dayjs from 'dayjs';
import { getDeviceConf, getSerialPortDataList, setDeviceConf } from '/@/api/gateway/southdirection';

const dataTypeArray = ref([
	{ type: 'bool', datalen: 1, show: false },
	{ type: 'int8', datalen: 1, show: false },
	{ type: 'uint8', datalen: 1, show: false },
	{ type: 'int16', datalen: 2, show: false },
	{ type: 'uint16', datalen: 2, show: false },
	{ type: 'float', datalen: 4, show: false },
	{ type: 'int32', datalen: 4, show: false },
	{ type: 'uint32', datalen: 4, show: false },
	{ type: 'int64', datalen: 8, show: false },
	{ type: 'uint64', datalen: 8, show: false },
	{ type: 'double', datalen: 8, show: false },
	{ type: 'char', datalen: 1, show: false },
	{ type: 'string', datalen: null, show: true },
	{ type: 'int16_AB', datalen: 2, show: false },
	{ type: 'int16_BA', datalen: 2, show: false },
	{ type: 'uint16_AB', datalen: 2, show: false },
	{ type: 'uint16_BA', datalen: 2, show: false },
	{ type: 'float_ABCD', datalen: 4, show: false },
	{ type: 'float_BADC', datalen: 4, show: false },
	{ type: 'float_CDAB', datalen: 4, show: false },
	{ type: 'float_DCBA', datalen: 4, show: false },
	{ type: 'int32_ABCD', datalen: 4, show: false },
	{ type: 'int32_BADC', datalen: 4, show: false },
	{ type: 'int32_CDAB', datalen: 4, show: false },
	{ type: 'int32_DCBA', datalen: 4, show: false },
	{ type: 'uint32_ABCD', datalen: 4, show: false },
	{ type: 'uint32_BADC', datalen: 4, show: false },
	{ type: 'uint32_CDAB', datalen: 4, show: false },
	{ type: 'uint32_DCBA', datalen: 4, show: false },
]);

//上报策略
const uploadModeList = ref([
	{ value: 'timer 10', link: 'timer 10' },
	{ value: 'change 10', link: 'change 10' },
	{ value: 'timer 10 || change 10', link: 'timer 10 || change 10' },
	{ value: 'label LD200 up', link: 'label LD200 up' },
]);

const querySearch = (queryString, cb) => {
	const results = queryString ? uploadModeList.value.filter(createFilter(queryString)) : uploadModeList.value;
	cb(results);
};
const createFilter = (queryString) => {
	return (restaurant) => {
		return restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0;
	};
};
//北向任务列表（后面换请求获取）
const taskList = ref([]);
const deviceConfigTableRef = ref();
const deviceDataTableRef = ref();
const tabelBox = ref(884);
const deviceConfigList = ref([]);

const protocolList = ref([
	{ label: 'ModbusTCP', value: 'ModbusTCP' },
	{ label: 'DLT645_2007', value: 'DLT645_2007' },
	{ label: 'gycan', value: 'gycan' },
]);
//新增配置
const addDeviceConfig = () => {
	let newDeviceConfig = {
		id: guidGenerator(),
		collectConf: {
			// 数据采集配置
			abnormalMax: 3, // 异常最大次数
			allowTimeOut: { read: 2000, write: 2000 }, // 读写超时设置
			intervalTime_ms: 100, // 采集间隔时间
			isBlockRead: true, // 是否块读取
			isBlockWrite: true, // 是否块写入
			isRunCmd: true, // 是否运行命令
			pollingCycleTime_ms: 1000, // 轮询周期时间
		},
		conclude: { isUse: false, libName: '' }, // 结论库设置
		equipId: '', // 设备ID
		equipName: '', // 设备名称
		inductionParam: {
			// 感应参数设置
			maxLenBlock_read: { boolArea: -1, charArea: -1 }, // 读取最大长度
			maxLenBlock_write: { boolArea: -1, charArea: -1 }, // 写入最大长度
		},
		interfaceParams: { link: '', physicalInterface: '' }, // 接口参数
		properties: [],
		protocol: { libName: '', params: { linkPar: '' } }, // 通信协议设置
	};
	console.log('deviceConfigList.value', deviceConfigTableRef.value);
	deviceConfigList.value.push(newDeviceConfig);
	// activeDeviceConfig.value=newDeviceConfig;
};

//删除配置
const delDeviceConfig = (index) => {
	console.log('当前点击的行号', index);
	ElMessageBox.confirm('确认要删除该设备配置吗?', '告警', {
		confirmButtonText: '确认',
		cancelButtonText: '取消',
		type: 'warning',
	})
		.then(() => {
			deviceConfigList.value.splice(index, 1);
			ElMessage({
				type: 'success',
				message: '删除成功',
			});
		})
		.catch(() => {
			ElMessage({
				type: 'info',
				message: '取消删除',
			});
		});
};

const getDeviceConfig = () => {
	console.log('获取配置');
	getDeviceConf({})
		.then((response) => {
			// 成功响应后的处理
			console.log(response); // 打印响应数据
			if (response.code == 0) {
				//缓存上下行主题
				deviceConfigList.value = response.data.equips || [];
				taskList.value = response.data.tasks || [];
				if (deviceConfigList.value.length) {
					if (deviceConfigList.value.length > ActiveRowIndex.value) {
						activeDeviceConfig.value = deviceConfigList.value[ActiveRowIndex.value];
					} else {
						activeDeviceConfig.value = deviceConfigList.value[0];
					}
				} else {
					addDeviceConfig();
				}
			} else {
				ElMessage.error(response.message);
			}
		})
		.catch((error) => {
			// 错误处理
			console.error(error); // 打印错误信息
			ElMessage.error(error);
		});
};

const dataFormat = (data) => {
	console.log('数据格式化', deviceConfigList.value);
	let nowtaskList =
		taskList.value.map((item) => {
			item.dataIdEntire = [];
			return item;
		}) || [];
	if (nowtaskList.length > 0) {
		deviceConfigList.value.forEach((item) => {
			item.properties.forEach((property) => {
				let taskId = property.taskId;
				nowtaskList.forEach((task) => {
					if (task.taskId === taskId) {
						task.dataIdEntire.push({
							equipId: item.equipId,
							idInfo: [{ id: property.id, uploadMode: property.uploadMode }],
						});
					}
				});
			});
		});
	}

	return {
		equips: data,
		tasks: nowtaskList,
	};
};

const setDeviceConfig = () => {
	console.log('提交配置', deviceConfigList.value);
	let obj = dataFormat(deviceConfigList.value);
	console.log('数据格式化后', obj);
	setDeviceConf(obj)
		.then((response) => {
			// 成功响应后的处理
			console.log(response); // 打印响应数据
			if (response.code == 0) {
				ElMessage.success('保存成功');
			} else {
				ElMessage.error(response.message);
			}
		})
		.catch((error) => {
			// 错误处理
			console.error(error); // 打印错误信息
			ElMessage.error(error);
		});
};

//当选中索引
const ActiveRowIndex = ref(0);

const collectionModelShow = ref(false);
const collectionRef = ref();
const collectionForm = ref({
	collectConf: {
		// 数据采集配置
		abnormalMax: 3, // 异常最大次数
		allowTimeOut: { read: 2000, write: 2000 }, // 读写超时设置
		intervalTime_ms: 100, // 采集间隔时间
		isBlockRead: true, // 是否块读取
		isBlockWrite: true, // 是否块写入
		isRunCmd: true, // 是否运行命令
		pollingCycleTime_ms: 1000, // 轮询周期时间
	},
	inductionParam: {
		// 感应参数设置
		maxLenBlock_read: { boolArea: -1, charArea: -1 }, // 读取最大长度
		maxLenBlock_write: { boolArea: -1, charArea: -1 }, // 写入最大长度
	},
});
//打开采集配置弹窗
const openCollectionModel = (row) => {
	console.log('当前采集', row);
	collectionForm.value = {
		collectConf: row.collectConf,
		inductionParam: row.inductionParam,
	};
	collectionModelShow.value = true;
};

const editCollection = () => {
	deviceConfigList.value[ActiveRowIndex.value].collectConf = collectionForm.value.collectConf;
	deviceConfigList.value[ActiveRowIndex.value].inductionParam = collectionForm.value.inductionParam;
	collectionModelShow.value = false;
};

//连接配置

//串口配置
const dlt645ModelShow = ref(false);
const dlt645Ref = ref();
const serialportList = ref([]);
const dlt645Form = ref({
	port: '',
	baudrate: 115200,
	databits: 8,
	stopbits: 1,
	parity: 'N',
});
//获取端口列表
const getSerialPortList = (msgShow = true) => {
	getSerialPortDataList({})
		.then((response) => {
			// 成功响应后的处理
			if (response.code === 0) {
				serialportList.value = response.data.list || [];
				if (msgShow) {
					ElMessage.success('获取端口列表成功');
				}
			} else {
				ElMessage.error(response.message);
			}
		})
		.catch((error) => {
			// 错误处理
			ElMessage.error(error);
		});
};

const editDlt645 = (formEl) => {
	if (!formEl) return;
	formEl.validate((valid) => {
		if (valid) {
			deviceConfigList.value[ActiveRowIndex.value].interfaceParams.link =
				dlt645Form.value.port +
				',' +
				dlt645Form.value.baudrate +
				',' +
				dlt645Form.value.databits +
				',' +
				dlt645Form.value.stopbits +
				',' +
				dlt645Form.value.parity;
			deviceConfigList.value[ActiveRowIndex.value].interfaceParams.physicalInterface = dlt645Form.value.port;
			dlt645ModelShow.value = false;
		}
	});
};

//TCP配置
const tcpModelShow = ref(false);
const tcpRef = ref();
const tcpForm = ref({
	link: '192.168.0.1:80',
});

const tcpFormRules = reactive({
	link: [
		{ required: true, message: 'ip地址+端口', trigger: 'blur' },
		{ pattern: /^([0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]{1,5}$/, message: '格式错误格式应该是ip地址+端口如：192.168.0.1:80', trigger: 'blur' },
	],
});

//打开采集配置弹窗
const openConnectModel = (row) => {
	console.log('当前采集', row.protocol.libName);
	if (!row.protocol.libName) {
		ElMessage.error('请先选择通信类型');
	} else if (row.protocol.libName === 'DLT645_2007' || row.protocol.libName === 'gycan') {
		if (row.interfaceParams.link) {
			tcpForm.value.port = row.interfaceParams.link.split(',')[0];
			tcpForm.value.baudrate = row.interfaceParams.link.split(',')[1];
			tcpForm.value.databits = row.interfaceParams.link.split(',')[2];
			tcpForm.value.stopbits = row.interfaceParams.link.split(',')[3];
			tcpForm.value.parity = row.interfaceParams.link.split(',')[4];
		} else {
			tcpForm.value = {
				port: '',
				baudrate: 115200,
				databits: 8,
				stopbits: 1,
				parity: 'N',
			};
		}
		// getSerialPortList()
		dlt645ModelShow.value = true;
	} else if (row.protocol.libName === 'ModbusTCP') {
		tcpForm.value.link = row.interfaceParams.link;
		tcpModelShow.value = true;
	} else {
		ElMessage.error('暂不支持该通信类型');
	}
};

const editTcp = (formEl) => {
	if (!formEl) return;
	formEl.validate((valid) => {
		if (valid) {
			deviceConfigList.value[ActiveRowIndex.value].interfaceParams.link = tcpForm.value.link;
			tcpModelShow.value = false;
		}
	});
};

const activeDeviceConfig = ref({
	collectConf: {
		// 数据采集配置
		abnormalMax: 3, // 异常最大次数
		allowTimeOut: { read: 2000, write: 2000 }, // 读写超时设置
		intervalTime_ms: 100, // 采集间隔时间
		isBlockRead: true, // 是否块读取
		isBlockWrite: true, // 是否块写入
		isRunCmd: true, // 是否运行命令
		pollingCycleTime_ms: 1000, // 轮询周期时间
	},
	conclude: { isUse: false, libName: '' }, // 结论库设置
	equipId: 'dev102', // 设备ID
	equipName: 'dev102', // 设备名称
	inductionParam: {
		// 感应参数设置
		maxLenBlock_read: { boolArea: -1, charArea: -1 }, // 读取最大长度
		maxLenBlock_write: { boolArea: -1, charArea: -1 }, // 写入最大长度
	},
	interfaceParams: { link: '', physicalInterface: '' }, // 接口参数
	properties: [
		// 设备属性项，可包含多个属性
		{
			authority: 'RW', // 读写权限
			dataAddress: '', // 数据地址
			dataDesc: '', // 数据描述
			dataDisplay: 'int16', // 数据展示格式
			dataName: '', // 数据名称
			dataUnit: '', // 数据单位
			driveFlag: { isConclude_R: true, isConclude_W: true }, // 驱动标志
			id: '', // 属性ID
			northCalcParam: {
				// 北向计算参数
				decimal: { numBits: 1, way: 'rounding' }, // 小数处理方式
				offset: '0', // 偏移量
				proportion: '1', // 比例
			},
			offset: '0', // 偏移量
			proportion: '1', // 比例
			taskId: '', // 任务ID
			uploadMode: '', // 上报策略
		},
	],
	protocol: { libName: 'ModbusTCP', params: { linkPar: '' } }, // 通信协议设置
});

//添加数据源配置
const addDeviceDataConfig = () => {
	let newDeviceDataConfig = {
		authority: 'RW', // 读写权限
		dataAddress: '', // 数据地址
		dataDesc: '', // 数据描述
		dataDisplay: 'int16', // 数据展示格式
		datalen: 2, // 数据长度
		datalenShow: false, // 数据长度是否可编辑
		dataName: '', // 数据名称
		dataUnit: '', // 数据单位
		driveFlag: { isConclude_R: true, isConclude_W: true }, // 驱动标志
		id: '', // 属性ID
		northCalcParam: {
			// 北向计算参数
			decimal: { numBits: 1, way: 'rounding' }, // 小数处理方式
			offset: '0', // 偏移量
			proportion: '1', // 比例
		},
		offset: '0', // 偏移量
		proportion: '1', // 比例
		taskId: '', // 任务ID
		uploadMode: '', // 上报策略
	};
	activeDeviceConfig.value.properties.push(newDeviceDataConfig);
};

const changedataDisplay = (e, index) => {
	let dataTypeObj = dataTypeArray.value.filter((item) => item.type === e);
	activeDeviceConfig.value.properties[index].datalen = dataTypeObj[0].datalen;
	activeDeviceConfig.value.properties[index].datalenShow = dataTypeObj[0].show;
};

const changeTaskId = (e, index) => {
	let taskObj = taskList.value.filter((item) => item.taskId === e);
	activeDeviceConfig.value.properties[index].uploadMode = taskObj[0].uploadMode;
};

//删除数据源配置
const delDeviceDataConfig = (index) => {
	ElMessageBox.confirm('确认要删除该数据源配置吗?', '告警', {
		confirmButtonText: '确认',
		cancelButtonText: '取消',
		type: 'warning',
	})
		.then(() => {
			activeDeviceConfig.value.properties.splice(index, 1);
			ElMessage({
				type: 'success',
				message: '删除成功',
			});
		})
		.catch(() => {
			ElMessage({
				type: 'info',
				message: '取消删除',
			});
		});
};

//选择设备配置
const deviceConfigClick = (e, event, column) => {
	activeDeviceConfig.value = e;
	ActiveRowIndex.value = deviceConfigList.value.indexOf(e);
};

//更新表格宽度
const handleResize = () => {
	deviceDataTableRef.value.doLayout();
	tabelBox.value = window.innerWidth - 180 - 10;
};

const exportDeviceConfigXlsx = () => {
	const workbook = XLSX.utils.book_new();
	deviceConfigList.value.map((item) => {
		let dataArr = [];
		dataArr = item.properties.map((val) => {
			return {
				equipId: item.equipId,
				...val,
				isConclude_R: val.driveFlag.isConclude_R,
				isConclude_W: val.driveFlag.isConclude_W,
				offset: val.northCalcParam.offset,
				proportion: val.northCalcParam.proportion,
				numBits: val.northCalcParam.decimal.numBits,
				way: val.northCalcParam.decimal.way,
				equipName: item.equipName,
				protocol: item.protocol.libName,
				link: item.interfaceParams.link,
				linkPar: item.protocol.params.linkPar,
			};
		});
		// 将 JSON 数据转换为工作表
		let worksheet = XLSX.utils.json_to_sheet(dataArr);
		// 创建工作簿并添加工作表
		XLSX.utils.book_append_sheet(workbook, worksheet, '南向' + item.equipId);
	});
	// 将工作簿写入二进制数组
	const selIn = XLSX.write(workbook, { bookType: 'xlsx', bookSST: true, type: 'array' });
	try {
		FileSaver.saveAs(new Blob([selIn], { type: 'application/octet-stream' }), '网关南向采集配置' + dayjs().format('YYYY-MM-DD HH-mm-ss') + '.xlsx');
	} catch (e) {
		if (typeof console !== 'undefined') console.log(e, selIn);
	}
	return selIn;
};

const exportDeviceDataConfigXlsx = () => {
	const workbook = XLSX.utils.book_new();
	let dataArr = [];
	dataArr = activeDeviceConfig.value.properties.map((val) => {
		return {
			equipId: activeDeviceConfig.value.equipId,
			...val,
			isConclude_R: val.driveFlag.isConclude_R,
			isConclude_W: val.driveFlag.isConclude_W,
			offset: val.northCalcParam.offset,
			proportion: val.northCalcParam.proportion,
			numBits: val.northCalcParam.decimal.numBits,
			way: val.northCalcParam.decimal.way,
			equipName: activeDeviceConfig.value.equipName,
			libName: activeDeviceConfig.value.protocol.libName,
			link: activeDeviceConfig.value.interfaceParams.link,
			linkPar: activeDeviceConfig.value.protocol.params.linkPar,
		};
	});
	// 将 JSON 数据转换为工作表
	let worksheet = XLSX.utils.json_to_sheet(dataArr);
	// 创建工作簿并添加工作表
	XLSX.utils.book_append_sheet(workbook, worksheet, '南向' + activeDeviceConfig.value.equipId);
	// 将工作簿写入二进制数组
	const selIn = XLSX.write(workbook, { bookType: 'xlsx', bookSST: true, type: 'array' });
	try {
		FileSaver.saveAs(
			new Blob([selIn], { type: 'application/octet-stream' }),
			'网关南向采集数据源配置' + dayjs().format('YYYY-MM-DD HH-mm-ss') + '.xlsx'
		);
	} catch (e) {
		if (typeof console !== 'undefined') console.log(e, selIn);
	}
	return selIn;
};

const handleFileChange = (file, fileList) => {
	const rawFile = file.raw;
	if (!rawFile) {
		ElMessage.error('请选择一个文件');
		return;
	}

	const reader = new FileReader();
	reader.onload = (e) => {
		const data = new Uint8Array(e.target.result);
		const workbook = XLSX.read(data, { type: 'array' });

		// 解析所有工作表
		const sheets = {};
		workbook.SheetNames.forEach((sheetName) => {
			const sheet = workbook.Sheets[sheetName];
			const json = XLSX.utils.sheet_to_json(sheet);
			sheets[sheetName] = json;
		});

		for (var prop in sheets) {
			console.log(prop, sheets[prop]);
			let dataArr = sheets[prop];
			if (dataArr.length > 0) {
				let flag = true;
				deviceConfigList.value.forEach((item) => {
					if (item.equipId === dataArr[0].equipId) {
						flag = false;
						item.properties = dataArr.map((val) => {
							return {
								authority: val.authority, // 读写权限
								dataAddress: val.dataAddress, // 数据地址
								dataDesc: val.dataDesc, // 数据描述
								dataDisplay: val.dataDisplay, // 数据展示格式
								datalen: val.datalen,
								datalenShow: val.datalenShow, // 数据长度是否可编辑
								dataName: val.dataName, // 数据名称
								dataUnit: val.dataUnit, // 数据单位
								driveFlag: { isConclude_R: val.isConclude_R, isConclude_W: val.isConclude_W }, // 驱动标志
								id: val.id, // 属性ID
								northCalcParam: {
									// 北向计算参数
									decimal: { numBits: val.numBits, way: val.way }, // 小数处理方式
									offset: val.offset, // 偏移量
									proportion: val.proportion, // 比例
								},
								offset: val.offset, // 偏移量
								proportion: val.proportion, // 比例
								taskId: val.taskId, // 任务ID
								uploadMode: val.uploadMode, // 上报策略
							};
						});
						item.equipName = dataArr[0].equipName;
						item.protocol.libName = dataArr[0].protocol;
						item.interfaceParams.link = dataArr[0].link;
						item.protocol.params.linkPar = dataArr[0].linkPar;
					}
				});
				// 是否有新增
				if (flag) {
					let obj = {
						id: guidGenerator(),
						collectConf: {
							// 数据采集配置
							abnormalMax: 3, // 异常最大次数
							allowTimeOut: { read: 2000, write: 2000 }, // 读写超时设置
							intervalTime_ms: 100, // 采集间隔时间
							isBlockRead: true, // 是否块读取
							isBlockWrite: true, // 是否块写入
							isRunCmd: true, // 是否运行命令
							pollingCycleTime_ms: 1000, // 轮询周期时间
						},
						conclude: { isUse: false, libName: '' }, // 结论库设置
						equipId: dataArr[0].equipId, // 设备ID
						equipName: dataArr[0].equipName, // 设备名称
						inductionParam: {
							// 感应参数设置
							maxLenBlock_read: { boolArea: -1, charArea: -1 }, // 读取最大长度
							maxLenBlock_write: { boolArea: -1, charArea: -1 }, // 写入最大长度
						},
						interfaceParams: { link: dataArr[0].link, physicalInterface: '' }, // 接口参数
						properties: [],
						protocol: { libName: dataArr[0].protocol, params: { linkPar: dataArr[0].linkPar } }, // 通信协议设置
					};
					obj.properties = dataArr.map((val) => {
						return {
							authority: val.authority, // 读写权限
							dataAddress: val.dataAddress, // 数据地址
							dataDesc: val.dataDesc, // 数据描述
							dataDisplay: val.dataDisplay, // 数据展示格式
							datalen: val.datalen,
							datalenShow: val.datalenShow, // 数据长度是否可编辑
							dataName: val.dataName, // 数据名称
							dataUnit: val.dataUnit, // 数据单位
							driveFlag: { isConclude_R: val.isConclude_R, isConclude_W: val.isConclude_W }, // 驱动标志
							id: val.id, // 属性ID
							northCalcParam: {
								// 北向计算参数
								decimal: { numBits: val.numBits, way: val.way }, // 小数处理方式
								offset: val.offset, // 偏移量
								proportion: val.proportion, // 比例
							},
							offset: val.offset, // 偏移量
							proportion: val.proportion, // 比例
							taskId: val.taskId, // 任务ID
							uploadMode: val.uploadMode, // 上报策略
						};
					});
					deviceConfigList.value.push(obj);
				}
			}
		}

		// 你可以在这里处理解析后的数据
		ElMessage.success('导入成功');
	};
	reader.readAsArrayBuffer(rawFile);
};

onMounted(() => {
	window.addEventListener('resize', handleResize);
	getDeviceConfig();
	getSerialPortList(false);
	handleResize();
});

onUnmounted(() => {
	window.removeEventListener('resize', handleResize);
});
</script>

<style scoped lang="scss">
.el-table .double-clicked-row {
	background-color: #f0f9eb;
}
:deep(.el-table .el-scrollbar) {
	background: #fff;
}
#southdirection-box {
	position: absolute;
	width: 100%;
	height: 100%;
	.btn-list {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 10px 0;
		.btn-list-right {
			display: flex;
			align-items: center;
		}
	}
	.device-config {
		position: relative;
		overflow-y: auto;
	}
	.data-config {
		position: relative;
		height: calc(100% - 278px);
		.table-box {
			position: absolute;
			width: 100%;
			height: calc(100% - 162px);
		}
	}
	.table-box {
		//position: absolute;
		//width: 100%;
	}
}
</style>
<style>
.selected-row {
	background-color: #55e800;
}
</style>
