import React, { useEffect, useRef, useState } from 'react'
import * as echarts from 'echarts'
import { EChartsOption, init, dispose, registerMap } from 'echarts'
import { Empty } from 'antd'
import { china } from '@/utils/dictionary'
/**通用直接传入原始配置EChartsOption*/
function Echarts(props: { children: EChartsOption | null, style?: { width: number | string, height: number | string } }) {
    const { style } = props
    const ref: { current: HTMLDivElement | null } = useRef(null)
    const [myChart, setMyChart] = useState<any>()
    /**创建myChart实例 */
    useEffect(() => {
        if (ref?.current && props?.children) {

            let myChart = init(ref.current)
            setMyChart(myChart)
            myChart.setOption(props.children);
            myChart.resize()
        }
    }, [ref?.current, props?.children])
    /**卸载myChart */
    useEffect(() => {
        return () => {
            if (myChart?.id) {
                dispose(myChart.id)
            }
        }
    }, [myChart?.id])
    return <>
        {
            props.children
                ?
                <div ref={ref} style={style ? style : { width: '100%', height: '100%' }} />
                :
                <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
                    <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
                </div>
        }
    </>
}
/**
 * Map粉丝统计 
 * @param data name省名称 vlaue值
 * @param style width ,height
*/
function Map(props: { data: { name: string, value: number }[], style?: { width: number | string, height: number | string } }) {
    const { data, style } = props
    const ref: { current: HTMLDivElement | null } = useRef(null)
    const [myChart, setMyChart] = useState<any>()
    /**创建myChart实例 */
    useEffect(() => {
        if (ref?.current && data.length > 0) {
            let myChart = init(ref.current)//初始化chart
            registerMap('China', require('../../public/map.json'))//获取地图数据
            let num: number[] = []//获取所有值方便取最大最小值
            let newData: any = china//处理匹配接口返回数据和地图数据的映射避免名字不同
            data.forEach((item: { name: string, value: number }) => {
                newData.forEach((data: { name: string, value: number }) => {
                    if (item.name && data.name.indexOf(item.name) !== -1) {
                        data.value = item.value
                        num.push(item.value)
                    }
                })
            })
            setMyChart(myChart)//存放Chart实例以备卸载
            myChart.setOption({//设置Chart配置
                /**悬浮提示 */
                tooltip: {
                    trigger: 'item',
                    formatter: '{b}:{c}'
                },
                /**右侧操作工具 */
                toolbox: {
                    show: true,
                    orient: 'vertical',
                    right: 50,
                    top: 'center',
                    feature: {
                        dataView: {
                            readOnly: false,
                            title: '查看详情'
                        },
                        restore: {
                            title: '刷新'
                        },
                        saveAsImage: {
                            title: '保存为图片'
                        }
                    }
                },
                /**左侧操作工具 */
                visualMap: {
                    min: 0,
                    max: Math.max(...num),
                    text: ['High', 'Low'],
                    realtime: false,
                    calculable: true,
                    top: 'middle',
                    inRange: {
                        color: ['lightskyblue', 'yellow', 'orangered']
                    }
                },
                /**地图参数设置 */
                series: [
                    {
                        name: '粉丝统计',
                        type: 'map',
                        map: 'China', // 自定义扩展图表类型
                        zoom: 1.2,
                        scaleLimit: { min: 1, max: 10 },
                        roam: true,
                        nameProperty: 'name',
                        data: newData,
                    }
                ],
            });
        }
    }, [ref?.current, data])
    /**卸载myChart */
    useEffect(() => {
        if (data.length === 0) {
            if (myChart?.id) {
                dispose(myChart.id)
            }
        }
        return () => {
            if (myChart?.id) {
                dispose(myChart.id)
            }
        }
    }, [myChart?.id, data])
    return <>
        {
            data.length > 0 && <div ref={ref} style={style ? style : { width: '100%', height: '100%' }} />
        }
        {
            data.length === 0 && <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
                <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
            </div>
        }
    </>
}
/**
 * 饼图总关注 
 * @param data name 名称 value 值
 * @param style width,height
 * @param name tooltip上的名字即饼图的名字
 * @param centerName 饼图中心统计的名称
*/
function PieFocus(props: {
    /**
     * @param data name 名称 value 值
     */
    data: { name: string, value: number }[],
    /**
     * @param name tooltip上的名字即饼图的名字
     */
    name: string,
    /**
     * @param centerName 饼图中心统计的名称
     */
    centerName: string,
    /**
    * @param style width,height
    */
    style?: { width: number | string, height: number | string },
}) {
    const { data, style, name, centerName } = props
    const ref: { current: HTMLDivElement | null } = useRef(null)
    const [myChart, setMyChart] = useState<any>()
    /**创建myChart实例 */
    useEffect(() => {
        if (ref?.current && data.length > 0) {
            let myChart = init(ref.current)
            setMyChart(myChart)
            myChart.setOption({
                /**鼠标悬浮 */
                tooltip: {
                    // trigger: 'item',
                    // formatter: '{a} <br />{b}: {c} ({d}%)'
                },
                /**图列 */
                legend: {
                    left: 'center',
                    bottom: 0,
                    data: data?.map((item: { name: string }) => item.name)
                },
                /**工具保存为图片 */
                toolbox: {
                    right: 50,
                    feature: {
                        saveAsImage: {
                            title: '保存为图片'
                        }
                    }
                },
                /**饼图参数 */
                series: [
                    {
                        name,
                        type: 'pie',
                        radius: ['50%', '70%'],
                        // avoidLabelOverlap: false,
                        label: {
                            show: true,
                            // position: 'center',
                            // fontSize: '30',
                            // fontWeight: 'bold',
                            formatter: `{b}:{c} ({d}%)`,
                        },
                        data
                    },
                    {
                        name,
                        type: 'pie',
                        radius: ['50%', '70%'],
                        label: {
                            show: true,
                            position: 'center',
                            fontSize: '30',
                            fontWeight: 'bold',
                            formatter: `${data.length > 1 ? data?.reduce((a: any, b: { value: number }) => {
                                return (a?.value || a) + (b?.value || 0)
                            }) : data[0].value}\n${centerName}`,
                        },
                        data
                    }
                ]
            });
        }
    }, [ref?.current, data])
    /**卸载myChart */
    useEffect(() => {
        if (data.length === 0) {
            if (myChart?.id) {
                dispose(myChart?.id)
            }
        }
        return () => {
            if (myChart?.id) {
                dispose(myChart?.id)
            }
        }
    }, [myChart?.id, data])
    return <>
        {
            data.length > 0 && <div ref={ref} style={style ? style : { width: '100%', height: '100%' }} />
        }
        {
            data.length === 0 && <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }} >
                <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
            </div>
        }
    </>
}
/**
 * Line 折线图
 * @param data legendName 图列名称 y:x(key为Y轴的展示的名称，value对应X轴的值。例:{legendName:'取消关注','2020-12-12':10,'2020-12-13':11,'2020-12-14':33}[])
 * @param style width,height
*/
function Line(props: {
    data?: { legendName: string, [key: string]: any }[],
    style?: React.CSSProperties,
    areaStyle?: boolean,//线变块颜色
    color?: string | string[],//线颜色
    markPoint?: any,//浮点
    fontColor?: string,//文字颜色
    series?: boolean,//堆叠
    title?: string,//标题
    smooth?: boolean,//true 圆弧线 false 直角
}) {
    const { data, style, areaStyle = false, color, markPoint, fontColor, series, title, smooth = false } = props
    const ref: { current: HTMLDivElement | null } = useRef(null)
    const [myChart, setMyChart] = useState<any>()
    let textStyle = fontColor ? { textStyle: { color: fontColor } } : {}
    /**创建myChart实例 */
    useEffect(() => {
        if (ref?.current && (data as any[]).length > 0) {
            let Xdata: any = []
            let Ydatas: any[] = []
            data?.forEach((item, index) => {
                Ydatas.push([])
                Object.keys(item).forEach((key: string) => {
                    if (index === 0 && key !== 'legendName') {
                        Xdata.push(key)
                    }
                    if (key !== 'legendName') {
                        Ydatas[index].push(item[key])
                    }
                })
            })

            let myChart = init(ref.current)
            setMyChart(myChart)
            myChart.setOption({
                /**鼠标悬浮 */
                tooltip: {
                    trigger: 'axis'
                },
                /**图列 */
                legend: {
                    data: (data as { legendName: string, [key: string]: any }[]).map((item: { legendName: string }) => item.legendName),
                    bottom: 0,
                    left: 'center',
                    ...textStyle
                },
                xAxis: {
                    data: Xdata,
                    boundaryGap: false,//贴边
                },
                yAxis: [
                    {
                        type: 'value',
                    },
                ],
                grid: {
                    left: 100,
                    right: 50,
                },
                ...textStyle,
                /**工具保存为图片 */
                toolbox: {
                    right: 50,
                    feature: {
                        saveAsImage: {
                            title: '保存为图片'
                        }
                    }
                },
                title: {
                    text: title || '',
                    textAlign: 'center',
                    right: 'center'
                },
                /**线图参数 */
                series: (data as { legendName: string, [key: string]: any }[]).map((item: { legendName: string }, index: number) => {
                    return {
                        name: item.legendName,//名称
                        type: 'line',//图形
                        data: Ydatas[index],//数据
                        areaStyle: areaStyle ? {} : undefined,//是否开启块级颜色
                        color: Array.isArray(color) ? color[index] : color,//颜色
                        markPoint: {//最大值最小值
                            data: markPoint ? markPoint : []
                        },
                        emphasis: series ? { focus: 'series' } : {}, //堆叠
                        smooth
                    }
                })
            });
        }
    }, [ref?.current, data])
    /**卸载myChart */
    useEffect(() => {
        if ((data as any[])?.length === 0) {
            if (myChart?.id) {
                dispose(myChart?.id)
            }
        }
        return () => {
            if (myChart?.id) {
                dispose(myChart.id)
            }
        }
    }, [myChart?.id, data])
    return <>
        {
            (data as any[])?.length > 0 && <div ref={ref} style={style ? style : { width: '100%', height: '100%' }} />

        }
        {
            (data as any[])?.length === 0 && <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
                <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
            </div>
        }
    </>
}

