<template>
    <div>
        <el-row :gutter="20" class="row-box">
            <el-col :span="8">
                <el-card class="el-card">
                    <template #header>
                        <div class="card-header">
                            <span>{{ $t('home.overview') }}</span>
                        </div>
                    </template>
                    <el-row :gutter="20">
                        <el-col :span="12">
                            <el-card style="font-size: 12px; height: 80px; border-radius: 10px">
                                <svg-icon style="float: left; margin-left: 5px" iconName="p-website"></svg-icon>
                                <span style="float: left; margin-left: 5px; margin-top: 10px">
                                    {{ $t('menu.website') }}
                                </span>
                                <el-link
                                    style="float: right; font-size: 24px; margin-right: 5px"
                                    @click="goRouter('/websites')"
                                    type="primary"
                                >
                                    {{ baseInfo?.websiteNumber }}
                                </el-link>
                            </el-card>
                        </el-col>
                        <el-col :span="12">
                            <el-card style="font-size: 12px; height: 80px; border-radius: 10px">
                                <svg-icon style="float: left; margin-left: 5px" iconName="p-database"></svg-icon>
                                <span style="float: left; margin-left: 5px; margin-top: 10px">
                                    {{ $t('menu.database') }}
                                </span>
                                <el-link
                                    style="float: right; font-size: 24px; margin-right: 5px"
                                    @click="goRouter('/databases')"
                                    type="primary"
                                >
                                    {{ baseInfo?.databaseNumber }}
                                </el-link>
                            </el-card>
                        </el-col>
                    </el-row>
                    <el-row :gutter="20" style="margin-top: 20px; margin-top: 30px">
                        <el-col :span="12">
                            <el-card style="font-size: 12px; height: 80px; border-radius: 10px">
                                <svg-icon style="float: left; margin-left: 5px" iconName="p-plan"></svg-icon>
                                <span style="float: left; margin-left: 5px; margin-top: 10px">
                                    {{ $t('menu.cronjob') }}
                                </span>
                                <el-link
                                    style="float: right; font-size: 24px; margin-right: 5px"
                                    @click="goRouter('/cronjobs')"
                                    type="primary"
                                >
                                    {{ baseInfo?.cronjobNumber }}
                                </el-link>
                            </el-card>
                        </el-col>
                        <el-col :span="12">
                            <el-card style="font-size: 12px; height: 80px; border-radius: 10px">
                                <svg-icon style="float: left; margin-left: 5px" iconName="p-appstore"></svg-icon>
                                <span style="float: left; margin-left: 5px; margin-top: 10px">
                                    {{ $t('home.appInstalled') }}
                                </span>
                                <el-link
                                    style="float: right; font-size: 24px; margin-right: 5px"
                                    @click="goRouter('/apps')"
                                    type="primary"
                                >
                                    {{ baseInfo?.appInstalldNumber }}
                                </el-link>
                            </el-card>
                        </el-col>
                    </el-row>
                </el-card>
            </el-col>
            <el-col :span="8">
                <el-card class="el-card">
                    <template #header>
                        <div class="card-header">
                            <span>{{ $t('commons.table.status') }}</span>
                        </div>
                    </template>
                    <Status ref="statuRef" />
                </el-card>
            </el-col>
            <el-col :span="8">
                <el-card class="el-card">
                    <template #header>
                        <div class="card-header">
                            <span>{{ $t('home.systemInfo') }}</span>
                        </div>
                    </template>
                    <el-form>
                        <el-form-item :label="$t('home.hostname')">{{ baseInfo.hostname }}</el-form-item>
                        <el-form-item :label="$t('home.platformVersion')">
                            {{ baseInfo.platform }}-{{ baseInfo.platformVersion }}
                        </el-form-item>
                        <el-form-item :label="$t('home.kernelVersion')">
                            {{ baseInfo.kernelVersion }}
                        </el-form-item>
                        <el-form-item :label="$t('home.kernelArch')">{{ baseInfo.kernelArch }}</el-form-item>
                        <el-form-item :label="$t('home.uptime')">{{ baseInfo.uptime }}</el-form-item>
                        <el-form-item :label="$t('home.runningTime')">{{ baseInfo.timeSinceUptime }}</el-form-item>
                    </el-form>
                </el-card>
            </el-col>
        </el-row>
        <el-row :gutter="20" style="margin-top: 20px" class="row-box">
            <el-col :span="12">
                <App ref="appRef" />
            </el-col>
            <el-col :span="12">
                <el-card class="el-card">
                    <el-radio-group v-model="chartOption" @change="changeOption">
                        <el-radio-button label="network">{{ $t('home.network') }}</el-radio-button>
                        <el-radio-button label="io">{{ $t('home.io') }}</el-radio-button>
                    </el-radio-group>
                    <el-select
                        v-if="chartOption === 'network'"
                        @change="onLoadBaseInfo(false, 'network')"
                        v-model="searchInfo.netOption"
                        style="float: right"
                    >
                        <el-option v-for="item in netOptions" :key="item" :label="item" :value="item" />
                    </el-select>
                    <el-select
                        v-if="chartOption === 'io'"
                        v-model="searchInfo.ioOption"
                        @change="onLoadBaseInfo(false, 'io')"
                        style="float: right"
                    >
                        <el-option v-for="item in ioOptions" :key="item" :label="item" :value="item" />
                    </el-select>
                    <div style="margin-top: 20px" v-if="chartOption === 'network'">
                        <el-tag>{{ $t('monitor.up') }}: {{ currentChartInfo.netBytesSent }} KB/s</el-tag>
                        <el-tag style="margin-left: 20px">
                            {{ $t('monitor.down') }}: {{ currentChartInfo.netBytesRecv }} KB/s
                        </el-tag>
                        <el-tag style="margin-left: 20px">
                            {{ $t('home.totalSend') }}: {{ computeSize(currentInfo.netBytesSent) }}
                        </el-tag>
                        <el-tag style="margin-left: 20px">
                            {{ $t('home.totalRecv') }}: {{ computeSize(currentInfo.netBytesRecv) }}
                        </el-tag>
                    </div>
                    <div style="margin-top: 20px" v-if="chartOption === 'io'">
                        <el-tag>{{ $t('monitor.read') }}: {{ currentChartInfo.ioReadBytes }} MB</el-tag>
                        <el-tag style="margin-left: 20px">
                            {{ $t('monitor.write') }}: {{ currentChartInfo.ioWriteBytes }} MB
                        </el-tag>
                        <el-tag style="margin-left: 20px">
                            {{ $t('home.rwPerSecond') }}: {{ currentChartInfo.ioCount }} {{ $t('home.time') }}
                        </el-tag>
                        <el-tag style="margin-left: 20px">
                            {{ $t('home.rwPerSecond') }}: {{ currentInfo.ioTime }} ms
                        </el-tag>
                    </div>
                    <div
                        v-if="chartOption === 'io'"
                        id="ioChart"
                        style="margin-top: 20px; width: 100%; height: 320px"
                    ></div>
                    <div
                        v-if="chartOption === 'network'"
                        id="networkChart"
                        style="margin-top: 20px; width: 100%; height: 320px"
                    ></div>
                </el-card>
            </el-col>
        </el-row>
    </div>
