<template>
    <div class="contain">
        <el-header class="headerPart">
            <div class="topLeft">
                <div class="selectPart">
                    <span>{{ t('statAnalysis.time') }}</span>
                    <el-date-picker
                        class="statAnalysisSelect"
                        v-model="statAnalysisTime"
                        :type="statAnalysisInterval == '1d' ? 'daterange' : 'datetimerange'"
                        :value-format="statAnalysisInterval == '1d' ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss'"
                        :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]"
                        :teleported="false"
                        :shortcuts="shortcuts"
                    />
                </div>
                <div class="selectPart">
                    <span>{{ t('statAnalysis.interval') }}</span>
                    <el-select v-model="statAnalysisInterval" :placeholder="'请选择' + t('statAnalysis.interval')" class="statAnalysisSelect">
                        <el-option v-for="v in statAnalysisSelectOptions.interval" :key="v.value" :label="v.label" :value="v.value"></el-option>
                    </el-select>
                </div>
                <el-button type="primary" :icon="Crop" class="addline" @click="openMeasure">测点选择</el-button>
            </div>
            <div class="topRight">
                <el-button type="primary" :loading="isLoading" @click="statAnalysisOperate()">{{ t('statAnalysis.search') }}</el-button>
                <el-button style="color: #0064aa" @click="statAnalysisExport()">{{ t('statAnalysis.export') }}</el-button>
            </div>
        </el-header>
        <div class="main">
            <div
                ref="chartContainer"
                style="height: calc(100% - 140px); width: calc(100% - 60px); border: 1px solid rgb(217, 217, 217); margin: 40px"
            ></div>
        </div>

        <el-dialog v-model="showMeasure" title="选择测点" width="1200" top="0">
            <div class="measureSlot">
                <el-row :gutter="20">
                    <el-col :span="12">
                        <div class="col">
                            <div class="transferHeader">
                                <span class="transferTitle">风机列表</span>
                            </div>
                            <div class="mainPart">
                                <el-table
                                    ref="tableDataLeftRef"
                                    :data="tableDataLeft"
                                    v-model:selection="selectedLeft"
                                    @selection-change="handleSelectionChange"
                                    row-key="irn"
                                    class="windtable"
                                >
                                    <el-table-column type="selection" width="40" />
                                    <el-table-column prop="name" label="风机名称" />
                                </el-table>
                                <el-table
                                    :data="tableDataMid"
                                    v-model:selection="selectedMid"
                                    @selection-change="handleSelectionChange2"
                                    row-key="irn"
                                    class="windtable"
                                >
                                    <el-table-column type="selection" width="40" />
                                    <el-table-column prop="name" label="风机名称" />
                                </el-table>
                                <el-table
                                    :data="tableDataRight"
                                    v-model:selection="selectedRight"
                                    @selection-change="handleSelectionChange1"
                                    row-key="irn"
                                    class="windtable"
                                >
                                    <el-table-column type="selection" width="40" />
                                    <el-table-column prop="name" label="风机名称" />
                                </el-table>
                            </div>
                        </div>
                    </el-col>
                    <el-col :span="12">
                        <div class="col">
                            <div class="transferHeader">
                                <span class="transferTitle">可添加的测点</span>
                                <el-radio-group v-model="radioActiveName" @change="typeChange">
                                    <el-radio :value="138">模拟量</el-radio>
                                    <el-radio :value="199">计算量</el-radio>
                                </el-radio-group>
                            </div>
                            <div class="mainPart">
                                <el-table
                                    :data="attrTableData"
                                    ref="attributeTableRef"
                                    @select="selectTable"
                                    @selectAll="selectTable"
                                    row-key="id"
                                    class="attrtable"
                                >
                                    <el-table-column type="selection" width="40" />
                                    <el-table-column prop="attributeName" label="属性名称" />
                                    <el-table-column prop="attributeCode" label="属性编码" />
                                    <el-table-column prop="subSystem" label="子系统" />
                                </el-table>
                            </div>
                            <div style="display: flex; justify-content: right">
                                <el-pagination
                                    v-model:current-page="pageSetting.current"
                                    v-model:page-size="pageSetting.pageSize"
                                    :total="pageSetting.total"
                                    :page-sizes="pageSetting.pageSizes"
                                    background
                                    :pager-count="5"
                                    layout="prev, pager, next,sizes"
                                    @change="getcurrentPage"
                                ></el-pagination>
                            </div>
                        </div>
                    </el-col>
                </el-row>
            </div>
            <template #footer>
                <span class="dialog-footer">
                    <el-button type="primary" @click="selectstatAnalysisAttributes"> 确认 </el-button>
                    <el-button @click="showMeasure = false">取消</el-button>
                </span>
            </template>
        </el-dialog>
    </div>