/**
 * Bar 柱状图
 * @param data legendName 图列名称 y:x(key为Y轴的展示的名称，value对应X轴的值。例:{legendName:'取消关注','2020-12-12':10,'2020-12-13':11,'2020-12-14':33}[])
 * @param style width,height
*/
function Bar(props: {
    data?: { legendName: string, [key: string]: any }[],
    style?: React.CSSProperties,
    fontColor?: string,//文字颜色
    title?: string,//标题
}) {
    const { data, style, fontColor, title } = props
    const ref: { current: HTMLDivElement | null } = useRef(null)
    const [myChart, setMyChart] = useState<any>()
    let textStyle = fontColor ? { textStyle: { color: fontColor } } : {}
    /**创建myChart实例 */
    useEffect(() => {
        if (ref?.current && (data as any[]).length > 0) {
            let Xdata: any = []     // name
            let Ydatas: any[] = []  // value
            data?.forEach((item) => {
                Xdata.push(item.name)
                Ydatas.push(item.value)
            })
            let sum = eval(Ydatas.join("+"))
            Ydatas = Ydatas.map((item: number) => {
                return (item / sum * 100).toFixed(0)
            })
            let myChart = init(ref.current)
            setMyChart(myChart)
            myChart.setOption({
                /**鼠标悬浮 */
                // tooltip: {
                //     trigger: 'axis',
                // },
                xAxis: {
                    max: 'dataMax'
                },
                yAxis: {
                    type: 'category',
                    data: Xdata,
                    inverse: true
                },
                grid: {
                    left: 100,
                    right: 50,
                },
                ...textStyle,
                title: {
                    text: title || '',
                    textAlign: 'center',
                    right: 'center'
                },
                /**线图参数 */
                series: [
                    {
                        type: 'bar',//图形
                        realtimeSort: true,
                        data: Ydatas,//数据
                        name: 'X',
                        label: {
                            show: true,
                            position: 'right',
                            valueAnimation: true,
                        }
                    }
                ]
            });
        }
    }, [ref?.current, data])
    /**卸载myChart */
    useEffect(() => {
        if ((data as any[])?.length === 0) {
            if (myChart?.id) {
                dispose(myChart?.id)
            }
        }
        return () => {
            if (myChart?.id) {
                dispose(myChart.id)
            }
        }
    }, [myChart?.id, data])
    return <>
        {
            (data as any[])?.length > 0 && <div ref={ref} style={style ? style : { width: '100%', height: '100%' }} />

        }
        {
            (data as any[])?.length === 0 && <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
                <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
            </div>
        }
    </>
}


