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)
    let maxValue = 0
    let minValue = 0
    let max = 0
    let min = 0
    maxValue = Math.max(...numList)
    minValue = Math.min(...numList)
    const o = maxValue - minValue == 0 ? maxValue : maxValue - minValue
    min = calculateValue(o, minValue, num, true)

    max = calculateValue(o, maxValue, num, false)
    // if (-100 >= minValue) {
    //     min = Math.floor((minValue + num * minValue) / 100) * 100
    // } else if (-10 >= minValue && minValue > -100) {
    //     min = Math.floor((minValue + num * minValue) / 10) * 10
    // } else if (-1 >= minValue && minValue > -10) {
    //     min = Math.floor(minValue + num * minValue)
    // } else if (0 > minValue && minValue > -1) {
    //     min = parseFloat((minValue + num * minValue).toFixed(1))
    // } else if (minValue == 0) {
    //     min = 0
    // } else if (0 < minValue && minValue < 1) {
    //     min = parseFloat((minValue - num * minValue).toFixed(1))
    // } else if (1 <= minValue && minValue < 10) {
    //     min = Math.floor(minValue - num * minValue)
    // } else if (10 <= minValue && minValue < 100) {
    //     min = Math.floor((minValue - num * minValue) / 10) * 10
    // } else if (100 <= minValue) {
    //     min = Math.floor((minValue - num * minValue) / 100) * 100
    // }

    // if (-100 >= maxValue) {
    //     max = Math.ceil((maxValue - num * maxValue) / 100) * 100
    // } else if (-10 >= maxValue && maxValue > -100) {
    //     max = Math.ceil((maxValue - num * maxValue) / 10) * 10
    // } else if (-1 >= maxValue && maxValue > -10) {
    //     max = Math.ceil(maxValue - num * maxValue)
    // } else if (0 > maxValue && maxValue > -1) {
    //     max = parseFloat((maxValue - num * maxValue).toFixed(1))
    // } else if (maxValue == 0) {
    //     max = 0
    // } else if (0 < maxValue && maxValue < 1) {
    //     max = parseFloat((maxValue + num * maxValue).toFixed(1))
    // } else if (1 <= maxValue && maxValue < 10) {
    //     max = Math.ceil(maxValue + num * maxValue)
    // } else if (10 <= maxValue && maxValue < 100) {
    //     max = Math.ceil((maxValue + num * maxValue) / 10) * 10
    // } else if (100 <= maxValue) {
    //     max = Math.ceil((maxValue + num * maxValue) / 100) * 100
    // }

    // if (maxValue > 1000 || minValue < -1000) {
    //     max = Math.ceil(maxValue / 100) * 100
    //     if (minValue == 0) {
    //         min = 0
    //     } else {
    //         min = Math.floor(minValue / 100) * 100
    //     }
    // } else if (maxValue < 60 && minValue > 40) {
    //     max = 60
    //     min = 40
    // } else if (maxValue == minValue && maxValue < 10 && minValue > 0) {
    //     max = Math.ceil(maxValue / 10) * 10
    //     min = Math.floor(minValue / 10) * 10
    // } else if (maxValue == minValue && maxValue != 0 && minValue != 0) {
    //     max = Math.ceil(maxValue / 10 + 1) * 10
    //     min = Math.floor(minValue / 10 - 1) * 10
    // } else {
    //     max = Math.ceil(maxValue / 10) * 10
    //     min = Math.floor(minValue / 10) * 10
    // }

    // if (maxValue > 0 && maxValue < 1) {
    //     max = 1
    // } else if (max == 0 && minValue > -1 && minValue < 0) {
    //     min = -1
    // }
    if (max > 1 && max < 10) {
        max = Math.ceil(max)
    }

    return [min, max]
}

export interface ExportFileNameOptions {
    subject?: string
    feature: string
    date?: string | Date | string[] | null
    ext?: string
}

/** 导出文件名中的日期，固定为当前年月日 yyyy-mm-dd */
export const formatExportDate = (): string => {
    const pad = (n: number) => String(n).padStart(2, '0')
    const now = new Date()
    return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`
}

/** 波形下载文件名中的时间，固定为当前时间 yyyy-mm-dd-HH-mm-ss */
export const formatExportDateTime = (): string => {
    const pad = (n: number) => String(n).padStart(2, '0')
    const now = new Date()
    return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`
}

