<template>
    <div class="analyze-steadyState" v-loading="loading">
        <analyzeTree ref="treeRef" :showCheckbox="true" :default-checked-keys="checkedKeyIds" @check="onCheck"
            :height="40" :engineering="true" />
        <div class="analyze-steadyState-right">
            <div ref="headerRef">
                <TableHeader :showSearch="false" ref="tableHeaderRef" @selectChange="selectChange">
                    <template v-slot:select>
                        <el-form-item label="时间:">
                            <DatePicker ref="datePickerRef"></DatePicker>
                        </el-form-item>
                        <el-form-item label="统计指标:">
                            <el-select style="width: 200px" v-model.trim="formInline.statisticalId" filterable
                                @change="frequencyFlag" placeholder="请选择">
                                <el-option v-for="item in zblist" :key="item.value" :label="item.label"
                                    :value="item.value"></el-option>
                            </el-select>
                        </el-form-item>
                        <el-form-item label="谐波次数:" v-show="frequencyShow">
                            <el-select v-model.trim="formInline.frequency" filterable placeholder="请选择"
                                style="width: 100px">
                                <el-option v-for="item in 49" :key="item + 1" :label="item + 1"
                                    :value="item + 1"></el-option>
                            </el-select>
                        </el-form-item>
                        <el-form-item label="值类型:">
                            <el-select v-model.trim="formInline.valueType" filterable placeholder="请选择">
                                <el-option v-for="item in typelist" :key="item.value" :label="item.label"
                                    :value="item.value"></el-option>
                            </el-select>
                        </el-form-item>
                    </template>
                    <template v-slot:operation>
                        <el-button type="primary" @click="search" icon="el-icon-Search">查询</el-button>
                        <el-button :type="timeControl ? 'primary' : ''" icon="el-icon-Sort" @click="setTimeControl">
                            缺失数据
                        </el-button>
                    </template>
                </TableHeader>
            </div>

            <el-empty description="暂无数据"  v-if="!echartsData" style="flex: 1;margin-top:  10%"></el-empty>
            <template v-else>
                <div :style="echartHeight">
                    <MyEchart :options="echartsData" />
                </div>
            </template>
        </div>
    </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { mainHeight } from '@/utils/layout'
import analyzeTree from '@/components/tree/govern/analyzeTree.vue'
import { queryByCode, queryCsDictTree } from '@/api/system-boot/dictTree'
import { queryCommonStatisticalByTime } from '@/api/cs-harmonic-boot/stable'
import DatePicker from '@/components/form/datePicker/index.vue'
import MyEchart from '@/components/echarts/MyEchart.vue'
import { yMethod, completeTimeSeries } from '@/utils/echartMethod'
import TableHeader from '@/components/table/header/index.vue'

const MAX_CHECK = 2
const defaultCheckedKeys = ref<any[]>([])
const checkedKeyIds = computed(() => defaultCheckedKeys.value.map(item => item.id))
const treeRef = ref()
const isSyncing = ref(false)
const tableHeaderRef = ref()
const headerRef = ref()
const echartHeight = ref(mainHeight(80))
const loading = ref(false)
const echartsData = ref<any>(null)
const datePickerRef = ref()
const timeControl = ref(false)
const timeFlag = ref(true)
const frequencyShow = ref(false)
const dataLists = ref<any[]>([])
const zblist = ref<any[]>([])

const formInline = reactive({
    statisticalId: '',
    valueType: '',
    startTime: '',
    endTime: '',
    frequency: '' as string | number
})

const typelist = [
    { label: '平均值', value: 'avg' },
    { label: '最大值', value: 'max' },
    { label: '最小值', value: 'min' },
    { label: 'CP95值', value: 'cp95' }
]

const lineStyle = [
    { type: 'solid', width: 3 },
    { type: 'dotted', width: 3 },
    { type: 'dashed', width: 3 }
]

const getEngineeringTree = () => treeRef.value?.treRef?.treeRef4

const init = () => {
    return queryByCode('portable-harmonic-jx').then(res => {
        return queryCsDictTree(res.data?.id).then(res => {
            zblist.value = res.data.map((item: any) => ({
                value: item.id,
                label: item.name,
                ...item
            }))
            formInline.statisticalId = zblist.value[0]?.value
            formInline.valueType = typelist[0].value
        })
    })
}

