<template>
	<div class="home-container">
		<el-row :gutter="15" class="home-card-one mb15">
			<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6" v-for="(v, k) in homeOne" :key="k" :class="{ 'home-media home-media-lg': k > 1, 'home-media-sm': k === 1 }">
				<div class="home-card-top-part">
					<div class="top">
						<img :src="'/imgs/' + v.icoimg" class="icoimg">
						<div class="card-right">
							<span class="font30">{{ v.allnum }}</span>
							<div class="label">{{ v.num3 }}</div>
						</div>
					</div>
					<div class="divider"></div>
					<div class="card-bottom">
						<div class="flex" style="gap:10px">
							<img src="/@/assets/ok.svg" v-if="k < 2" alt="" class="icon">
							<img src="/@/assets/date.svg" v-else alt="" class="icon">
							<span class="info" :style="{ color: v.title1_bgcolor }">{{ v.title1 }}</span>
							<div class="num"> {{ v.num1 }}</div>
						</div>
						<div class="split"></div>
						<div class="flex" style="gap:10px">
							<img src="/@/assets/stop.svg" v-if="k < 2" alt="" class="icon">
							<img src="/@/assets/today.svg" v-else alt="" class="icon">
							<span class="info" :style="{ color: v.title2_bgcolor }">{{ v.title2 }}</span>
							<div class="num"> {{ v.num2 }}</div>
						</div>
					</div>
				</div>
			</el-col>
		</el-row>
		<el-row :gutter="15" class="home-card-two mb15">
			<el-col :xs="24" :sm="14" :md="14" :lg="16" :xl="16">
				<div class="home-card-item">
					<div style="height: 100%" ref="homeLineRef"></div>
				</div>
			</el-col>
			<el-col :xs="24" :sm="10" :md="10" :lg="8" :xl="8" class="home-media">
				<div class="home-card-item">
					<div style="height: 100%" ref="homePieRef"></div>
				</div>
			</el-col>
		</el-row>
		<el-row :gutter="15" class="home-card-three">
			<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
				<div class="home-card-item" style="height: auto;">
					<div class="home-card-item-title">
						<span>告警信息列表</span>
						<el-button size="small" text type="primary" @click="toMore()">更多信息</el-button>
					</div>
					<el-table :data="tableData.data" style="width: 100%" v-loading="loading">
						<el-table-column label="ID" align="center" prop="id" width="100" v-col="'ID'" />
						<el-table-column label="告警类型" width="120" prop="type" align="center" show-overflow-tooltip v-col="'type'">
							<template #default="scope">
								<span v-if="scope.row.type == 1">规则告警</span>
								<span v-else>设备自主告警</span>
							</template>
						</el-table-column>
						<el-table-column label="规则级别" width="120" align="center" prop="alarmLevel.name" show-overflow-tooltip v-col="'alarmLevel'" />
						<el-table-column label="规则名称" prop="ruleName" show-overflow-tooltip v-col="'ruleName'" />
						<el-table-column label="产品标识" prop="productKey" show-overflow-tooltip v-col="'productKey'" />
						<el-table-column label="设备标识" prop="deviceKey" show-overflow-tooltip v-col="'deviceKey'" />

						<el-table-column prop="status" label="告警状态" width="100" align="center" v-col="'status'">
							<template #default="scope">
								<el-tag type="success" size="small" v-if="scope.row.status">已处理</el-tag>
								<el-tag type="info" size="small" v-else>未处理</el-tag>
							</template>
						</el-table-column>
						<el-table-column prop="createdAt" label="告警时间" align="center" width="170" v-col="'createdAt'"></el-table-column>
						<el-table-column label="操作" width="130" align="center" fixed="right" v-col="'handle'">
							<template #default="scope">
								<el-button v-auth="'detail'" size="small" text type="primary" @click="onOpenDetailDic(scope.row)">详情</el-button>
								<el-button v-auth="'edit'" size="small" text type="warning" @click="onOpenEditDic(scope.row)" v-if="scope.row.status == 0">处理</el-button>
							</template>
						</el-table-column>
					</el-table>
				</div>
			</el-col>
		</el-row>

		<EditDic ref="editDicRef" @dataList="getAlarmList" />
		<DetailDic ref="detailRef" @dataList="getAlarmList" />
	</div>
