<template>
    <div class="measurement">
        <el-table :columns="tableColumn" :data="tableData" @sort-change="sortChange" max-height="495">
            <el-table-column
                v-for="item in tableColumn"
                :key="item.prop"
                :label="item.label"
                :prop="item.prop"
                :width="item.width ?? ''"
                :align="item.align"
                :sortable="item.sortable"
            >
                <template #default="scope">
                    <div v-if="item.prop === 'realTimeValue'" class="realTimeValue">
                        <div class="realTimeValueText">{{ scope.row.realTimeValue }}</div>
                    </div>
                    <div v-if="item.prop === 'operate'" @click="openLineChart(scope.row)" class="operate">
                        <template v-if="!enumStore.keys.includes(scope.row.attributeCode)">
                            <svg xmlns="http://www.w3.org/2000/svg" class="icon" width="20px" height="20px" viewBox="0 0 1024 1024" version="1.1">
                                {{ scope.row }}
                                <path
                                    d="M896 896H96a32 32 0 0 1-32-32V224a32 32 0 0 1 64 0v608h768a32 32 0 1 1 0 64zM247.008 640a32 32 0 0 1-20.992-56.192l200.992-174.24a32 32 0 0 1 42.272 0.288l172.128 153.44 229.088-246.304a32 32 0 0 1 46.88 43.616l-250.432 269.216a31.936 31.936 0 0 1-44.704 2.08l-174.56-155.52-179.744 155.84a31.872 31.872 0 0 1-20.928 7.776z"
                                />
                            </svg>
                        </template>
                    </div>
                </template>
            </el-table-column>
        </el-table>
        <div>
            <el-pagination
                v-model:current-page="pageSetting.current"
                v-model:page-size="pageSetting.pageSize"
                :total="pageSetting.total"
                :page-sizes="pageSetting.pageSizes"
                background
                :pager-count="7"
                layout="prev, pager, next, jumper,sizes,total"
                @change="getcurrentPage"
            ></el-pagination>
        </div>
    </div>
    <el-dialog v-model="lineChartVisible" title="历史曲线" @close="closeLineChart" :width="910">
        <el-form :inline="true" :model="seachOptions" :rules="searchRules" ref="searchFormRef">
            <div class="searchPart">
                <div>
                    <el-form-item prop="datePickerValue" label="历史区间：">
                        <el-date-picker
                            v-model="seachOptions.datePickerValue"
                            type="datetimerange"
                            start-placeholder="开始时间"
                            end-placeholder="结束时间"
                            format="YYYY-MM-DD HH:mm:ss"
                            date-format="YYYY/MM/DD"
                            time-format="HH:mm:ss"
                            :shortcuts="shortcuts"
                            :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
                        ></el-date-picker>
                    </el-form-item>
                </div>
                <div>
                    <el-form-item prop="interval" label="时间间隔：">
                        <el-select v-model="seachOptions.interval" placeholder="请选择时间间隔" style="width: 100px">
                            <el-option label="原始" value="40s"></el-option>
                            <el-option label="1分钟" value="1m"></el-option>
                            <el-option label="5分钟" value="5m"></el-option>
                            <el-option label="10分钟" value="10m"></el-option>
                            <el-option label="15分钟" value="15m"></el-option>
                            <el-option label="1小时" value="1h"></el-option>
                            <el-option label="1天" value="1d"></el-option>
                        </el-select>
                    </el-form-item>
                </div>
                <el-button type="primary" @click="getChartData" :loading="loading">查询</el-button>
            </div>
        </el-form>
        <div class="chartPart">
            <div class="lineChart" ref="chartRef"></div>
        </div>
    </el-dialog>
</template>

<script setup lang="ts">
import { reactive, ref, watch, onMounted } from 'vue'
import { ElMessage, FormInstance, dayjs } from 'element-plus'
import type { ModelAttributeFieldsEnums, GetModelAttributeType } from '/@/views/backend/auth/model/type'
import { ModelAttributeType } from '/@/views/backend/auth/model/type'
import { getModelAttributeListReq, getRealValueListReq } from '/@/api/backend/deviceModel/request'
import * as echarts from 'echarts'
import { getRealValueRangeReq } from '/@/api/backend/deviceModel/request'
import { useEnumStore } from '/@/stores/enums'
const enumStore = useEnumStore()

const props = withDefaults(
    defineProps<{ iotModelId: string; deviceId: string; show: boolean; autoUpdate: boolean; attributeType: ModelAttributeType }>(),
    {
        iotModelId: '',
        deviceId: '',
        show: false,
        autoUpdate: false,
        attributeType: 138,
    }
)

