const dataProcessing = (arr: any[]) => {
    return arr
        .filter(item => typeof item === 'number' || (typeof item === 'string' && !isNaN(parseFloat(item))))
        .map(item => (typeof item === 'number' ? item : parseFloat(item)))
}
const calculateValue = (o: number, value: number, num: number, isMin: boolean) => {
    if (value === 0) {
        return 0
    } else if (value > 0 && Math.abs(value) < 1 && isMin == true) {
        return 0
    } else if (value > -1 && value < 0 && isMin == false) {
        return 0
    }

    let base
    if (Math.abs(o) >= 100) {
        base = 100
    } else if (Math.abs(o) >= 10) {
        base = 10
    } else if (Math.abs(o) >= 1) {
        base = 1
    } else {
        const multiple = 1 / 0.1

        base = Math.ceil(Math.abs(o) * multiple) / multiple
    }

    let calculatedValue
    if (isMin) {
        if (value < 0) {
            calculatedValue = value + num * value
        } else {
            calculatedValue = value - num * value
        }
    } else {
        if (value < 0) {
            calculatedValue = value - num * value
        } else {
            calculatedValue = value + num * value
        }
    }

    if (base === 0.1) {
        // return parseFloat(calculatedValue.toFixed(1))
        return Math.ceil(calculatedValue * 10) / 10
    } else if (isMin) {
        return Math.floor(calculatedValue / base) * base
    } else {
        return Math.ceil(calculatedValue / base) * base
    }
}
// 处理y轴最大最小值
export const yMethod = (arr: any) => {
    let num = 0.2
    let numList = dataProcessing(arr)
    if (numList.length === 0) {
        return [0, 0]
    }
    const maxValue = Math.max(...numList)
    const minValue = Math.min(...numList)
    let min = 0
    let max = 0

    // 一正一负时各自按绝对值范围计算，不用 max - min 作为跨度
    if (maxValue > 0 && minValue < 0) {
        min = calculateValue(Math.abs(minValue), minValue, num, true)
        max = calculateValue(Math.abs(maxValue), maxValue, num, false)
    } else {
        const o = maxValue - minValue === 0 ? maxValue : maxValue - minValue
        min = calculateValue(o, minValue, num, true)
        max = calculateValue(o, maxValue, num, false)
    }

    return [min, max]
}

/**
 * title['A相','B相',]
 * data[[1,2],[3,4]]
 */
// 导出csv文件
const convertToCSV = (title: object, data: any) => {
    console.log('🚀 ~ convertToCSV ~ data:', data)
    let csv = ''
    // 添加列头
    csv += ',' + title.join(',') + '\n'
    // 遍历数据并添加到CSV字符串中
    data?.map(item => {
        csv += item.join(',') + '\n'
    })
    return csv
}
export const exportCSV = (title: object, data: any, filename: string) => {
    const csv = convertToCSV(title, data)
    const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' })
    const link = document.createElement('a')
    link.href = URL.createObjectURL(blob)
    link.download = filename
    link.click()
    // 释放URL对象
    URL.revokeObjectURL(link.href)
}

/**
 * 补全时间序列数据中缺失的条目
 * @param rawData 原始数据，格式为 [["时间字符串", "数值", "单位", "类型"], ...]
 * @returns 补全后的数据，缺失条目数值为 null
 */