</template>
<script setup lang="ts">
import { markRaw, reactive, ref, watch, nextTick, onMounted, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { queryWindTurbinesPages, historyReq, trendContrastExport } from '/@/api/backend/statAnalysis/request'
import { ElMessage, ElMenu } from 'element-plus'
import { DArrowRight, Plus, Crop, Close } from '@element-plus/icons-vue'
import * as echarts from 'echarts'
import { getModelAttributeListReq } from '/@/api/backend/deviceModel/request'
import { getCutDecimalsValue } from '/@/views/backend/equipment/airBlower/utils'

const { t } = useI18n()

const statAnalysisInterval = ref('1h')
const statAnalysisSelectOptions: any = reactive({
    interval: [
        { label: '一分钟', value: '1m' },
        { label: '五分钟', value: '5m' },
        { label: '十分钟', value: '10m' },
        { label: '十五分钟', value: '15m' },
        { label: '一小时', value: '1h' },
        { label: '一天', value: '1d' },
        { label: '原始', value: 'NONE' },
    ],
})
const getFormattedDate = (offset: number) => {
    const date = new Date()
    date.setDate(date.getDate() + offset)

    const year = date.getFullYear()
    const month = String(date.getMonth() + 1).padStart(2, '0')
    const day = String(date.getDate()).padStart(2, '0')
    return `${year}-${month}-${day}`
}

const statAnalysisTime = ref([getFormattedDate(0) + ' 00:00:00', getFormattedDate(0) + ' 23:59:59'])

const showMeasure = ref(false)

const selectstatAnalysisAttributes = () => {
    showMeasure.value = false
}
const chartContainer = ref<HTMLElement | null>(null)

const option: any = {
    tooltip: {},
    legend: {
        icon: 'circle',
        itemGap: 20,
        itemWidth: 8,
        itemHeight: 8,
        data: [],
    },
    xAxis: {
        data: [],
        axisLabel: {
            rotate: 15,
        },
    },
    yAxis: {
        type: 'value',
    },
    series: [],
    grid: {},
}

const chart: any = ref(null)
onMounted(() => {
    if (chartContainer.value) {
        chart.value = markRaw(echarts.init(chartContainer.value))
    }

    queryWindTurbines().then((res) => {
        selectedLeft.value = [tableDataLeft.value[0]]
        getCompleteData().then((attrRes: any) => {
            console.log('🚀 ~ getCompleteData ~ attrRes:', attrRes)
            multipleSelection.value = [
                {
                    attributeName: attrRes.attributeName,
                    attributeCode: attrRes.attributeCode,
                    unit: attrRes.unit,
                },
            ]
            statAnalysisOperate()
        })
    })
})
const tableDataLeft = ref([])
const tableDataRight = ref([])
const tableDataMid = ref([])
const iotModelId = ref('')
const selectedLeft = ref([])
const selectedRight = ref([])
const selectedMid = ref([])

const radioActiveName = ref(138)
const attributeTableRef = ref()
const typeChange = () => {
    pageSetting.current == 1 ? getCompleteData() : (pageSetting.current = 1)
}

const queryWindTurbines = () => {
    return new Promise((resolve) => {
        queryWindTurbinesPages()
            .then((res) => {
                if (res.code == 200) {
                    const resData = res.data.map((item: any, index: any) => {
                        return {
                            index: index,
                            ...item,
                        }
                    })
                    if (resData.length) {
                        iotModelId.value = resData[0]['modelId']
                        const middleIndex = Math.floor(resData.length / 3)
                        tableDataLeft.value = resData.slice(0, middleIndex)
                        tableDataMid.value = resData.slice(middleIndex, middleIndex * 2)
                        tableDataRight.value = resData.slice(middleIndex * 2)
                    }
                    resolve(resData[0])
                } else {
                    ElMessage.error(res.msg)
                }
            })
            .catch((err) => {
                ElMessage.error(err ?? '查询失败')
            })
    })
}

const pageSetting = reactive({
    current: 1,
    pageSize: 20,
    total: 0,
    pageSizes: [20, 50, 100],
})

const getcurrentPage = () => {
    getCompleteData()
}

const getCompleteData = () => {
    const requestData: any = {
        iotModelId: iotModelId.value,
        pageNum: pageSetting.current,
        pageSize: pageSetting.pageSize,
        attributeType: radioActiveName.value,
    }
    return new Promise((resolve) => {
        getModelAttributeListReq(requestData)
            .then((res: any) => {
                if (res.rows && res.rows.length > 0) {
                    attrTableData.value = res.rows
                    pageSetting.total = res.total
                    nextTick(() => {
                        initSelect()
                    })
                    resolve(attrTableData.value[0])
                } else {
                    if (res.rows && res.rows.length === 0) {
                        attrTableData.value = []
                    } else {
                        ElMessage.error(res.msg)
                    }
                }
            })
            .catch((err) => {
                ElMessage.error(err?.response?.data?.msg ?? '查询失败')
            })
    })
}

const initSelect = () => {
    const defaultCode = multipleSelection.value.map((item: any) => item.attributeCode)
    const row = attrTableData.value.filter((item: any) => defaultCode.includes(item.attributeCode))
    if (row.length === 0) return
    row.forEach((item) => {
        attributeTableRef.value?.toggleRowSelection(item, true)
    })
}

const multipleSelection: any = ref([])

const selectTable = (section: any) => {
    const allCode = attrTableData.value.map((item: any) => {
        return item.attributeCode
    })
    const extraCode = multipleSelection.value.filter((item: any) => !allCode.includes(item.attributeCode))
    const setionMap = section.map((item: any) => {
        return {
            attributeName: item.attributeName,
            attributeCode: item.attributeCode,
            unit: item.unit,
        }
    })
    multipleSelection.value = [...extraCode, ...setionMap]
}
const attrTableData = ref([])

window.onresize = () => {
    chart.value.resize()
}

const shortcuts = [
    {
        text: '今天',
        value: () => {
            const start = getFormattedDate(0) + ' 00:00:00'
            const end = getFormattedDate(0) + ' 23:59:59'
            return [start, end]
        },
    },
    {
        text: '昨天',
        value: () => {
            const start = getFormattedDate(-1) + ' 00:00:00'
            const end = getFormattedDate(-1) + ' 23:59:59'
            return [start, end]
        },
    },
    {
        text: '前3天',
        value: () => {
            const start = getFormattedDate(-3) + ' 00:00:00'
            const end = getFormattedDate(-1) + ' 23:59:59'
            return [start, end]
        },
    },
    {
        text: '本周',
        value: () => {
            return getDateRange('week')
        },
    },
    {
        text: '本月',
        value: () => {
            return getDateRange('month')
        },
    },
]

const getDateRange = (type: 'week' | 'month') => {
    const today = new Date()
    if (type === 'week') {
        const dayOfWeek = today.getDay()
        const startOfWeek = new Date(today)
        startOfWeek.setDate(today.getDate() - dayOfWeek + (dayOfWeek === 0 ? -6 : 1))
        startOfWeek.setHours(0, 0, 0, 0)
        const endOfWeek = new Date(startOfWeek)
        endOfWeek.setDate(startOfWeek.getDate() + 6)
        endOfWeek.setHours(23, 59, 59, 999)
        return [startOfWeek, endOfWeek]
    }
    if (type === 'month') {
        const startOfMonth = new Date(today.getFullYear(), today.getMonth(), 1)
        startOfMonth.setHours(0, 0, 0, 0)
        const endOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0)
        endOfMonth.setHours(23, 59, 59, 999)
        return [startOfMonth, endOfMonth]
    }
}