</template>

<script lang="ts">
import { toRefs, reactive, defineComponent, onMounted, ref, watch, nextTick, onActivated, getCurrentInstance, onUnmounted } from 'vue';
import * as echarts from 'echarts';
import { useRouter, useRoute } from 'vue-router';
import { useStore } from '/@/store/index';

import api from '/@/api/datahub';
import dayjs from 'dayjs';

import EditDic from '../alarm/log/component/edit.vue';
import DetailDic from '../alarm/log/component/detail.vue';

let global: any = {
	homeChartOne: null,
	homeChartTwo: null,
	homeCharThree: null,
	dispose: [null, '', undefined]
};

export default defineComponent({
	name: 'home',
	components: { EditDic, DetailDic },
	setup() {
		// 页面是显示状态
		let isActice = true

		onUnmounted(() => {
			isActice = false
		})

		const { proxy } = getCurrentInstance() as any;
		const { alarm_type } = proxy.useDict('alarm_type');
		const alarmTypeMap: any = {}

		// 监听告警类型是否获取成功
		watch(() => alarm_type.value, (list) => {
			if (!list.length) return
			list.forEach((item: any) => {
				alarmTypeMap[item.value] = item.label
			});

			// 预警类型需要类型返回后才能请求
			getDeviceAlarmLevelCount()
		}, {
			immediate: true
		})

		const editDicRef = ref();
		const detailRef = ref();
		const homeLineRef = ref();
		const homePieRef = ref();
		const homeBarRef = ref();
		const store = useStore();
		const router = useRouter();
		const state = reactive({
			loading: false,
			tableData: {
				data: [],
				total: 0,
				loading: false,
				param: {
					pageNum: 1,
					pageSize: 20,
					status: '',
					dateRange: [],
				},
			},
			homeOne: [
				{
					allnum: 0,
					num1: 0,
					num2: 0,
					num3: '产品',
					num4: 'icon-zidingyibuju',
					color1: '#6690F9',
					color2: '--el-color-warning-lighter',
					color3: '--el-color-warning',
					icoimg: 'dashboard-icon1.svg',
					title1: '启用',
					title2: '停用',
					title1_bgcolor: '#3cd357',
					title2_bgcolor: '#FFBB73',

				},
				{
					allnum: 0,
					num1: 0,
					num2: 0,
					num3: '在线设备',
					num4: 'icon-putong',
					color1: '#FF6462',
					color2: '--next-color-primary-lighter',
					color3: '--el-color-primary',
					icoimg: 'dashboard-icon2.svg',
					title1: '启用',
					title2: '停用',
					title1_bgcolor: '#3cd357',
					title2_bgcolor: '#FFBB73',
				},
				{
					allnum: 0,
					num1: 0,
					num2: 0,
					num3: '设备消息',
					num4: 'icon-shidu',
					color1: '#6690F9',
					color2: '--el-color-success-lighter',
					color3: '--el-color-success',
					icoimg: 'dashboard-icon3.svg',
					title1: '本月',
					title2: '今日',
					title1_bgcolor: '#4285F4',
					title2_bgcolor: '#FFBB73',
				},
				{
					allnum: 0,
					num1: 0,
					num2: 0,
					num3: '设备告警',
					num4: 'icon-zaosheng',
					color1: '#6690F9',
					color2: '--el-color-warning-lighter',
					color3: '--el-color-warning',
					icoimg: 'dashboard-icon4.svg',
					title1: '本月',
					title2: '今日',
					title1_bgcolor: '#5ECCFF',
					title2_bgcolor: '#FFBB73',
				},
			],
			myCharts: [],
			charts: {
				theme: '',
				bgColor: '',
				color: '#303133',
			},
			lineChartXAxisData: [],
			lineChartMsgTotalData: [],
			lineChartAlarmTotalData: [],
			pieChartLegend: [],
			pieChartLevel: [],
			pieChartData: []
		});
		// 折线图
		const initLineChart = () => {
			if (!global.dispose.some((b: any) => b === global.homeChartOne)) global.homeChartOne.dispose();
			global.homeChartOne = <any>echarts.init(homeLineRef.value, state.charts.theme);
			const option = {
				backgroundColor: state.charts.bgColor,
				title: {
					text: '设备消息',
					x: 'left',
					textStyle: { fontSize: '15', color: state.charts.color },
				},
				grid: { top: 70, right: 20, bottom: 30, left: 50 },
				tooltip: { trigger: 'axis' },
				legend: { data: ['消息量', '预警量'], right: 0 },
				xAxis: {
					data: state.lineChartXAxisData
				},
				yAxis: [
					{
						type: 'value',
						name: '条数',
						splitLine: { show: true, lineStyle: { type: 'dashed', color: 'rgba(0, 0, 0, 0.03)' } },
						axisLabel: {
							margin: 2,
							formatter: function (value: any) {
								if (value >= 10000 && value < 10000000) {
									value = value / 10000 + "W";
								} else if (value >= 10000000) {
									value = value / 10000000 + "KW";
								}
								return value;
							}
						},
					},
				],
				series: [
					{
						name: '消息量',
						type: 'line',
						symbolSize: 0,
						symbol: 'circle',
						smooth: true,
						data: state.lineChartMsgTotalData,
						lineStyle: { color: '#FBBB04', width: 3 },
						itemStyle: { color: '#FBBB04', borderColor: '#FBBB04' },
						areaStyle: {
							color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
								{ offset: 0, color: 'rgba(251, 187, 4, 0.3)' },
								{ offset: 1, color: 'rgba(251, 187, 4, 0)' },
							]),
						},
					},
					{
						name: '预警量',
						type: 'line',
						symbolSize: 6,
						symbol: 'circle',
						smooth: true,
						data: state.lineChartAlarmTotalData,
						lineStyle: { color: '#4285F4', width: 3 },
						itemStyle: { color: '#4285F4', borderColor: '#4285F4' },
						areaStyle: {
							color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
								{ offset: 0, color: 'rgba(66, 133, 244, 0.3)' },
								{ offset: 1, color: 'rgba(66, 133, 244, 0)' },
							]),
						},
						emphasis: {
							itemStyle: {
								color: {
									type: 'radial',
									x: 0.5,
									y: 0.5,
									r: 0.5,
									colorStops: [
										{ offset: 0, color: '#9E87FF' },
										{ offset: 0.4, color: '#9E87FF' },
										{ offset: 0.5, color: '#fff' },
										{ offset: 0.7, color: '#fff' },
										{ offset: 0.8, color: '#fff' },
										{ offset: 1, color: '#fff' },
									],
								},
								borderColor: '#9E87FF',
								borderWidth: 2,
							},
						},
					},
				],
			};
			(<any>global.homeChartOne).setOption(option);
			(<any>state.myCharts).push(global.homeChartOne);
		};
		// 饼图
		const initPieChart = () => {
			if (!global.dispose.some((b: any) => b === global.homeChartTwo)) global.homeChartTwo.dispose();
			global.homeChartTwo = <any>echarts.init(homePieRef.value, state.charts.theme);
			var getname = state.pieChartLegend;
			var getvalue = state.pieChartData;
			var data = [];

			for (var i = 0; i < getname.length; i++) {
				data.push({ name: getname[i], value: getvalue[i] });
			}

			const colorList = ['#FF0000', '#4285F4', '#FBBB04', '#34A853', '#669'];
			const color = state.pieChartLevel.map(level => colorList[level - 1])

			const option = {
				color,
				backgroundColor: state.charts.bgColor,
				title: {
					text: '预警类型',
					x: 'left',
					textStyle: { fontSize: '15', color: state.charts.color },
				},
				// tooltip: { trigger: 'item', formatter: '{b} <br/> {c}%' },
				tooltip: { trigger: 'item' },
				graphic: {
					elements: [
						{
							type: 'image',
							z: -1,
							left: '16.5%',
							top: 'center',
						},
					],
				},
				legend: {
					type: 'scroll',
					orient: 'vertical',
					right: '0%',
					left: '65%',
					top: 'center',
					itemWidth: 14,
					itemHeight: 14,
					data: getname,
					textStyle: {
						rich: {
							name: {
								fontSize: 14,
								fontWeight: 400,
								width: 200,
								height: 35,
								padding: [0, 0, 0, 60],
								color: state.charts.color,
							},
							rate: {
								fontSize: 15,
								fontWeight: 500,
								height: 35,
								width: 40,
								padding: [0, 0, 0, 30],
								color: state.charts.color,
							},
						},
					},
				},
				series: [
					{
						type: 'pie',
						radius: ['70', '90'],
						center: ['32%', '50%'],
						padAngle: 1,
						label: { show: false },
						labelLine: { show: false },
						data: data,
					},
				],
			};
			(<any>global.homeChartTwo).setOption(option);
			(<any>state.myCharts).push(global.homeChartTwo);
		};
		// 批量设置 echarts resize
		const initEchartsResizeFun = () => {
			nextTick(() => {
				for (let i = 0; i < state.myCharts.length; i++) {
					setTimeout(() => {
						(<any>state.myCharts[i]).resize();
					}, i * 1000);
				}
			});
		};
		// 批量设置 echarts resize
		const initEchartsResize = () => {
			window.addEventListener('resize', initEchartsResizeFun);
		};

		// 定时获取设备，在线信息，告警数量更新
		const getOverviewData = () => {
			getProductCount()
			getDeviceDataTotalCount()
			getDeviceDataTotalCountMonth()
			getDeviceDataTotalCountDay()
			getDeviceOnlineOfflineCount()
			getDeviceAlarmLevelCountYear()
			getDeviceAlarmLevelCountMonth()
			getDeviceAlarmLevelCountDay()
			// 图形数据
			getDeviceDataCount()
		};

		// 普通数据3秒更新
		const intervalTimeLong = 3000

		function loopRquest(fun: Function, timeLong?: number) {
			setTimeout(() => {
				isActice && fun()
			}, timeLong || intervalTimeLong)
		}

		// 获取告警告警数量和消息数量绘图
		function getDeviceDataCount() {
			// 获取年度消息，年度告警数量
			Promise.all([api.iotManage.deviceDataCount('year'), api.iotManage.deviceAlertCountByYearMonth(dayjs().format('YYYY'))]).then(([msg, alarm]: any) => {
				const msgArr = msg?.data || []
				const alarmArr = alarm?.data || []
				// console.log(alarmArr)
				state.lineChartMsgTotalData = msgArr.map((item: any) => item.Value)
				state.lineChartXAxisData = msgArr.map((item: any) => item.Title)
				state.lineChartAlarmTotalData = alarmArr.map((item: any) => item.Value)
			}).finally(() => loopRquest(getDeviceDataCount, 60000))
		}

		// 获取告警告警数量和消息数量绘图
		function getDeviceAlarmLevelCount() {
			// 按告警级别统计 绘制饼图
			api.iotManage.deviceAlarmLevelCount('year', dayjs().format('YYYY')).then((res: any) => {
				const list = (res.data || []).sort((a: any, b: any) => b.Title - a.Title)
				state.pieChartLegend = list.map((item: any) => alarmTypeMap[item.Title])
				state.pieChartLevel = list.map((item: any) => item.Title)
				state.pieChartData = list.map((item: any) => item.Value)
			}).finally(() => loopRquest(getDeviceAlarmLevelCount, 60000))
		}

		// 产品数量
		function getProductCount() {
			api.iotManage.productCount().then((res: any) => {
				state.homeOne[0].allnum = res.total;
				state.homeOne[0].num1 = res.enable
				state.homeOne[0].num2 = res.disable
			}).finally(() => loopRquest(getProductCount))
		}

		// 设备数据总数
		function getDeviceDataTotalCount() {
			api.iotManage.deviceDataTotalCount('year').then((res: any) => {
				state.homeOne[2].allnum = res.number;
			}).finally(() => loopRquest(getDeviceDataTotalCount))
		}

		// 设备数据总数-月
		function getDeviceDataTotalCountMonth() {
			api.iotManage.deviceDataTotalCount('month').then((res: any) => {
				state.homeOne[2].num1 = res.number;
			}).finally(() => loopRquest(getDeviceDataTotalCountMonth))
		}

		// 设备数据总数-月
		function getDeviceDataTotalCountDay() {
			api.iotManage.deviceDataTotalCount('day').then((res: any) => {
				state.homeOne[2].num2 = res.number;
			}).finally(() => loopRquest(getDeviceDataTotalCountDay))
		}

		// 设备数量
		function getDeviceOnlineOfflineCount() {
			api.iotManage.deviceOnlineOfflineCount().then((res: any) => {
				state.homeOne[1].allnum = res.online;
				state.homeOne[1].num1 = res.total - res.disable
				state.homeOne[1].num2 = res.disable
			}).finally(() => loopRquest(getDeviceOnlineOfflineCount))
		}

		// 告警数量-年
		function getDeviceAlarmLevelCountYear() {
			api.iotManage.deviceAlarmLevelCount('year', dayjs().format('YYYY')).then((res: any) => {
				const list = (res.data || [])
				const total = list.reduce((a: any, b: any) => a + b.Value, 0)
				state.homeOne[3].allnum = total;
			}).finally(() => loopRquest(getDeviceAlarmLevelCountYear))
		}

		// 告警数量-月
		function getDeviceAlarmLevelCountMonth() {
			api.iotManage.deviceAlarmLevelCount('month', dayjs().format('M')).then((res: any) => {
				const total = (res.data || []).reduce((a: any, b: any) => a + b.Value, 0)
				state.homeOne[3].num1 = total;
			}).finally(() => loopRquest(getDeviceAlarmLevelCountMonth))
		}

		// 告警数量-日
		function getDeviceAlarmLevelCountDay() {
			api.iotManage.deviceAlarmLevelCount('day', dayjs().format('D')).then((res: any) => {
				const total = (res.data || []).reduce((a: any, b: any) => a + b.Value, 0)
				state.homeOne[3].num2 = total;
			}).finally(() => loopRquest(getDeviceAlarmLevelCountDay))
		}

		const getAlarmList = () => {
			api.iotManage.getAlarmList(state.tableData.param).then((res: any) => {
				state.tableData.data = res.list;
				state.tableData.total = res.Total;
			})
		}
		//打开详情页
		const onOpenDetailDic = (row: any) => {
			detailRef.value.openDialog(row);
		};
		// 打开修改产品弹窗
		const onOpenEditDic = (row: any) => {
			editDicRef.value.openDialog(row);
		};
		// 告警信息-更多信息
		const toMore = () => {
			router.push({ path: '/iotmanager/alarm/log' });
		};
		// 页面加载时
		onMounted(() => {
			initEchartsResize();
			getOverviewData();
			getAlarmList();
		});
		// 由于页面缓存原因，keep-alive
		onActivated(() => {
			initEchartsResizeFun();
		});
		// 监听 vuex 中的 tagsview 开启全屏变化，重新 resize 图表，防止不出现/大小不变等
		watch(
			() => store.state.tagsViewRoutes.isTagsViewCurrenFull,
			() => {
				initEchartsResizeFun();
			}
		);
		watch(
			() => state.lineChartAlarmTotalData,
			() => {
				initLineChart();
			}
		);
		watch(
			() => state.pieChartData,
			() => {
				initPieChart();
			}
		);
		// 监听 vuex 中是否开启深色主题
		watch(
			() => store.state.themeConfig.themeConfig.isIsDark,
			(isIsDark) => {
				nextTick(() => {
					state.charts.theme = isIsDark ? 'dark' : '';
					state.charts.bgColor = isIsDark ? 'transparent' : '';
					state.charts.color = isIsDark ? '#dadada' : '#303133';
					setTimeout(() => {
						initLineChart();
					}, 500);
					setTimeout(() => {
						initPieChart();
					}, 700);
				});
			},
			{
				deep: true,
				immediate: true,
			}
		);
		watch(
			() => state.lineChartMsgTotalData,
			() => {
				initLineChart();
			}
		);
		return {
			homeLineRef,
			homePieRef,
			homeBarRef,
			detailRef,
			editDicRef,
			toMore,
			onOpenEditDic,
			getAlarmList,
			onOpenDetailDic,
			getOverviewData,
			...toRefs(state),
		};
	},
});
</script>

