import { ref, watch } from 'vue'
import { EChartsOption } from 'echarts';
import { Dataset, Candlestick, MACD, VOL, KDJ, CCI, Colors } from './type'
import { getTheme, ThemeEnum } from '@/common/config/theme';
import { throttle } from '@/utils/time'
import moment from 'moment';

export function useOptions(klineData: Dataset<Candlestick>, macdData: Dataset<MACD>, volData: Dataset<VOL>, kdjData: Dataset<KDJ>, cciData: Dataset<CCI>) {
    const theme = getTheme(),
        klineOption = ref<EChartsOption>({}),
        macdOption = ref<EChartsOption>({}),
        volOption = ref<EChartsOption>({}),
        kdjOption = ref<EChartsOption>({}),
        cciOption = ref<EChartsOption>({});

    const getDefaultOption = (): EChartsOption => {
        const { xAxisLineColor } = getColors();
        return {
            dataZoom: {
                type: 'inside',
                startValue: klineData.source.length - 120, // 起始显示K线条数(最新120条)
                endValue: klineData.source.length,
                minValueSpan: 50, // 限制窗口缩放显示最少数据条数
                maxValueSpan: 400, // 限制窗口缩放显示最大数据条数
            },
            xAxis: {
                type: 'category',
                axisLabel: {
                    formatter: (val: string) => moment(val).format('YYYY/MM/DD'),
                    margin: 12,
                },
            },
            yAxis: {
                scale: true,
                splitLine: {
                    lineStyle: {
                        // 坐标分隔线颜色
                        color: xAxisLineColor,
                    },
                },
            },
        }
    }

    // K线配置项
    const setKlineOption = () => {
        const { seriesMarkLineColor, seriesMarkLabelColor } = getColors();
        const { dimensions, source } = klineData;

        klineOption.value = {
            ...getDefaultOption(),
            dataset: {
                dimensions,
                source,
            },
            series: [
                {
                    name: 'K线',
                    type: 'candlestick',
                    // 最新价标线
                    markLine: {
                        // 标线两端图标
                        symbol: 'none',
                        // 标线标签样式
                        label: {
                            color: seriesMarkLabelColor,
                            fontWeight: 'bold',
                            backgroundColor: 'rgba(255,255,255,.75)',
                            padding: 5,
                            borderRadius: 3
                        },
                        // 标线样式
                        lineStyle: {
                            type: 'dashed',
                            color: seriesMarkLineColor,
                        },
                        data: [
                            {
                                // 收盘价
                                yAxis: source.length ? source[source.length - 1].close : 0,
                            },
                        ],
                    },
                },
                {
                    name: 'MA5',
                    type: 'line',
                    sampling: 'average', //折线图在数据量远大于像素点时候的降采样策略，开启后可以有效的优化图表的绘制效率
                    smooth: true,
                    symbol: 'none',
                    lineStyle: {
                        width: 1,
                        opacity: 0.8,
                    },
                },
                {
                    name: 'MA10',
                    type: 'line',
                    sampling: 'average',
                    smooth: true,
                    symbol: 'none',
                    lineStyle: {
                        width: 1,
                        opacity: 0.8,
                    },
                },
                {
                    name: 'MA15',
                    type: 'line',
                    sampling: 'average',
                    smooth: true,
                    symbol: 'none',
                    lineStyle: {
                        width: 1,
                        opacity: 0.8,
                    },
                },
            ],
        }
    }

    // MACD配置项
    const setMacdOption = () => {
        const { upColor, downColor } = getColors();
        const { dimensions, source } = macdData;
        macdOption.value = {
            ...getDefaultOption(),
            dataset: {
                dimensions,
                source,
            },
            series: [
                {
                    name: 'MACD',
                    type: 'bar',
                    sampling: 'average',
                    barWidth: '20%',
                    itemStyle: {
                        color: (params: any) => {
                            if (params.data.macd > 0) {
                                return upColor;
                            } else {
                                return downColor;
                            }
                        },
                    }
                },
                {
                    name: 'DIF',
                    type: 'line',
                    sampling: 'average',
                    smooth: true,
                    symbol: 'none',
                    lineStyle: {
                        width: 1,
                        opacity: 0.8,
                    },
                },
                {
                    name: 'DEA',
                    type: 'line',
                    sampling: 'average',
                    smooth: true,
                    symbol: 'none',
                    lineStyle: {
                        width: 1,
                        opacity: 0.8,
                    },
                },
            ],
        }
    }

    // VOL配置项
    const setVolOption = () => {
        const { upColor, downColor } = getColors();
        const { dimensions, source } = volData;

        volOption.value = {
            ...getDefaultOption(),
            dataset: {
                dimensions,
                source,
            },
            series: [
                {
                    name: 'VOL',
                    type: 'bar',
                    sampling: 'average',
                    barWidth: '60%',
                    itemStyle: {
                        color: (params: any) => {
                            const { close, open } = klineData.source[params.dataIndex]
                            // 判断收盘价是否高于或等于开盘价
                            if (close >= open) {
                                return upColor;
                            } else {
                                return downColor;
                            }
                        },
                    }
                },
            ],
        }
    }

    // KDJ配置项
    const setKdjOption = () => {
        const { dimensions, source } = kdjData;
        kdjOption.value = {
            ...getDefaultOption(),
            dataset: {
                dimensions,
                source,
            },
            series: [
                {
                    name: 'K',
                    type: 'line',
                    sampling: 'average',
                    smooth: true,
                    symbol: 'none',
                    lineStyle: {
                        width: 1,
                        opacity: 0.8,
                    },
                },
                {
                    name: 'D',
                    type: 'line',
                    sampling: 'average',
                    smooth: true,
                    symbol: 'none',
                    lineStyle: {
                        width: 1,
                        opacity: 0.8,
                    },
                },
                {
                    name: 'J',
                    type: 'line',
                    sampling: 'average',
                    smooth: true,
                    symbol: 'none',
                    lineStyle: {
                        width: 1,
                        opacity: 0.8,
                    },
                },
            ],
        }
    }

    // CCI配置项
    const setCciOption = () => {
        const { dimensions, source } = cciData;
        cciOption.value = {
            ...getDefaultOption(),
            dataset: {
                dimensions,
                source,
            },
            series: [
                {
                    name: 'CCI',
                    type: 'line',
                    sampling: 'average',
                    smooth: true,
                    symbol: 'none',
                    lineStyle: {
                        width: 1,
                        opacity: 0.8,
                    },
                },
            ],
        }
    }

    // 获取图表主题色
    const getColors = (): Colors => {
        switch (theme.value) {
            case ThemeEnum.default:
            case ThemeEnum.dark: {
                return {
                    upColor: '#eb5454',
                    downColor: '#47b262',
                    xAxisLineColor: '#171B1D',
                    yAxisLineColor: '#171B1D',
                    seriesMarkLabelColor: '#3C454B',
                    seriesMarkLineColor: '#666',
                };
            }
            case ThemeEnum.light: {
                return {
                    upColor: '#eb5454',
                    downColor: '#47b262',
                    xAxisLineColor: '#DAE5EC',
                    yAxisLineColor: '#DAE5EC',
                    seriesMarkLabelColor: '#777',
                    seriesMarkLineColor: '#ACB8C0',
                };
            }
        }
    }

    const initOptions = (onReady?: () => void) => {
        setKlineOption();
        setMacdOption();
        setVolOption();
        setKdjOption();
        setCciOption();
        onReady && onReady();
    }

    // 动态更新数据
    const updateOptions = throttle(() => {
        const klineSource = klineData.source;
        const macdSource = macdData.source;
        const volSource = volData.source;
        const kdjSource = kdjData.source;
        const cciSource = cciData.source;

        klineOption.value = {
            dataset: {
                source: klineSource,
            },
            series: [
                {
                    name: 'K线',
                    markLine: {
                        data: [
                            {
                                yAxis: klineSource[klineSource.length - 1].close,
                            },
                        ],
                    },
                },
            ],
        }
        macdOption.value = {
            dataset: {
                source: macdSource,
            },
        }
        volOption.value = {
            dataset: {
                source: volSource,
            },
        }
        kdjOption.value = {
            dataset: {
                source: kdjSource,
            },
        }
        cciOption.value = {
            dataset: {
                source: cciSource,
            },
        }
    }, 1000)

    // 监听主题变化
    watch(theme, () => initOptions());

    return {
        klineOption,
        macdOption,
        volOption,
        kdjOption,
        cciOption,
        initOptions,
        updateOptions,
    }
}