import React, {useState, useEffect, useRef, useContext} from 'react';
import classNames from 'classnames';
import moment from 'moment';
import Empty from '@wisdom-components/empty';
import LoadBox from '@wisdom-components/loadbox';
import BasicTable from '@wisdom-components/basictable';
import {ExportExcel} from '@wisdom-components/exportexcel';
import {ConfigProvider, Select, DatePicker, Radio, Table, Button} from 'antd';
import {VerticalAlignBottomOutlined} from '@ant-design/icons';
import {BasicChart} from '@wisdom-components/basicchart';
import {getStatisticsInfo} from './apis';
import './index.less';

const StatisticalHistoryView = (props) => {
    const {getPrefixCls} = useContext(ConfigProvider.ConfigContext);
    const prefixCls = getPrefixCls('ec-statistical-history-view');
    const chartRef = useRef(null);
    const defaultOptionRef = useRef({
        title: {
            show: false,
            text: '',
        },
        tooltip: false,
        grid: {
            containLabel: true,
            left: 20,
            right: 20,
            // top: 20,
            bottom: 10,
        },
        toolbox: {
            show: false,
        },
        xAxis: [
            {
                type: 'time',
                axisTick: {
                    alignWithLabel: true,
                },
                boundaryGap: false,
                splitLine: {
                    show: true,
                    lineStyle: {
                        type: 'dashed',
                    },
                },
            },
        ],
        yAxis: [
            {
                type: 'value',
                max: 100,
                min: 0,
                position: 'left',
                alignTicks: true,
                axisLine: {
                    show: true,
                },
                axisLabel: {
                    formatter: '{value}',
                },
            },
        ],
        series: [{
            type: 'line',
            data: [
                [moment(moment().format('YYYY-MM-DD 00:00:00')).valueOf(), null],
                [moment(moment().format('YYYY-MM-DD 23:59:59')).valueOf(), null],
            ]
        }]
    });
    // 用来判定是否是初始化、是否时报错
    const emptyOrError = useRef({
        empty: true,
        error: true
    })
    const [loading, setLoading] = useState(false);
    const [historyRender, setHistoryRender] = useState(true);
    const [historyParams, setHistoryParams] = useState({});
    const [columns, setColumns] = useState([
        {
            title: '时间',
            dataIndex: 'pt',
            align: 'center',
            width: 100,
            fixed: 'left',
        },
    ]);
    const [dataSource, setDataSource] = useState([]);
    const [options, setOptions] = useState({});
    const [dateValue, setDateValue] = useState('today');
    const [picker, setPicker] = useState('day');
    const [time, setTime] = useState({startTime: '', endTime: ''});
    const [dateTime, setDateTime] = useState(moment().format('YYYY-MM-DD HH:mm:ss'));

    // 时间切换筛选
    const onTimeChange = (e) => {
        setDateValue(e.target.value);
    };

    // 自定义时间类型
    const onPickerChange = (value) => {
        setPicker(value);
        let start = moment(dateTime).subtract(2, value).startOf(value).format('YYYY-MM-DD 00:00:00');
        let end = moment(dateTime).endOf(value).format('YYYY-MM-DD 23:59:59');
        setTime({startDate: start, endDate: end});
    };

    // 自定义时间选择
    const onDateChange = (value, dateString) => {
        setDateTime(dateString);
        const start = moment(value).subtract(2, picker).startOf(picker).format('YYYY-MM-DD 00:00:00');
        const end = moment(value).endOf(picker).format('YYYY-MM-DD 23:59:59');
        setTime({startDate: start, endDate: end});
    };

    const exportExcelBtn = (e) => {
        if (!dataSource.length) return false;
        const sheetFilter = columns.map((item) => {
            return item.dataIndex;
        });
        const sheetHeader = columns.map((item) => {
            return item.title;
        });
        const sheetData = dataSource.map((item) => {
            return {
                pt: item.pt,
                value0: String(item.value0),
                value1: String(item.value1),
                value2: String(item.value2),
            };
        });
        ExportExcel({
            name: `${props?.deviceParams?.sensors || ''}指标数据`,
            content: [
                {
                    sheetData: sheetData,
                    sheetName: 'sheet1',
                    sheetFilter: sheetFilter,
                    sheetHeader: sheetHeader,
                    columnWidths: [10, 10, 10, 10],
                },
            ],
        });
    };
    // 生成对应的数据结构
    const returnDataStructure = (dateFrom, dateTo, dateType, dateValue) => {
        //
        let length = new Array(3).fill(false);
        let finalData = [];
        if (dateType === 'day') {
            let days = length.map((item, index) => {
                return moment(dateTo).subtract(index, 'days').format('YYYY-MM-DD')
            });
            let hours = new Array(24).fill(false).map((item, index) => {
                return index < 10 ? `0${index}` : index;
            })
            days.forEach(day => {
                hours.forEach(hour => {
                    finalData.push(`${day} ${hour}`);
                })
            })
        }
        if (dateType === 'month') {
            let months = length.map((item, index) => {
                return moment(dateTo).subtract(index, 'months').format('YYYY-MM')
            });
            let days = new Array(31).fill(false).map((item, index) => {
                return index < 9 ? `0${index + 1}` : index + 1;
            })
            months.forEach(month => {
                days.forEach(day => {
                    finalData.push(`${month} ${day}`);
                })
            })
        }
        if (dateType === 'year') {
            let years = length.map((item, index) => {
                return moment(dateTo).subtract(index, 'years').format('YYYY')
            });
            let months = new Array(12).fill(false).map((item, index) => {
                return index < 9 ? `0${index + 1}` : index + 1;
            })
            years.forEach(year => {
                months.forEach(month => {
                    finalData.push(`${year} ${month}`);
                })
            })
        }
        return finalData.map(item => {
            return {
                time: item,
                value: null,
            }
        });
    };
    const handleDataForEmptyOrError = () => {
        let _data = returnDataStructure(time.startDate, time.endDate, picker, dateValue);
        dataMenthod({nameDate: _data, dName: props?.deviceParams?.sensors ?? ''});
    }
    // 获取历史统计数据
    const getHistoryData = async () => {
        const {deviceCode = '', sensors = '', deviceType = '', statisticType = ''} = historyParams;
        const nameTypeList = [];
        if (!deviceCode || !sensors) return setOptions(null);
        nameTypeList.push({
            name: sensors,
            type: statisticType || 'Sub',
        });
        const params = {
            pageIndex: 1,
            pageSize: 999,
            nameTypeList: nameTypeList,
            accountName: deviceType,
            dateFrom: time.startDate,
            dateTo: time.endDate,
            deviceCode: deviceCode,
            dateType: picker,
        };
        setLoading(true);
        let results = null;
        try {
            results = await getStatisticsInfo(params);
            emptyOrError.current.error = false;
        } catch (err) {
            if (historyParams.sensors) {
                handleDataForEmptyOrError()
            }
            return setLoading(false);
        }
        setLoading(false);
        const list = results?.data?.list || [];
        if (list.length === 0) {
            handleDataForEmptyOrError()
        }
        const dataList = list.length ? list[0] : {};
        const dNameDataList = dataList.dNameDataList ? dataList.dNameDataList : [];
        const data = dNameDataList.length ? dNameDataList[0] : null;
        if (!data) return setOptions(null);
        dataMenthod(data);
    };

    const dataMenthod = (data) => {
        const {nameDate} = data;
        nameDate.forEach(item => {
            if (item.value !== null) emptyOrError.current.empty = false;
        })
        let time0 = '',
            time1 = '',
            time2 = '';
        let data0 = [],
            data1 = [],
            data2 = [];
        let timeName = [];
        switch (dateValue) {
            case 'today':
                time0 = moment(time.endDate).subtract(0, 'day').format('YYYY-MM-DD');
                time1 = moment(time.endDate).subtract(1, 'day').format('YYYY-MM-DD');
                time2 = moment(time.endDate).subtract(2, 'day').format('YYYY-MM-DD');
                timeName = [].concat(dayName);
                nameDate.forEach((item) => {
                    const times = moment(item.time).format('YYYY-MM-DD');
                    const pt = moment(item.time).format('HH时');
                    if (times === time0) data0.push({...item, pt: pt});
                    if (times === time1) data1.push({...item, pt: pt});
                    if (times === time2) data2.push({...item, pt: pt});
                });
                break;
            case 'thisWeek':
                time0 = moment(time.endDate).subtract(0, 'week').format('WW');
                time1 = moment(time.endDate).subtract(1, 'week').format('WW');
                time2 = moment(time.endDate).subtract(2, 'week').format('WW');
                timeName = [].concat(weekName);
                nameDate.forEach((item) => {
                    const times = moment(item.time).format('WW');
                    const pt = getWeek(item.time);
                    if (times === time0) data0.push({...item, pt: pt});
                    if (times === time1) data1.push({...item, pt: pt});
                    if (times === time2) data2.push({...item, pt: pt});
                });
                break;
            case 'thisMonth':
                time0 = moment(time.endDate).subtract(0, 'month').format('YYYY-MM');
                time1 = moment(time.endDate).subtract(1, 'month').format('YYYY-MM');
                time2 = moment(time.endDate).subtract(2, 'month').format('YYYY-MM');
                timeName = [].concat(monthName);
                nameDate.forEach((item) => {
                    const times = moment(item.time).format('YYYY-MM');
                    const pt = moment(item.time).format('DD日');
                    if (times === time0) data0.push({...item, pt: pt});
                    if (times === time1) data1.push({...item, pt: pt});
                    if (times === time2) data2.push({...item, pt: pt});
                });
                break;
            case 'thisYear':
                time0 = moment(time.endDate).subtract(0, 'year').format('YYYY');
                time1 = moment(time.endDate).subtract(1, 'year').format('YYYY');
                time2 = moment(time.endDate).subtract(2, 'year').format('YYYY');
                timeName = [].concat(yearName);
                nameDate.forEach((item) => {
                    const times = moment(item.time).format('YYYY');
                    const pt = moment(item.time).format('MM月');
                    if (times === time0) data0.push({...item, pt: pt});
                    if (times === time1) data1.push({...item, pt: pt});
                    if (times === time2) data2.push({...item, pt: pt});
                });
                break;
            case 'customer':
                const style = picker === 'day' ? 'HH时' : picker === 'month' ? 'DD日' : 'MM月';
                const format = picker === 'day' ? 'YYYY-MM-DD' : picker === 'month' ? 'YYYY-MM' : 'YYYY';
                time0 = moment(time.endDate).subtract(0, picker).format(format);
                time1 = moment(time.endDate).subtract(1, picker).format(format);
                time2 = moment(time.endDate).subtract(2, picker).format(format);
                timeName = [].concat([time0, time1, time2]);
                nameDate.forEach((item) => {
                    const times = moment(item.time).format(format);
                    const pt = moment(item.time).format(style);
                    if (times === time0) data0.push({...item, pt: pt});
                    if (times === time1) data1.push({...item, pt: pt});
                    if (times === time2) data2.push({...item, pt: pt});
                });
                break;
        }
        const dataChart = {
            data: [data0, data1, data2],
            name: timeName,
        };
        const _data = [data0, data1, data2].sort((a, b) => {
            return b.length - a.length;
        })
        const dataTable = _data[0].map((item, index) => {
            return {
                ...item,
                value0: data0[index] ? data0[index]?.value === 0 || data0[index]?.value ? data0[index]?.value : '-' : '',
                value1: data1[index] ? data1[index]?.value === 0 || data1[index]?.value ? data1[index]?.value : '-' : '',
                value2: data2[index] ? data2[index]?.value === 0 || data2[index]?.value ? data2[index]?.value : '-' : '',
            };
        });
        renderChart(dataChart, data);
        renderTable(dataTable, timeName);
    };

    const renderChart = (dataInfo, data) => {
        if (!dataInfo) return setOptions(null);
        const {unit, dName} = data;
        const series = [];
        let xData = [];
        dataInfo.data.forEach((item, index) => {
            const config = !index && dName.indexOf('流量') > -1 ? {areaStyle: {}} : {};
            const style = index ? {lineStyle: {normal: {type: 'dashed'}}} : {};
            const list = {
                name: dataInfo.name[index],
                type: 'line',
                smooth: true,
                ...config,
                ...style,
                data: item.map((arr) => {
                    return {
                        name: arr.pt,
                        value: arr.value,
                    };
                }),
            };
            series.push(list);
            xData = item.map((arr) => {
                return arr.pt;
            });
        });
        let showMinMax = emptyOrError.current.empty && emptyOrError.current.error;
        const option = {
            title: {
                show: false,
                text: '',
            },
            tooltip: {
                trigger: 'axis',
                axisPointer: {
                    type: 'cross',
                },
            },
            grid: {
                containLabel: true,
                left: 20,
                right: 20,
                // top: 20,
                bottom: 10,
            },
            toolbox: {
                show: false,
            },
            legend: {
                left: 'center',
            },
            xAxis: [
                {
                    type: 'category',
                    axisTick: {
                        alignWithLabel: true,
                    },
                    boundaryGap: false,
                    splitLine: {
                        show: true,
                        lineStyle: {
                            type: 'dashed',
                        },
                    },
                    data: xData,
                },
            ],
            yAxis: [
                {
                    type: 'value',
                    name: unit,
                    position: 'left',
                    alignTicks: true,
                    axisLine: {
                        show: true,
                    },
                    axisLabel: {
                        formatter: '{value}',
                    },
                    ...(showMinMax ? {min: 0, max: 100} : {})
                },
            ],
            series: series,
        };
        setOptions(option);
    };

    const renderTable = (dataInfo, timeName) => {
        const dataIndex = ['value0', 'value1', 'value2'];
        const column1 = [
            {
                title: '时间',
                dataIndex: 'pt',
                align: 'center',
                width: 100,
                fixed: 'left',
            },
        ];
        const column2 = timeName.map((item, index) => {
            return {
                title: item,
                dataIndex: dataIndex[index],
                align: 'center',
            };
        });
        const column = column1.concat(column2);
        setColumns(column);
        setDataSource(dataInfo);
    };

    const getWeek = (date) => {
        const weekTime = moment(date).day();
        switch (weekTime) {
            case 1:
                return '周一';
                break;
            case 2:
                return '周二';
                break;
            case 3:
                return '周三';
                break;
            case 4:
                return '周四';
                break;
            case 5:
                return '周五';
                break;
            case 6:
                return '周六';
                break;
            case 0:
                return '周日';
                break;
        }
    };

    const Summary = (currentData) => {
        return (
            <Table.Summary.Row>
                {columns.map((item, index) => {
                    let sum = 0;
                    currentData.reduce((prev, next) => {
                        sum += next[item.dataIndex] === '-' || next[item.dataIndex] === '' ? 0 : next[item.dataIndex];
                    }, 0);
                    return (
                        <Table.Summary.Cell key={item.dataIndex} index={index} align={'center'}>
                            {index === 0 ? '总计' : sum.toFixed(0)}
                        </Table.Summary.Cell>
                    );
                })}
            </Table.Summary.Row>
        );
    };
    useEffect(() => {
        if (props?.deviceParams?.sensors) {
            handleDataForEmptyOrError()
        }
    }, [])
    useEffect(() => {
        setHistoryParams(props.deviceParams || {});
    }, [props.deviceParams]);

    useEffect(() => {
        let start = '',
            end = '';
        switch (dateValue) {
            case 'today':
                start = moment().subtract(2, 'day').format('YYYY-MM-DD 00:00:00');
                end = moment().format('YYYY-MM-DD 23:59:59');
                setPicker('day');
                break;
            case 'thisWeek':
                start = moment().startOf('week').subtract(2, 'week').format('YYYY-MM-DD 00:00:00');
                end = moment().endOf('week').format('YYYY-MM-DD 23:59:59');
                setPicker('month');
                break;
            case 'thisMonth':
                start = moment().startOf('month').subtract(2, 'month').format('YYYY-MM-DD 00:00:00');
                end = moment().endOf('month').format('YYYY-MM-DD 23:59:59');
                setPicker('month');
                break;
            case 'thisYear':
                start = moment().startOf('year').subtract(2, 'year').format('YYYY-MM-DD 00:00:00');
                end = moment().endOf('year').format('YYYY-MM-DD 23:59:59');
                setPicker('year');
                break;
            case 'customer':
                start = moment(dateTime).startOf(picker).subtract(2, picker).format('YYYY-MM-DD 00:00:00');
                end = moment(dateTime).endOf(picker).format('YYYY-MM-DD 23:59:59');
                break;
        }
        setTime({startDate: start, endDate: end});
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [dateValue]);

    useEffect(() => {
        getHistoryData();
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [time, historyParams, picker]);

    return (
        <div className={classNames(prefixCls)}>
            <div className={classNames(`${prefixCls}-box`)}>
                <div className={classNames(`${prefixCls}-header`)}>
                    <div className={classNames(`${prefixCls}-time`)}>
                        <span>时间选择:</span>
                        <Radio.Group value={dateValue} defaultValue={dateList[0].key} onChange={onTimeChange}>
                            {dateList.map((item) => (
                                <Radio.Button key={item.key} value={item.key}>
                                    {item.name}
                                </Radio.Button>
                            ))}
                        </Radio.Group>
                        {dateValue === 'customer' && (
                            <>
                                <Select
                                    defaultValue="day"
                                    value={picker}
                                    options={timeList}
                                    onChange={onPickerChange}
                                    className={classNames(`${prefixCls}-select`)}
                                />
                                <DatePicker onChange={onDateChange} value={moment(dateTime)} picker={picker}
                                            allowClear={false}/>
                            </>
                        )}
                    </div>
                    <Button
                        className={classNames(`${prefixCls}-down-load`)}
                        type="primary"
                        onClick={exportExcelBtn}
                        disabled={!dataSource.length}
                    >
                        <VerticalAlignBottomOutlined/>
                        下载
                    </Button>
                </div>
                <div className={classNames(`${prefixCls}-content`)}>
                    {
                        <>
                            <div className={classNames(`${prefixCls}-chart`)}>
                                {
                                    <BasicChart
                                        ref={chartRef}
                                        option={(!options || !options?.series) ? defaultOptionRef.current : options}
                                        notMerge
                                        style={{width: '100%', height: '100%'}}
                                    />
                                }
                            </div>
                            <div className={classNames(`${prefixCls}-table`)}>
                                <BasicTable
                                    dataSource={dataSource}
                                    columns={columns}
                                    pagination={false}
                                    bordered={true}
                                    onRow={(record, index) => {
                                        return {
                                            onMouseEnter: (event) => {
                                                let seriesIndex = 0;
                                                const dataIndex = ['value0', 'value1', 'value2'];
                                                seriesIndex = dataIndex.findIndex((item) => {
                                                    return record[item] !== '-';
                                                });
                                                chartRef?.current?.getEchartsInstance() &&
                                                chartRef?.current?.getEchartsInstance().dispatchAction({
                                                    type: 'showTip',
                                                    seriesIndex: seriesIndex,
                                                    dataIndex: index,
                                                });
                                            }, // 鼠标移入行
                                            onMouseLeave: (event) => {
                                                chartRef?.current?.getEchartsInstance() &&
                                                chartRef?.current?.getEchartsInstance().dispatchAction({
                                                    type: 'hideTip',
                                                    dataIndex: index,
                                                });
                                            }, // 鼠标移出行
                                        };
                                    }}
                                    scroll={{x: '100%', y: 'calc(100% - 40px)'}}
                                    summary={Summary}
                                />
                            </div>
                        </>
                    }
                </div>
            </div>
            {loading && (
                <div className={classNames(`${prefixCls}-load-box`)}>
                    <LoadBox spinning={loading}/>
                </div>
            )}
        </div>
    );
};

export default StatisticalHistoryView;

const dateList = [
    {
        key: 'today',
        name: '今日',
    },
    // {
    //   key: 'thisWeek',
    //   name: '本周',
    // },
    {
        key: 'thisMonth',
        name: '本月',
    },
    {
        key: 'thisYear',
        name: '今年',
    },
    {
        key: 'customer',
        name: '自定义',
    },
];

const timeList = [
    {
        value: 'day',
        label: '日',
    },
    {
        value: 'month',
        label: '月',
    },
    {
        value: 'year',
        label: '年',
    },
];

const dayName = ['今日', '昨日', '前日'];

const weekName = ['本周', '上周', '上上周'];

const monthName = ['本月', '上月', '上上月'];

const yearName = ['今年', '去年', '前年'];