export const completeTimeSeries = (rawData: string[][]): (string | null)[][] => {
    // 步骤1：校验原始数据并解析时间
    if (rawData.length < 2) {
        console.warn('数据量不足2条，无法计算时间间隔，直接返回原始数据')
        return rawData.map(item => [...item])
    }

    // 解析所有时间为Date对象，过滤无效时间并按时间排序
    const validData = rawData
        .map(item => {
            // 确保至少有时间和数值字段
            if (!item[0]) {
                return { time: new Date(0), item, isValid: false }
            }
            const time = new Date(item[0])
            return { time, item, isValid: !isNaN(time.getTime()) }
        })
        .filter(data => data.isValid)
        .sort((a, b) => a.time.getTime() - b.time.getTime()) // 确保数据按时间排序
        .map(data => data.item)

    if (validData.length < 2) {
        throw new Error('有效时间数据不足2条，无法继续处理')
    }

    // 步骤2：计算时间间隔（分析前几条数据确定最可能的间隔）
    const intervals: number[] = []
    // 分析前10条数据来确定间隔，避免单一间隔出错
    const analyzeCount = Math.min(10, validData.length - 1)
    for (let i = 0; i < analyzeCount; i++) {
        const currentTime = new Date(validData[i][0]!).getTime()
        const nextTime = new Date(validData[i + 1][0]!).getTime()
        const interval = nextTime - currentTime
        if (interval > 0) {
            intervals.push(interval)
        }
    }

    // 取最常见的间隔作为标准间隔
    const timeInterval = getMostFrequentValue(intervals)
    if (timeInterval <= 0) {
        throw new Error('无法确定有效的时间间隔')
    }

    // 步骤3：生成完整的时间序列范围（从第一条到最后一条）
    const startTime = new Date(validData[0][0]!).getTime()
    const endTime = new Date(validData[validData.length - 1][0]!).getTime()
    const completeTimes: Date[] = []

    // 生成从 startTime 到 endTime 的所有间隔时间点
    for (let time = startTime; time <= endTime; time += timeInterval) {
        completeTimes.push(new Date(time))
    }

    // 步骤4：将原始数据转为时间映射表，使用精确的时间字符串匹配
    const timeDataMap = new Map<string, (string | undefined)[]>()
    validData.forEach(item => {
        // 使用原始时间字符串作为键，避免格式转换导致的匹配问题
        if (item[0]) {
            timeDataMap.set(item[0], item)
        }
    })

    // 提取模板数据（从第一条有效数据中提取单位和类型，处理可能的缺失）
    const template = validData[0]

    // 步骤5：对比补全数据，缺失条目数值为 null
    const completedData = completeTimes.map(time => {
        // 保持与原始数据相同的时间格式
        const timeStr = formatTime(time)
        const existingItem = timeDataMap.get(timeStr)

        if (existingItem) {
            // 存在该时间，返回原始数据
            return [...existingItem]
        } else {
            // 缺失该时间，数值设为 null，其他字段沿用第一个有效数据的格式
            // 处理可能缺失的单位和类型字段
            const result: (string | null | undefined)[] = [timeStr, '/']
            // 仅在原始数据有单位字段时才添加
            if (template.length > 2) {
                result.push(template[2])
            }
            // 仅在原始数据有类型字段时才添加
            if (template.length > 3) {
                result.push(template[3])
            }
            return result
        }
    })

    return completedData
}

/**
 * 格式化时间为 "YYYY-MM-DD HH:mm:ss" 格式
 * @param date 日期对象
 * @returns 格式化后的时间字符串
 */
function formatTime(date: Date): string {
    const year = date.getFullYear()
    const month = String(date.getMonth() + 1).padStart(2, '0')
    const day = String(date.getDate()).padStart(2, '0')
    const hours = String(date.getHours()).padStart(2, '0')
    const minutes = String(date.getMinutes()).padStart(2, '0')
    const seconds = String(date.getSeconds()).padStart(2, '0')

    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
}

/**
 * 获取数组中出现频率最高的值
 * @param arr 数字数组
 * @returns 出现频率最高的值
 */
function getMostFrequentValue(arr: number[]): number {
    if (arr.length === 0) return 0

    const frequencyMap = new Map<number, number>()
    arr.forEach(num => {
        frequencyMap.set(num, (frequencyMap.get(num) || 0) + 1)
    })

    let maxFrequency = 0
    let mostFrequent = arr[0]

    frequencyMap.forEach((frequency, num) => {
        if (frequency > maxFrequency) {
            maxFrequency = frequency
            mostFrequent = num
        }
    })

    return mostFrequent
}