/**
 * Bar 柱状图
 * @param data legendName 图列名称 y:x(key为Y轴的展示的名称，value对应X轴的值。例:{legendName:'取消关注','2020-12-12':10,'2020-12-13':11,'2020-12-14':33}[])
 * @param style width,height
*/
// [
//     { name: '4341556373', value: 300 }, { name: '4341523456', value: 240 },
// ]
function BarMonitor(props: {
    data?: { legendName: string, [key: string]: any }[],
    style?: React.CSSProperties,
    fontColor?: string,//文字颜色
    title?: string,//标题
    isGraphic?: boolean, // 是否渐变
    xName?: string,
    yName?: string,
    planID?: string,
    onChange?: (id: string, accountId: number[]) => void,
}) {
    const { data, style, fontColor, title, xName, yName, planID, onChange } = props
    const colors = ['#f8128d', '#fa40a3', '#f56db5', '#f58bc4', '#f7a1cf', '#f5b7d8', '#facee5', '#f8c8e2', '#f8d6e8', '#fae8f1']
    const ref: { current: HTMLDivElement | null } = useRef(null)
    const [myChart, setMyChart] = useState<any>()
    let textStyle = fontColor ? { textStyle: { color: fontColor } } : {}

    /**创建myChart实例 */
    useEffect(() => {
        if (ref?.current && (data as any[]).length > 0) {
            let Xdata: any = []     // name
            let Ydatas: any[] = []  // value
            data?.forEach((item) => {
                Xdata.push(item.adName)
                Ydatas.push(item.value)
            })
            let dataIndex = data?.findIndex((item: any) => item?.name == planID)
            Ydatas = Ydatas.map((item: number, index: number) => {
                if (dataIndex !== -1 && dataIndex === index) {
                    return {
                        value: item,
                        itemStyle: {
                            color: '#37A2FF',
                            shadowColor: 'rgba(0, 0, 0, 0.8)',
                            shadowBlur: 10,
                        },
                    }
                } else {
                    return {
                        value: item,
                        itemStyle: {
                            color: colors[index],
                        }
                    }
                }

            })
            let myChart = init(ref.current)
            setMyChart(myChart)
            myChart?.setOption({
                /**鼠标悬浮 */
                // tooltip: {
                //     trigger: 'axis',
                // },
                xAxis: {
                    name: xName || '',
                    max: 'dataMax',
                    nameTextStyle: {  // y轴名字文字样式设置
                        verticalAlign: "bottom",
                        lineHeight: 5,
                        fontWeight: 'bold',
                    },
                    axisLine: {  // 坐标轴轴线相关设置
                        show: true   // 是否显示坐标轴轴线
                    },
                },
                yAxis: {
                    name: yName || '',
                    type: 'category',
                    data: Xdata,
                    inverse: true,
                    nameLocation: 'start',  // y轴名字显示位置 
                    nameTextStyle: {  // y轴名字文字样式设置
                        verticalAlign: "bottom",
                        lineHeight: 0,
                        fontWeight: 'bold',
                        color: '#000',
                        padding: [0, 80, 0, 0]
                    },
                    nameGap: 20,
                    triggerEvent: true,
                    axisLabel: {//名称
                        margin: 10,
                        width: 80,
                        overflow: 'truncate',
                        ellipsis: '...',
                        color: (value: any, index: any) => {
                            if (index === dataIndex) {
                                return '#f8128d'
                            }
                            return '#3946c3'
                        },
                    },
                },
                grid: {
                    left: 100,
                    right: 70
                },
                ...textStyle,
                title: {
                    text: title || '起量广告排行榜',
                    textStyle: {
                        color: '#3946c3',
                        fontSize: 16
                    },
                    left: 'center',
                    bottom: 0,
                },
                tooltip: {
                    show: true,
                    // formatter:'{b0}: {c0}',
                    formatter: function (a: any) {
                        return `${a.marker}  <strong> ${a.name} : ${a.value}</strong>`
                    }
                },
                series: [
                    {
                        type: 'bar',//图形
                        realtimeSort: true,
                        data: Ydatas,//数据
                        name: 'X',
                        showBackground: true,
                        backgroundStyle: {
                            color: 'transparent'
                        },
                        label: {
                            show: true,
                            valueAnimation: true,
                            position: 'right',
                            fontSize: 14,
                            fontWeight: 900
                        }
                    }
                ]
            });
            myChart.on('click', (params: any) => {
                let v = params.dataIndex
                let d: any = (data as any[])[v]
                onChange && onChange(d.name, [d.accountId])
            });
        }
    }, [ref?.current, data, planID])
    /**卸载myChart */
    useEffect(() => {
        if ((data as any[])?.length === 0) {
            if (myChart?.id) {
                dispose(myChart?.id)
            }
        }
        return () => {
            if (myChart?.id) {
                dispose(myChart.id)
            }
        }
    }, [myChart?.id, data])
    return <>
        {
            (data as any[])?.length > 0 && <div ref={ref} style={style ? style : { width: '100%', height: '100%' }} />

        }
        {
            (data as any[])?.length === 0 && <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
                <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
            </div>
        }
    </>
}