onMounted(() => {
    init()
})

const onCheck = (_data: any, { checkedNodes }: { checkedNodes: any[] }) => {
    if (isSyncing.value) return

    const tree = getEngineeringTree()
    if (!tree) return

    if (checkedNodes.length <= MAX_CHECK) {
        defaultCheckedKeys.value = checkedNodes.map(node => ({ ...node }))
        if (checkedNodes.length === 0) {
            echartsData.value = null
            dataLists.value = []
        }
        return
    }

    const allowedIds = new Set(defaultCheckedKeys.value.map(item => item.id))
    const extras = checkedNodes.filter(node => !allowedIds.has(node.id))

    if (defaultCheckedKeys.value.length >= MAX_CHECK) {
        isSyncing.value = true
        extras.forEach(node => tree.setChecked(node.id, false, false))
        nextTick(() => {
            isSyncing.value = false
        })
        ElMessage.warning(`最多只能选择${MAX_CHECK}个`)
        return
    }

    const room = MAX_CHECK - defaultCheckedKeys.value.length
    extras.slice(0, room).forEach(node => {
        if (!defaultCheckedKeys.value.some(item => item.id === node.id)) {
            defaultCheckedKeys.value.push({ ...node })
        }
    })
    const rejected = extras.slice(room)
    if (rejected.length) {
        isSyncing.value = true
        rejected.forEach(node => tree.setChecked(node.id, false, false))
        nextTick(() => {
            isSyncing.value = false
        })
        ElMessage.warning(`最多只能选择${MAX_CHECK}个`)
    }
}

const search = async () => {
    if (defaultCheckedKeys.value.length === 0) {
        ElMessage.warning('请选择设备')
        return
    }
    if (zblist.value.length === 0) {
        await init()
    }
    if (timeFlag.value) {
        datePickerRef.value?.setInterval(5)
        timeFlag.value = false
    }
    loading.value = true
    formInline.startTime = datePickerRef.value.timeValue[0]
    formInline.endTime = datePickerRef.value.timeValue[1]
    if (!frequencyShow.value) {
        formInline.frequency = ''
    }

    try {
        const results = await Promise.all(
            defaultCheckedKeys.value.map(device =>
                queryCommonStatisticalByTime({
                    ...formInline,
                    devId: device.id
                }).then(({ data }: { data: any[] }) => ({
                    deviceName: device.name,
                    data
                }))
            )
        )
        dataLists.value = results.flatMap(({ deviceName, data }) =>
            data.map((item: any) => ({
                ...item,
                anotherName:
                    defaultCheckedKeys.value.length > 1 ? `${deviceName}_${item.anotherName}` : item.anotherName
            }))
        )
        setEchart()
    } catch {
        loading.value = false
    }
}