<style scoped lang="scss">
$homeNavLengh: 8;

.home-card-top-part {
	background-color: var(--el-color-white);
	border-radius: 8px;
	padding: 20px 20px;

	.top {
		display: flex;
		justify-content: space-around;
		overflow: hidden;
		align-items: center;
	}

	.icoimg {
		width: 54px !important;
		height: 54px !important;
		margin-right: 12px;
	}

	.label {
		font-size: 14px;
		font-weight: 500;
	}

	.divider {
		border-top: 1px solid var(--el-border-color-light);
		margin: 12px 0 15px;

	}

	.card-right {
		flex: 1;
		display: flex;
		flex-direction: column;
		justify-content: space-between;
		white-space: nowrap;
		line-height: 1;
		height: 54px;

		.font30 {
			color: #4285F4;
			font-weight: bold;
			font-size: 30px;
		}

	}

	.card-bottom {
		font-size: 12px;
		display: flex;
		align-items: center;
		justify-content: space-around;
		gap: 12px;
		white-space: nowrap;

		.split {
			border-right: 1px solid var(--el-border-color-light);
			height: 20px;
		}

		.icon {
			width: 17px;
			height: 17px;

		}

		.info {
			font-size: 12px;
			font-weight: 500;
		}
	}
}

.home-container {
	overflow: hidden;

	.home-card-one,
	.home-card-two,
	.home-card-three {
		.icoimg {
			width: 75px;
			height: 75px;
		}

		.title_status {
			width: 7px;
			height: 7px;
			background: #c1bbbb;
			border-radius: 50px;
			margin-right: 5px;
		}

		.home-card-item,
		.home-card-top {
			width: 100%;
			height: 130px;
			border-radius: 8px;
			transition: all ease 0.3s;
			padding: 10px 20px;
			overflow: hidden;
			background: var(--el-color-white);
			color: var(--el-text-color-primary);

			// border: 1px solid var(--next-border-color-light);
			&:hover {
				// box-shadow: 0 2px 12px var(--next-color-dark-hover);
				transition: all ease 0.3s;
			}

			&-icon {
				width: 70px;
				height: 70px;
				border-radius: 100%;
				flex-shrink: 1;

				i {
					color: var(--el-text-color-placeholder);
				}
			}

			&-title {
				font-size: 15px;
				font-weight: bold;
				height: 30px;
			}
		}
	}

	.home-card-three {
		.home-card-item-title {
			display: flex;
			justify-content: space-between;
			// span:nth-child(2) {
			// 	color: #409eff;
			// }
		}
	}

	.home-card-one {
		@for $i from 0 through 3 {
			.home-one-animation#{$i} {
				opacity: 0;
				animation-name: error-num;
				animation-duration: 0.5s;
				animation-fill-mode: forwards;
				animation-delay: calc($i/10) + s;
			}
		}
	}

	.home-card-two,
	.home-card-three {
		.home-card-item {
			height: 300px;
		}

		.home-card-top {
			height: 250px;

			.box-card {
				padding: 15px 20px 20px 10px;

				p {
					margin-bottom: 10px;
				}

				&-item {
					margin-bottom: 10px;
				}
			}
		}

		.home-card-item,
		.home-card-top {
			width: 100%;
			overflow: hidden;

			.home-monitor {
				height: 100%;

				.flex-warp-item {
					width: 25%;
					height: 111px;
					display: flex;

					.flex-warp-item-box {
						margin: auto;
						text-align: center;
						color: var(--el-text-color-primary);
						display: flex;
						border-radius: 5px;
						background: var(--next-bg-color);
						cursor: pointer;
						transition: all 0.3s ease;

						&:hover {
							background: var(--el-color-primary-light-9);
							transition: all 0.3s ease;
						}
					}

					@for $i from 0 through $homeNavLengh {
						.home-animation#{$i} {
							opacity: 0;
							animation-name: error-num;
							animation-duration: 0.5s;
							animation-fill-mode: forwards;
							animation-delay: calc($i/10) + s;
						}
					}
				}
			}
		}
	}

	.text-info {
		color: #23c6c8;
	}

	.text-danger {
		color: #ed5565;
	}

	.git-res {
		margin-top: 20px;
	}

	.git-res .el-link {
		margin-right: 30px;
	}

	ul,
	li {
		padding: 0;
		margin: 0;
		list-style: none
	}

	.product {
		margin-top: 50px;

		h3 {
			margin-bottom: 15px;
		}
	}

	.product li {
		margin-bottom: 20px;
		float: left;
		width: 150px;
	}

	.box-card.xx {
		margin-top: 20px;
	}
}
</style>