/**
 * Line 折线图
 * @param data legendName 图列名称 y:x(key为Y轴的展示的名称，value对应X轴的值。例:{legendName:'取消关注','2020-12-12':10,'2020-12-13':11,'2020-12-14':33}[])
 * @param style width,height
*/
function LineMonitor(props: {
    data?: { legendName: string, [key: string]: any }[],
    style?: React.CSSProperties,
    areaStyle?: boolean,//线变块颜色
    color?: string | string[],//线颜色
    markPoint?: any,//浮点
    fontColor?: string,//文字颜色
    series?: boolean,//堆叠
    title?: string,//标题
    smooth?: boolean,//true 圆弧线 false 直角
    dataZoomInside?: boolean,  // 控制是否开启滚轮缩放
    dataZoomSlider?: boolean,  // 控制是否开启组件缩放
}) {
    const { data, style, areaStyle = false, color, markPoint, fontColor, series, title, smooth = false, dataZoomInside, dataZoomSlider } = props
    const ref: { current: HTMLDivElement | null } = useRef(null)
    const [myChart, setMyChart] = useState<any>()
    let textStyle = fontColor ? { textStyle: { color: fontColor } } : {}
    /**创建myChart实例 */
    useEffect(() => {
        if (ref?.current && (data as any[]).length > 0) {
            let Xdata: any = []
            let Ydatas: any[] = []
            data?.forEach((item, index) => {
                Ydatas.push([])
                Object.keys(item).forEach((key: string) => {
                    if (index === 0 && key !== 'legendName') {
                        Xdata.push(key)
                    }
                    if (key !== 'legendName') {
                        Ydatas[index].push(item[key])
                    }
                })
            })
            let myChart = init(ref.current)
            // 设置是否可缩放
            let dataZoom = []
            if (dataZoomInside) {
                dataZoom.push({
                    type: 'inside'
                })
            }
            if (dataZoomSlider) {
                dataZoom.push({
                    type: 'slider',
                    width: 200,
                    height: 20,
                    top: 0,
                    left: 140,
                    disabled: dataZoomSlider
                })
            }
            setMyChart(myChart)
            myChart.setOption({
                /**鼠标悬浮 */
                tooltip: {
                    trigger: 'axis'
                },
                /**图列 */
                legend: {
                    data: (data as { legendName: string, [key: string]: any }[]).map((item: { legendName: string }) => item.legendName),
                    bottom: 0,
                    left: 'center',
                    show: data && data?.length > 1 ? true : false,//数据只有一条就隐藏
                    ...textStyle
                },
                xAxis: {
                    data: Xdata,
                    boundaryGap: false,//贴边
                },
                yAxis: [
                    {
                        type: 'value',
                        axisLabel: {//名称
                            fontWeight: 900,
                            fontSize: 15,
                            color: '#333333',
                            textBorderColor: '#dfdfdf',
                            textBorderWidth: 1
                        },
                    },
                ],
                dataZoom,
                grid: {
                    left: 100,
                    right: 50,
                },
                ...textStyle,
                /**工具保存为图片 */
                toolbox: {
                    right: 50,
                    // feature: {
                    //     saveAsImage: {
                    //         title: '保存为图片'
                    //     }
                    // }
                },
                title: {
                    text: title || '',
                    left: 'center',
                    bottom: 0,
                    textStyle: {
                        color: '#3946c3',
                        fontSize: 16
                    },
                },
                /**线图参数 */
                series: (data as { legendName: string, [key: string]: any }[]).map((item: { legendName: string }, index: number) => {
                    return {
                        name: item.legendName,//名称
                        type: 'line',//图形
                        data: Ydatas[index],//数据
                        areaStyle: areaStyle ? {} : undefined,//是否开启块级颜色
                        color: Array.isArray(color) ? color[index] : color,//颜色
                        markPoint: {//最大值最小值
                            data: markPoint ? markPoint : []
                        },
                        emphasis: series ? { focus: 'series' } : {}, //堆叠
                        smooth
                    }
                })
            });
        }
    }, [ref?.current, data])
    /**卸载myChart */
    useEffect(() => {
        if ((data as any[])?.length === 0) {
            if (myChart?.id) {
                dispose(myChart?.id)
            }
        }
        return () => {
            if (myChart?.id) {
                dispose(myChart.id)
            }
        }
    }, [myChart?.id, data])
    return <>
        {
            (data as any[])?.length > 0 && <div ref={ref} style={style ? style : { width: '100%', height: '100%' }} />

        }
        {
            (data as any[])?.length === 0 && <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
                <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
            </div>
        }
    </>
}

/**
 * 常用option配置//https://echarts.apache.org/next/zh/option.html#legend
 * @param legend 图例组件 用于用户操作筛选图表展示的组件
 * @param title 图标标题 
 * @param grid 网格控制 可在一个渲染框架中渲染多个图表 或单个图表的间距宽高等值的设定
 * @param xAxis grid 中的 x 轴的设置
 * @param yAxis grid 中的 y 轴的设置
 * @param tooltip 鼠标悬浮的提示组件
 * @param series 系列数据配置
 */
function useEcharts() {
    return {
        Echarts,
        Map,
        PieFocus,
        Line,
        Bar,
        BarMonitor,
        LineMonitor
    }
}
export default useEcharts