const tableDataLeftRef = ref()
const openMeasure = () => {
    showMeasure.value = true
    pageSetting.current = 1
    nextTick(() => {
        selectedLeft.value.forEach((item) => {
            tableDataLeftRef.value?.toggleRowSelection(item, true)
        })
        initSelect()
    })
}

const handleSelectionChange1 = (val: any) => {
    selectedRight.value = val
}
const handleSelectionChange2 = (val: any) => {
    selectedMid.value = val
}
const handleSelectionChange = (val: any) => {
    selectedLeft.value = val
}
const isLoading = ref(false)

function generateDeviceAttributes(devices: any, attributes: any) {
    const attributeCodes = attributes.map((attr: any) => attr.attributeCode)
    return devices.map((device: any) => {
        return {
            deviceId: device.irn,
            attributes: attributeCodes,
        }
    })
}

const statAnalysisOperate = () => {
    const allDevices = [...selectedLeft.value, ...selectedMid.value, ...selectedRight.value]
    if (!statAnalysisTime.value) {
        ElMessage.info('请选择查询时间！')
        return
    } else if (!allDevices.length) {
        ElMessage.info('请选择风机！')
        return
    } else if (!multipleSelection.value.length) {
        ElMessage.info('请选择测点名称！')
        return
    }

    isLoading.value = true
    option.series = []
    option.legend.data = []
    calculate.value = []
    chart.value.setOption(option, { notMerge: true })
    historyDataReq(getRequestData())
}
const calculate: any = ref([{ max: '', min: '', average: '' }])
const historyDataReq = (data: any) => {
    const selectAllDevices = [...selectedLeft.value, ...selectedMid.value, ...selectedRight.value].sort((a: any, b: any) => {
        return a.index - b.index
    })
    historyReq(data)
        .then((res) => {
            isLoading.value = false
            if (res.code == 200) {
                const resData = res.data
                const deviceIdKeys = Object.keys(resData)
                if (deviceIdKeys.length) {
                    selectAllDevices.forEach((item: any) => {
                        if (!resData[item.irn]) {
                            ElMessage.info(`${item.name}没有数据`)
                            return
                        }
                        const deviceName = item.name
                        Object.keys(resData[item.irn]).forEach((val) => {
                            const attRow = multipleSelection.value.filter((value: any) => value.attributeCode === val)
                            const attName = attRow[0]['attributeName']
                            const unit = attRow[0]['unit']
                            const historyData = resData[item.irn][val]
                            const xData = historyData['times']
                            const yData = historyData['values']
                            if (!yData.length) {
                                ElMessage.info(`${deviceName + attName}数据为空`)
                                return
                            }
                            const seriesData = {
                                name: deviceName + attName,
                                type: 'line',
                                data: yData.map((value: any) => ({
                                    value: getCutDecimalsValue(value, 2),
                                    unit: unit, // 将单位添加到每个数据点
                                })),
                                smooth: true,
                                symbolSize: 5,
                                symbol: 'circle',
                            }
                            option.tooltip = {
                                show: true,
                                trigger: 'axis',
                                formatter: function (params: any) {
                                    return params
                                        .map((item: any) => {
                                            return `${item.marker} ${item.seriesName} (${timestampToTime(xData[item.dataIndex])}):  ${item.value} ${item.data.unit}`
                                        })
                                        .join('<br/>')
                                },
                            }
                            option.legend.data.push(deviceName + attName)
                            option.xAxis.data = xData.map((item: any) => timestampToTime(item))
                            option.series.push(seriesData)
                            chart.value.setOption(option)
                        })
                    })
                }
            } else {
                isLoading.value = false
                ElMessage.warning('查询失败')
            }
        })
        .catch((error) => {
            isLoading.value = false
            console.error(error)
            ElMessage.warning(error)
        })
}