/** 监测点 / 设备 / 项目（可选）_ 功能 _ yyyy-mm-dd（当前日期） */
export const buildExportBaseName = (options: Pick<ExportFileNameOptions, 'subject' | 'feature' | 'date'>): string => {
    const { subject, feature } = options
    const dateStr = formatExportDate()
    return [subject?.trim(), feature?.trim(), dateStr].filter(part => part).join('_')
}

/** 波形 zip 下载：监测点_波形_yyyy-mm-dd-HH-mm-ss.zip（当前时间） */
export const buildWaveExportFileName = (subject?: string): string => {
    const base = [subject?.trim(), '波形', formatExportDateTime()].filter(part => part).join('_')
    return `${base}.zip`
}

export const buildExportFileName = (options: ExportFileNameOptions): string => {
    const ext = (options.ext || 'csv').replace(/^\./, '')
    return `${buildExportBaseName(options)}.${ext}`
}

export const resolveExportFileName = (filenameOrOptions: string | ExportFileNameOptions): string => {
    if (typeof filenameOrOptions === 'string') {
        return filenameOrOptions
    }
    return buildExportFileName(filenameOrOptions)
}

/** 从行数据中取监测点 / 设备 / 项目名称 */
export const getExportSubjectFromRow = (row: any): string =>
    row?.lineName || row?.equipmentName || row?.projectName || row?.engineeringName || row?.name || ''

/**
 * title['A相','B相',]
 * data[[1,2],[3,4]]
 */
// 导出csv文件
const convertToCSV = (title: object, data: any) => {
    let csv = ''
    // 添加列头
    csv += ',' + title.join(',') + '\n'
    // 遍历数据并添加到CSV字符串中
    data?.map(item => {
        csv += '\u200B' + item.join(',') + '\n'
    })
    return csv
}
export const exportCSV = (title: object, data: any, filenameOrOptions: string | ExportFileNameOptions) => {
    const filename = resolveExportFileName(filenameOrOptions)
    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)
}

/**
 * 将多条折线按时间对齐合并为 CSV 行（避免各 series 长度不一致时按索引对齐丢数据）
 */
export const buildSeriesCsvData = (seriesList: Array<{ name: string; data?: any[] }>) => {
    if (!seriesList?.length) {
        return { titles: [], rows: [] }
    }
    const titles = seriesList.map(s => s.name)
    const timeMap = new Map<string, (string | number | null)[]>()

    seriesList.forEach((series, seriesIndex) => {
        series.data?.forEach((point: any) => {
            const time = point?.[0]
            if (!time) return
            const timeKey = String(time)
            if (!timeMap.has(timeKey)) {
                timeMap.set(timeKey, [timeKey, ...Array(seriesList.length).fill(null)])
            }
            const row = timeMap.get(timeKey)!
            row[seriesIndex + 1] = point[1] ?? null
        })
    })

    const rows = Array.from(timeMap.values()).sort(
        (a, b) => new Date(a[0] as string).getTime() - new Date(b[0] as string).getTime()
    )
    return { titles, rows }
}

export const exportSeriesCSV = (
    seriesList: Array<{ name: string; data?: any[] }>,
    filenameOrOptions: string | ExportFileNameOptions
) => {
    const { titles, rows } = buildSeriesCsvData(seriesList)
    if (!rows.length) return
    exportCSV(titles, rows, filenameOrOptions)
}

/**
 * 补全时间序列数据中缺失的条目
 * @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
        }
    })

    // 补首尾边界：首日 00:00:00、末日 23:59:59
    const createPadItem = (timeStr: string): (string | null | undefined)[] => {
        const result: (string | null | undefined)[] = [timeStr, '/']
        if (template.length > 2) result.push(template[2])
        if (template.length > 3) result.push(template[3])
        return result
    }

    const firstDate = new Date(completedData[0][0] as string)
    const dayStartStr = formatTime(
        new Date(firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate(), 0, 0, 0)
    )

    const lastDate = new Date(completedData[completedData.length - 1][0] as string)
    const dayEndStr = formatTime(new Date(lastDate.getFullYear(), lastDate.getMonth(), lastDate.getDate(), 23, 59, 59))

    const firstTimeStr = formatTime(new Date(completedData[0][0] as string))
    if (firstTimeStr !== dayStartStr) {
        completedData.unshift(createPadItem(dayStartStr))
    }

    const lastTimeStr = formatTime(new Date(completedData[completedData.length - 1][0] as string))
    if (lastTimeStr !== dayEndStr) {
        completedData.push(createPadItem(dayEndStr))
    }

    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
}