</template>

<script lang="ts" setup>
import { onMounted, onBeforeUnmount, ref, reactive } from 'vue';
import * as echarts from 'echarts';
import Status from '@/views/home/status/index.vue';
import App from '@/views/home/app/index.vue';
import i18n from '@/lang';
import { Dashboard } from '@/api/interface/dashboard';
import { dateFromatForSecond, computeSize } from '@/utils/util';
import { useRouter } from 'vue-router';
import { loadBaseInfo, loadCurrentInfo } from '@/api/modules/dashboard';
import { getIOOptions, getNetworkOptions } from '@/api/modules/monitor';
const router = useRouter();

const statuRef = ref();
const appRef = ref();

const chartOption = ref('network');
let timer: NodeJS.Timer | null = null;
let isInit = ref<boolean>(true);

const ioReadBytes = ref<Array<number>>([]);
const ioWriteBytes = ref<Array<number>>([]);
const netBytesSents = ref<Array<number>>([]);
const netBytesRecvs = ref<Array<number>>([]);
const timeIODatas = ref<Array<string>>([]);
const timeNetDatas = ref<Array<string>>([]);

const ioOptions = ref();
const netOptions = ref();
const searchInfo = reactive({
    ioOption: 'all',
    netOption: 'all',
});

const baseInfo = ref<Dashboard.BaseInfo>({
    haloID: 0,
    dateeaseID: 0,
    jumpserverID: 0,
    metersphereID: 0,
    kubeoperatorID: 0,
    kubepiID: 0,

    websiteNumber: 0,
    databaseNumber: 0,
    cronjobNumber: 0,
    appInstalldNumber: 0,

    hostname: '',
    os: '',
    platform: '',
    platformFamily: '',
    platformVersion: '',
    kernelArch: '',
    kernelVersion: '',
    virtualizationSystem: '',
    uptime: '',
    timeSinceUptime: '',

    cpuCores: 0,
    cpuLogicalCores: 0,
    cpuModelName: '',
    currentInfo: null,
});
const currentInfo = ref<Dashboard.CurrentInfo>({
    procs: 0,

    load1: 0,
    load5: 0,
    load15: 0,
    loadUsagePercent: 0,

    cpuPercent: [] as Array<number>,
    cpuUsedPercent: 0,
    cpuUsed: 0,
    cpuTotal: 0,

    memoryTotal: 0,
    memoryAvailable: 0,
    memoryUsed: 0,
    MemoryUsedPercent: 0,

    ioReadBytes: 0,
    ioWriteBytes: 0,
    ioTime: 0,
    ioCount: 0,

    total: 0,
    free: 0,
    used: 0,
    usedPercent: 0,

    inodesTotal: 0,
    inodesUsed: 0,
    inodesFree: 0,
    inodesUsedPercent: 0,

    netBytesSent: 0,
    netBytesRecv: 0,

    shotTime: new Date(),
});
const currentChartInfo = reactive({
    ioReadBytes: 0,
    ioWriteBytes: 0,
    ioCount: 0,

    netBytesSent: 0,
    netBytesRecv: 0,
});