const statAnalysisExport = () => {
    trendContrastExport(getRequestData()).then((res: any) => {
        const downloadUrl = window.URL.createObjectURL(res)
        const a = document.createElement('a')
        a.href = downloadUrl
        a.download = '趋势对比' + new Date().getTime()
        document.body.appendChild(a)
        a.click()
        window.URL.revokeObjectURL(downloadUrl)
        document.body.removeChild(a)
    })
}

const getRequestData = () => {
    const devices = generateDeviceAttributes([...selectedLeft.value, ...selectedMid.value, ...selectedRight.value], multipleSelection.value)
    const requestData = {
        devices: devices,
        interval: statAnalysisInterval.value || '5m',
        startTime: new Date(statAnalysisTime.value[0]).getTime(),
        endTime: new Date(statAnalysisTime.value[1]).getTime(),
    }
    console.log('🚀 ~ getRequestData ~ requestData:', requestData)

    return requestData
}

const timestampToTime = (timestamp: any) => {
    timestamp = timestamp ? timestamp : null
    let date = new Date(timestamp)
    let Y = date.getFullYear() + '-'
    let M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'
    let D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' '
    let h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':'
    let m = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
    return Y + M + D + h + m
}
</script>
<style scoped lang="scss">
.statAnalysis {
    height: 100%;
    .contain {
        height: calc(100% - 60px);
        .main {
            display: flex;
            height: calc(100% - 60px);

            .right {
                width: calc(100% - 418px);
                height: 100%;
            }
        }
    }
    .headerPart {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 0 20px;
        height: 60px;
        .addline {
            height: 40px;
        }
        .topLeft {
            display: flex;
            .icon {
                width: 40px;
                height: 40px;
                padding: 10px 0;
            }

            .dialog-footer button:first-child {
                margin-right: 10px;
            }
        }
        .topRight {
            display: flex;
            margin: 12px 0;
            .el-button {
                width: 100px;
                height: 40px;
            }
        }
    }
    .selectPart {
        display: flex;
        justify-content: space-between;
        align-items: center;
        height: 40px;
        margin-right: 20px;
        span {
            margin-right: 10px;
        }
        .customName {
            width: 120px;
            margin-right: 10px;
        }
        .statAnalysisSelect {
            width: 200px;
            :deep(.el-select__wrapper) {
                height: 40px;
            }
            :deep(.el-input__inner) {
                height: 38px;
            }
        }
    }
    .timeColumns {
        .moduleRow {
            .item {
                position: relative;
                margin: 0px 12px 12px;
                padding: 12px 12px 8px;
                border-radius: 20px;
                box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12);
                .topLeft {
                    display: flex;
                }
                .selectPart {
                    width: 388px;
                    justify-content: left;
                    margin: 4px;
                    span {
                        white-space: nowrap;
                    }
                    .statAnalysisSelectattributes {
                        width: 320px;
                        height: 30px;
                    }
                    .statAnalysisSelect {
                        height: 30px;
                        :deep(.el-select__wrapper) {
                            height: 30px;
                        }
                        :deep(.el-input__inner) {
                            height: 28px;
                        }
                    }
                    .customName {
                        height: 30px;
                    }
                }
            }
        }
        .removeModule {
            position: absolute;
            top: 6px;
            right: 8px;
            color: rgba(0, 0, 0, 0);
            cursor: pointer;
            transition: color 0.5s;
        }
        &:hover {
            .removeModule {
                color: rgba(0, 0, 0, 0.55);
                border: 1px solid rgba(0, 0, 0, 0.55);
                border-radius: 50px;
            }
        }
        .headerPart {
            padding: 2px 20px;
        }
    }
    #myEChart {
        width: 100%;
        height: 300px;
    }
    .measureSlot {
        display: flex;
        .col {
            border: 1px solid #e1edf6;
            border-radius: 6px;
            .transferHeader {
                height: 40px;
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 0 10px;
                color: #333333;
                background: #f7f9fc;
                border-bottom: 1px solid #e1edf6;
                border-radius: 6px 6px 0 0;
            }
            .windtable {
                height: 721px;
            }
            .mainPart {
                display: flex;
                padding: 10px;
                .attrtable {
                    height: 690px;
                }
            }
        }
    }
}
</style>
