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 [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).format('YYYY-MM-DD 00:00:00');
    const end = moment(value).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 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);
    } catch (err) {
      return setLoading(false);
    }
    setLoading(false);
    const list = results?.data?.list || [];
    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;
    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 dataTable = data0.map((item, index) => {
      return {
        ...item,
        value0: item?.value === 0 || item?.value ? item?.value : '-',
        value1: data1[index]?.value === 0 || data1[index]?.value ? data1[index]?.value : '-',
        value2: 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;
      });
    });
    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}',
          },
        },
      ],
      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] === '-' ? 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(() => {
    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().startOf(picker).subtract(2, picker).format('YYYY-MM-DD 00:00:00');
        end = moment().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} />
              </>
            )}
          </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`)}>
                {options ? (
                  <BasicChart
                    ref={chartRef}
                    option={options}
                    notMerge
                    style={{ width: '100%', height: '100%' }}
                  />
                ) : (
                  <div className={classNames(`${prefixCls}-empty`)}>
                    <Empty />
                  </div>
                )}
              </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 = ['今年', '去年', '前年'];