const changeOption = async () => {
    isInit.value = true;
    loadData();
};

const goRouter = async (path: string) => {
    router.push({ path: path });
};

const onLoadNetworkOptions = async () => {
    const res = await getNetworkOptions();
    netOptions.value = res.data;
    searchInfo.netOption = netOptions.value && netOptions.value[0];
};

const onLoadIOOptions = async () => {
    const res = await getIOOptions();
    ioOptions.value = res.data;
    searchInfo.ioOption = ioOptions.value && ioOptions.value[0];
};

const onLoadBaseInfo = async (isInit: boolean, range: string) => {
    if (range === 'all' || range === 'io') {
        ioReadBytes.value = [];
        ioWriteBytes.value = [];
        timeIODatas.value = [];
    } else if (range === 'all' || range === 'network') {
        netBytesSents.value = [];
        netBytesRecvs.value = [];
        timeNetDatas.value = [];
    }
    const res = await loadBaseInfo(searchInfo.ioOption, searchInfo.netOption);
    baseInfo.value = res.data;
    currentInfo.value = baseInfo.value.currentInfo;
    if (baseInfo.value.timeSinceUptime) {
        baseInfo.value.timeSinceUptime.replaceAll('days', i18n.global.t('home.Day'));
        baseInfo.value.timeSinceUptime.replaceAll('hours', i18n.global.t('home.Hour'));
        baseInfo.value.timeSinceUptime.replaceAll('minutes', i18n.global.t('home.Minute'));
    }
    onLoadCurrentInfo();
    statuRef.value.acceptParams(currentInfo.value, baseInfo.value);
    appRef.value.acceptParams(baseInfo.value);
    if (isInit) {
        window.addEventListener('resize', changeChartSize);
        timer = setInterval(async () => {
            onLoadCurrentInfo();
        }, 3000);
    }
};

const onLoadCurrentInfo = async () => {
    const res = await loadCurrentInfo(searchInfo.ioOption, searchInfo.netOption);
    currentChartInfo.netBytesSent = Number(
        ((res.data.netBytesSent - currentInfo.value.netBytesSent) / 1024 / 3).toFixed(2),
    );
    netBytesSents.value.push(currentChartInfo.netBytesSent);
    if (netBytesSents.value.length > 20) {
        netBytesSents.value.splice(0, 1);
    }
    currentChartInfo.netBytesRecv = Number(
        ((res.data.netBytesRecv - currentInfo.value.netBytesRecv) / 1024 / 3).toFixed(2),
    );
    netBytesRecvs.value.push(currentChartInfo.netBytesRecv);
    if (netBytesRecvs.value.length > 20) {
        netBytesRecvs.value.splice(0, 1);
    }

    currentChartInfo.ioReadBytes = Number(
        ((res.data.ioReadBytes - currentInfo.value.ioReadBytes) / 1024 / 1024 / 3).toFixed(2),
    );
    ioReadBytes.value.push(currentChartInfo.ioReadBytes);
    if (ioReadBytes.value.length > 20) {
        ioReadBytes.value.splice(0, 1);
    }
    currentChartInfo.ioWriteBytes = Number(
        ((res.data.ioWriteBytes - currentInfo.value.ioWriteBytes) / 1024 / 1024 / 3).toFixed(2),
    );
    ioWriteBytes.value.push(currentChartInfo.ioWriteBytes);
    if (ioWriteBytes.value.length > 20) {
        ioWriteBytes.value.splice(0, 1);
    }
    currentChartInfo.ioCount = Number(((res.data.ioCount - currentInfo.value.ioCount) / 3).toFixed(2));

    timeIODatas.value.push(dateFromatForSecond(res.data.shotTime));
    if (timeIODatas.value.length > 20) {
        timeIODatas.value.splice(0, 1);
    }
    timeNetDatas.value.push(dateFromatForSecond(res.data.shotTime));
    if (timeNetDatas.value.length > 20) {
        timeNetDatas.value.splice(0, 1);
    }
    loadData();
    currentInfo.value = res.data;
    statuRef.value.acceptParams(currentInfo.value, baseInfo.value);
};