const tableColumn = [
    {
        label: '序号',
        prop: 'porder',
        width: 76,
        align: 'center',
        sortable: 'custom',
    },
    {
        label: '属性名称',
        prop: 'attributeName',
        align: 'left',
        sortable: 'custom',
    },
    {
        label: '属性编码',
        prop: 'attributeCode',
        align: 'left',
        width: 200,
        sortable: 'custom',
    },
    {
        label: '子系统',
        prop: 'subSystem',
        align: 'left',
        width: 110,
        sortable: false,
    },
    {
        label: '实时值',
        prop: 'realTimeValue',
        width: 140,
        align: 'center',
        sortable: false,
    },
    {
        label: '历史曲线',
        prop: 'operate',
        align: 'center',
        width: 80,
        sortable: false,
    },
]
const tableData = ref<any[]>([])

const getAttributeList = () => {
    const requestData: GetModelAttributeType = {
        iotModelId: props.iotModelId,
        pageNum: pageSetting.current,
        pageSize: pageSetting.pageSize,
        orderColumn: sortData.orderColumn,
        orderType: sortData.orderType,
        attributeType: props.attributeType,
    }

    return new Promise((resolve) => {
        getModelAttributeListReq(requestData)
            .then((res) => {
                if (res.rows && res.rows.length > 0) {
                    const codeList: any = []
                    const data = res.rows!.map((item) => {
                        codeList.push(item.attributeCode)
                        return {
                            ...item,
                            attributeTypeName:
                                item.attributeType === 138
                                    ? '模拟量'
                                    : item.attributeType === 139
                                      ? '累积量'
                                      : item.attributeType === 140
                                        ? '离散量'
                                        : item.attributeType!,
                        }
                    })
                    pageSetting.total = res.total
                    resolve({ data, codeList })
                } else {
                    if (res.rows && res.rows.length === 0) {
                        tableData.value = []
                    } else {
                        ElMessage.error(res.msg)
                    }
                }
            })
            .catch((err) => {
                ElMessage.error(err?.response?.data?.msg ?? '查询失败')
            })
    })
}

const getRealValueList = (data: { deviceId: string; attributes: string[] }, list?: any) => {
    return new Promise((resolve) => {
        getRealValueListReq([data]).then((res) => {
            if (res.success && res.data) {
                resolve({ realVal: res.data, list })
            }
        })
    })
}

const getCompleteData = () => {
    getAttributeList()
        .then(({ data, codeList }: any) => {
            return getRealValueList({ deviceId: props.deviceId, attributes: codeList }, data)
        })
        .then((realData: any) => {
            console.log(realData)

            const data = realData.list.map((item: any) => {
                let realValItem = realData.realVal[props.deviceId]?.[item.attributeCode?.toLowerCase()]
                if (enumStore.keys.includes(item.attributeCode)) {
                    realValItem = enumStore.data[item.attributeCode][realValItem]
                }
                return {
                    ...item,
                    realTimeValue:
                        typeof realValItem === 'number'
                            ? realValItem
                                ? realValItem % 1 === 0
                                    ? realValItem
                                    : realValItem.toFixed(3)
                                : '-'
                            : realValItem,
                }
            })

            tableData.value = data
        })
}

const sortData = reactive<{ orderColumn?: keyof typeof ModelAttributeFieldsEnums; orderType?: 'asc' | 'desc' }>({
    orderColumn: 'porder',
    orderType: 'asc',
})

const sortChange = ({ prop, order }: { prop: keyof typeof ModelAttributeFieldsEnums; order: 'ascending' | 'descending' | null }) => {
    const propEnums = {
        attributeCode: 'attribute_code',
        attributeName: 'attribute_name',
        attributeTypeName: 'attribute_type',
        porder: 'porder',
        serviceCode: 'service_code',
        serviceName: 'service_name',
        serviceTypeName: 'service_type',
    }
    const orderType = order === 'ascending' ? 'asc' : order === 'descending' ? 'desc' : undefined
    const filed = propEnums[prop as keyof typeof propEnums] as keyof typeof ModelAttributeFieldsEnums
    sortData.orderColumn = orderType ? filed : undefined
    sortData.orderType = orderType
    getCompleteData()
}

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

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

const openLineChart = (data: any) => {
    lineChartVisible.value = true
    searchInfo.attr = data.attributeCode
    searchInfo.name = data.attributeName
    searchInfo.unit = data.unit
}

watch(
    () => props.show,
    (newVal) => {
        if (newVal) {
            getCompleteData()
        } else {
            autoUpdateTimer.value && clearInterval(autoUpdateTimer.value)
            autoUpdateTimer.value = null
        }
    },
    {
        immediate: true,
    }
)
const autoUpdateTimer: any = ref(null)
watch(
    () => props.autoUpdate,
    (newVal) => {
        if (newVal) {
            if (!autoUpdateTimer.value) {
                autoUpdateTimer.value = setInterval(() => {
                    getCompleteData()
                }, 2000)
            }
        } else {
            clearInterval(autoUpdateTimer.value)
            autoUpdateTimer.value = null
        }
    }
)