const setEchart = () => {
    loading.value = true
    const data = JSON.parse(JSON.stringify(dataLists.value))
    if (data.length) {
        const list = processingOfData(data, 'unit')
        echartsData.value = {}
        const legend: any[] = []
        const xAxis: any[] = []
        const yAxis: any[] = []
        const series: any[] = []
        const color: any[] = []
        data.forEach((item: any) => {
            if (!xAxis.includes(item.time)) {
                xAxis.push(item.time)
            }
        })
        const units = Object.keys(list)
        for (const unit in list) {
            const [min, max] = yMethod(list[unit].map((item: any) => item.statisticalData))
            yAxis.push({
                name: unit == 'null' ? '' : unit,
                type: 'value',
                min,
                max,
                axisLine: {
                    show: true,
                    lineStyle: { color: '#333' }
                }
            })
            const anotherList = processingOfData(list[unit], 'anotherName')
            for (const k in anotherList) {
                const lineName = lineStyle[Object.keys(anotherList).indexOf(k)]
                const phaseList = processingOfData(anotherList[k], 'phase')
                for (const j in phaseList) {
                    color.push(j == 'A' ? '#DAA520' : j == 'B' ? '#2E8B57' : j == 'C' ? '#A52a2a' : '#0000CC')
                    legend.push(
                        j == 'T' ? k : j == 'A' ? `A相_${k}` : j == 'B' ? `B相_${k}` : j == 'C' ? `C相_${k}` : j
                    )
                    series.push({
                        name: j == 'T' ? k : j == 'A' ? `A相_${k}` : j == 'B' ? `B相_${k}` : j == 'C' ? `C相_${k}` : j,
                        symbol: 'none',
                        smooth: true,
                        type: 'line',
                        data: timeControl.value
                            ? completeTimeSeries(
                                phaseList[j].map((item: any) => [
                                    item.time,
                                    Math.floor(item.statisticalData * 100) / 100,
                                    unit,
                                    lineName.type
                                ])
                            )
                            : phaseList[j].map((item: any) => [
                                item.time,
                                Math.floor(item.statisticalData * 100) / 100,
                                unit,
                                lineName.type
                            ]),
                        lineStyle: lineName,
                        yAxisIndex: units.indexOf(unit)
                    })
                }
            }
        }

        echartsData.value = {
            title: {
                text: zblist.value.filter(item => item.id == formInline.statisticalId)[0]?.name
            },
            tooltip: {
                axisPointer: {
                    type: 'cross',
                    label: { color: '#fff', fontSize: 16 }
                },
                textStyle: { color: '#fff', fontStyle: 'normal', opacity: 0.35, fontSize: 14 },
                backgroundColor: 'rgba(0,0,0,0.55)',
                borderWidth: 0,
                formatter(params: any) {
                    const xname = params[0].value[0]
                    let str = `${xname}<br>`
                    params.forEach((el: any) => {
                        let marker = ''
                        if (el.value[3] == 'dashed') {
                            for (let i = 0; i < 3; i++) {
                                marker += `<span style="display:inline-block;border: 2px ${el.color} solid;margin-right:5px;width:10px;height:0px;background-color:#ffffff00;"></span>`
                            }
                        } else {
                            marker = `<span style="display:inline-block;border: 2px ${el.color} ${el.value[3]};margin-right:5px;width:40px;height:0px;background-color:#ffffff00;"></span>`
                        }
                        str += `${marker}${el.seriesName.split('(')[0]}：${el.value[1] != null ? el.value[1] + ' ' + (el.value[2] == 'null' ? '' : el.value[2]) : '-'
                            }<br>`
                    })
                    return str
                }
            },
            legend: {
                itemWidth: 20,
                itemHeight: 20,
                itemStyle: { opacity: 0 },
                type: 'scroll',
                top: 25
            },
            grid: {
                left: '20px',
                right: '40px',
                bottom: '50px',
                top: '80px',
                containLabel: true
            },
            toolbox: { feature: { saveAsImage: {} } },
            color,
            xAxis: {
                name: '',
                type: 'time',
                axisLabel: {
                    formatter: { day: '{MM}-{dd}', month: '{MM}', year: '{yyyy}' }
                }
            },
            yAxis,
            options: { series }
        }
    } else {
        echartsData.value = null
    }
    loading.value = false
}

const setTimeControl = () => {
    timeControl.value = !timeControl.value
    setEchart()
}

const processingOfData = (data: any, type: string) => {
    const groupedData: any = {}
    data.forEach((item: any) => {
        if (!groupedData[item[type]]) {
            groupedData[item[type]] = []
        }
        groupedData[item[type]].push(item)
    })
    return groupedData
}

const frequencyFlag = () => {
    const name = zblist.value.filter(item => item.id == formInline.statisticalId)[0]?.name
    if (name?.includes('含有率') || name?.includes('幅值')) {
        frequencyShow.value = true
        formInline.frequency = 2
    } else {
        frequencyShow.value = false
    }
    tableHeaderRef.value?.computedSearchRow()
}

const selectChange = () => {
    setTimeout(() => {
        echartHeight.value = mainHeight(23 + headerRef.value.offsetHeight)
    }, 100)
}
</script>

<style lang="scss">
.analyze-steadyState {
    display: flex;
    height: 100%;
    min-height: 0;

    &-right {
        height: 100%;
        overflow: hidden;
        flex: 1;
        padding: 10px 10px 10px 0;
        display: flex;
        flex-direction: column;
    }
}
</style>
<style lang="scss" scoped>
.el-select {
    min-width: 100px;
}
</style>