const loadData = async () => {
    if (chartOption.value === 'io') {
        let ioReadYDatas = {
            name: i18n.global.t('monitor.read'),
            type: 'line',
            smooth: true,
            areaStyle: {
                color: '#ebdee3',
            },
            data: ioReadBytes.value,
            showSymbol: false,
        };
        let ioWriteYDatas = {
            name: i18n.global.t('monitor.write'),
            type: 'line',
            smooth: true,
            areaStyle: {
                color: '#ebdee3',
            },
            data: ioWriteBytes.value,
            showSymbol: false,
        };
        freshChart(
            'ioChart',
            [i18n.global.t('monitor.read'), i18n.global.t('monitor.write')],
            timeIODatas.value,
            [ioReadYDatas, ioWriteYDatas],
            i18n.global.t('monitor.network'),
            'MB',
        );
    } else {
        let netTxYDatas = {
            name: i18n.global.t('monitor.up'),
            type: 'line',
            smooth: true,
            areaStyle: {
                color: '#ebdee3',
            },
            data: netBytesRecvs.value,
            showSymbol: false,
        };
        let netRxYDatas = {
            name: i18n.global.t('monitor.down'),
            type: 'line',
            smooth: true,
            areaStyle: {
                color: '#ebdee3',
            },
            data: netBytesSents.value,
            showSymbol: false,
        };
        freshChart(
            'networkChart',
            [i18n.global.t('monitor.up'), i18n.global.t('monitor.down')],
            timeNetDatas.value,
            [netTxYDatas, netRxYDatas],
            i18n.global.t('monitor.network'),
            'KB/s',
        );
    }
};

function freshChart(chartName: string, legendDatas: any, xDatas: any, yDatas: any, yTitle: string, formatStr: string) {
    if (isInit.value) {
        echarts.init(document.getElementById(chartName) as HTMLElement);
        isInit.value = false;
    }
    let itemChart = echarts.getInstanceByDom(document.getElementById(chartName) as HTMLElement);
    const option = {
        title: [
            {
                left: 'center',
                text: yTitle,
            },
        ],
        zlevel: 1,
        z: 1,
        tooltip: {
            trigger: 'axis',
            formatter: function (datas: any) {
                let res = datas[0].name + '<br/>';
                for (const item of datas) {
                    res += item.marker + ' ' + item.seriesName + '：' + item.data + formatStr + '<br/>';
                }
                return res;
            },
        },
        grid: { left: '7%', right: '7%', bottom: '20%' },
        legend: {
            data: legendDatas,
            right: 10,
        },
        xAxis: { data: xDatas, boundaryGap: false },
        yAxis: { name: '( ' + formatStr + ' )' },
        series: yDatas,
    };
    itemChart?.setOption(option, true);
}

function changeChartSize() {
    echarts.getInstanceByDom(document.getElementById('ioChart') as HTMLElement)?.resize();
    echarts.getInstanceByDom(document.getElementById('networkChart') as HTMLElement)?.resize();
}

onMounted(() => {
    onLoadNetworkOptions();
    onLoadIOOptions();
    onLoadBaseInfo(true, 'all');
});

onBeforeUnmount(() => {
    clearInterval(Number(timer));
    timer = null;
    window.removeEventListener('resize', changeChartSize);
});
</script>

<style scoped>
.card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
}
</style>