const loading = ref(false)
const searchFormRef = ref<FormInstance>()
const lineChartVisible = ref(false)
const searchInfo = reactive({
    unit: '',
    name: '',
    attr: '',
})
const shortcuts = [
    {
        text: '今天',
        value: () => {
            const start = dayjs().startOf('day').toDate()
            const end = dayjs().endOf('day').toDate()
            return [start, end]
        },
    },
    {
        text: '昨天',
        value: () => {
            const start = dayjs().subtract(1, 'day').startOf('day').toDate()
            const end = dayjs().subtract(1, 'day').endOf('day').toDate()
            return [start, end]
        },
    },
    {
        text: '前三天',
        value: () => {
            const start = dayjs().subtract(4, 'day').startOf('day').toDate()
            const end = dayjs().subtract(1, 'day').endOf('day').toDate()
            return [start, end]
        },
    },
]
const getChartData = () => {
    searchFormRef.value?.validate((valid) => {
        if (valid) {
            loading.value = true
            getRealValueRangeReq({
                startTime: dayjs(seachOptions.datePickerValue[0]).valueOf(),
                endTime: dayjs(seachOptions.datePickerValue[1]).valueOf(),
                devices: [
                    {
                        deviceId: props.deviceId,
                        attributes: [searchInfo.attr],
                    },
                ],
                interval: seachOptions.interval,
            }).then((res) => {
                initChart(res.data?.[props.deviceId]?.[searchInfo.attr])
            })
        }
    })
}

const chartRef = ref()
let chartInstance: any = null
const seachOptions = reactive({
    datePickerValue: [0, 0],
    interval: '5m',
})

const searchRules = {
    datePickerValue: [
        {
            validator: (rule: any, value: any, callback: any) => {
                if (!value[0] || !value[1]) {
                    callback(new Error('请选择时间范围'))
                    return
                }
                callback()
            },
            trigger: 'change',
        },
    ],
    interval: [
        {
            required: true,
            message: '请输入时间间隔',
            trigger: 'input',
        },
    ],
}

const initChart = (data: { values: number[]; times: number[] }) => {
    chartInstance && chartInstance.clear()

    chartInstance = chartInstance ? chartInstance : echarts.init(chartRef.value)
    const times = data?.times.map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))

    const option = {
        animation: false,
        grid: {
            top: 50,
            right: 23,
            bottom: 10,
            left: 18,
            containLabel: true,
        },
        tooltip: {
            trigger: 'axis',
            axisPointer: {
                type: 'shadow',
            },
        },
        xAxis: {
            type: 'category',
            axisLine: {
                show: true,
                lineStyle: {
                    color: '#dadada',
                    width: 1,
                    type: 'solid',
                },
            },
            axisLabel: {
                //x轴文字的配置
                show: true,
                color: '#4E5969',
                interval: 'auto',
                //rotate: 45
            },
            splitLine: {
                //分割线配置
                show: false,
                lineStyle: {
                    color: '#999999',
                },
            },
            data: times ?? [],
        },
        yAxis: [
            {
                type: 'value',
                name: searchInfo.unit,
                nameTextStyle: {
                    color: '#4E5969',
                },
                axisLine: {
                    show: false,
                    lineStyle: {
                        color: '#dadada',
                        width: 0,
                        type: 'solid',
                    },
                },
                axisLabel: {
                    //x轴文字的配置
                    show: true,
                    color: '#4E5969',
                },
                axisTick: { show: false },
                splitLine: {
                    interval: 50,
                    lineStyle: {
                        type: 'dashed',
                        color: '#dadada',
                    },
                },
            },
        ],
        legend: {
            data: [searchInfo.name],
            textStyle: {
                color: '#73767a',
            },
        },
        series: [
            {
                name: searchInfo.name,
                type: 'line',
                barWidth: 20,
                itemStyle: {
                    color: '#00A7EB',
                    barBorderRadius: 2,
                },
                smooth: 0.6,
                symbol: 'none',
                data: data?.values ?? []
            },
        ],
    }
    chartInstance.setOption(option)
    loading.value = false
}

const closeLineChart = () => {
    chartInstance && chartInstance.clear()
    searchFormRef.value!.resetFields()
}

watch(
    () => props.attributeType,
    () => {
        getCompleteData()
    }
)
</script>

<style scoped lang="scss">
.realTimeValueText {
    color: #0064aa;
}

.operate {
    &:hover {
        cursor: pointer;
    }
}

.searchPart {
    width: 100%;
    display: flex;
    justify-content: space-between;
}
.chartPart {
    width: 100%;
    height: 400px;
    .lineChart {
        width: 100%;
        height: 100%;
    }
}
</style>
