import { reactive } from 'vue'
import { getRangeTime } from '@/utils/time'
import { EchartsDataset } from './interface'

export function useDataset() {
    const dataset = reactive<EchartsDataset>({
        invalid: [],
        rawDate: [],
        yestclose: 0,
        decimal: 0,
        maxMark: 0,
        minMark: 0,
        interval: 0,
        timeline: {
            dimensions: ['date', 'close', 'ma5'],
            source: {
                date: [],
                close: [],
                ma5: []
            },
        }
    })

    // 清空数据
    const clearData = () => {
        dataset.invalid = [];
        dataset.rawDate = [];
        dataset.yestclose = 0;
        dataset.decimal = 0;
        dataset.maxMark = 0;
        dataset.minMark = 0;
        dataset.interval = 0;
        dataset.timeline.source = {
            date: [],
            close: [],
            ma5: []
        };
    }

    // 处理行情数据
    const handleData = (rawData: Model.QueryTSDataRsp, onReady?: () => void) => {
        const { date, close, ma5 } = dataset.timeline.source;
        const { preSettle, decimalPlace, runSteps, historyDatas } = rawData;

        dataset.decimal = decimalPlace;
        dataset.yestclose = preSettle;

        // 开盘交易时间
        for (let i = 0; i < runSteps.length; i++) {
            const { start, end } = runSteps[i];
            const rangeTime = getRangeTime(start, end, 'HH:mm', 'm');
            date.push(...rangeTime);
        }

        for (let i = 0; i < historyDatas.length; i++) {
            const { ts, c, f } = historyDatas[i];
            if (f) dataset.invalid.push(i); // 添加补充数据的索引位置

            dataset.rawDate.push(ts);
            close.push(c);
            ma5.push('-');
        }
        // 计算各种指标
        calcIndicator();
        onReady && onReady();
    }

    // 计算MA
    const calcMA = (startIndex = 0) => {
        const { close, ma5 } = dataset.timeline.source;
        for (let i = startIndex; i < close.length; i++) {
            // 判断是否补充数据
            if (dataset.invalid.includes(i)) {
                ma5[i] = i > 0 ? ma5[i - 1].toString() : '--'; // 如果存在，取上一条记录的MA值
            } else {
                let n = 0;
                const tmpList: number[] = [];

                for (let j = i; j >= 0; j--) {
                    if (dataset.invalid.includes(j)) continue; // 如果是补充数据，跳过本次循环
                    if (n === 5) break; // 如果 n 等于计数，结束循环
                    tmpList.push(close[j]);
                    n++;
                }

                if (n === 5) {
                    // 计算总价(收盘价总和)
                    const total = tmpList.reduce((res, val) => res + val, 0);
                    // 计算均价
                    ma5[i] = (total / 5).toFixed(2);
                } else {
                    ma5[i] = '--';
                }
            }
        }
    }

    // 计算图表最高最低指标线
    const calcMarkLine = () => {
        const { close } = dataset.timeline.source;
        const point = Math.pow(10, -dataset.decimal) * 10; // 图表上下保留10个报价点数
        let max = Math.max(...close); // 取历史行情最高价
        let min = Math.min(...close); // 取历史行情最低价

        const last = close[close.length - 1], // 历史行情最后收盘价
            a = dataset.yestclose - min, // 计算收盘价和最低价的差值
            b = max - dataset.yestclose; // 计算收盘价和最高价的差值

        // 比较差值大小
        if (a > b) {
            max = dataset.yestclose + a;
            if (last > max) {
                const c = last - max;
                max += c;
                min -= c;
            }
        } else {
            min = min - (b - a);
            if (min > last) {
                const c = min - last;
                max += c;
                min -= c;
            }
        }

        dataset.maxMark = max + point;
        dataset.minMark = min - point;
        dataset.interval = (dataset.maxMark - dataset.minMark) / 6;
    }

    // 计算各项指标
    const calcIndicator = (startIndex = 0) => {
        calcMA(startIndex);
        calcMarkLine();
    }

    return {
        dataset,
        handleData,
        clearData,
        calcIndicator,
    }
}