import React, { useContext, useEffect, useRef, useState } from 'react';
import { ConfigProvider, Modal, Radio, Slider, InputNumber, Input, Button } from 'antd';
import classNames from 'classnames';
import moment from 'moment';
import { BasicChart } from '@wisdom-components/basicchart';
import { getHistoryInfo } from '../apis';
import { std } from 'mathjs';
import skmeans from 'skmeans';
import LoadBox from '@wisdom-components/loadbox';
import { outlierArr, timeArr, chartArr, average } from './utils';
import './index.less';

const LimitCurve = (props) => {
  const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
  const prefixCls = getPrefixCls('limit-curve');
  const { width, deviceCode, sensors, deviceType, getContainer, title } = props;
  const [spinning,setSpinning] = useState(true);
  const [open, setOpen] = useState(false);
  const [timeType, setTimeType] = useState('近7天'); // 时间
  const [outlier, setOutlier] = useState(3); // 过滤异常
  const [curve, setCurve] = useState('特征曲线'); // 曲线类型
  const [sensitive, setSensitive] = useState(10); // 敏感度
  const [sensorData, setSensorData] = useState([]); // 所有数据
  const [chartData, setChartData] = useState([]); // 图表数据
  const [timeCycle, setTimeCycle] = useState(60);
  const [options, setOptions] = useState({});

  const chartRef = useRef(null);

  // 确定
  const onOk = () => {
    props.onOk && props.onOk(123);
  };

  // 取消
  const onCancel = () => {
    setOpen(false);
    props.onCancel && props.onCancel();
  };

  // 获取历史数据
  const getSensorsData = async () => {
    setSpinning(true);
    const params = {
      isDilute: true,
      zoom: '',
      unit: '',
      dateFrom: moment().subtract(8, 'day').format('YYYY-MM-DD 00:00:00'),
      dateTo: moment().subtract(1, 'day').format('YYYY-MM-DD 23:59:59'),
      acrossTables: [{ deviceCode: deviceCode, sensors: sensors, deviceType: deviceType }],
      isBoxPlots: true,
    };
    const results = await getHistoryInfo(params);
    setSpinning(false);
    const historyData = results?.data?.[0] || {};

    setSensorData(() => {
      return historyData;
    });
  };

  // 图表数据处理
  const chartDataHandle = (data) => {
    const times = moment().subtract(1, 'day').format('YYYY-MM-DD');
    const chart = data.map((item) => {
      return {
        ...item,
        time: moment(item.pt).format(times + ' HH:mm:ss'),
      };
    });
    return chart;
  };

  // 聚集方法
  const clusteredMothod = () => {};

  // 渲染图表
  const renderChart = (_chartData) => {
    const chartData = _chartData.map((item) => {
      return [new Date(item.time).getTime(), item.pv];
    });
    const clustered = skmeans(chartData, 24);
    const { centroids = [] } = clustered;
    const _centroids = centroids.sort((a, b) => {
      return a[0] - b[0];
    });
    console.log(_centroids);
    const option = {
      xAxis: {
        type: 'time',
        axisTick: {
          alignWithLabel: true,
        },
        boundaryGap: false,
        splitLine: {
          show: true,
          lineStyle: {
            type: 'dashed',
          },
        },
      },
      yAxis: {
        type: 'value',
        name: 'm',
        position: 'left',
        alignTicks: true,
        axisLine: {
          show: true,
        },
        axisLabel: {
          formatter: '{value}',
        },
      },
      series: [
        {
          type: 'scatter',
          name: sensors,
          sampling: 'average',
          large: true,
          symbolSize: 5,
          data: _chartData.map((item) => {
            return [new Date(item.time).getTime(), item.pv];
          }),
        },
        {
          type: 'line',
          name: sensors,
          sampling: 'average',
          large: true,
          data: _centroids.map((item) => {
            return [Math.floor(item[0]), item[1]];
          }),
        },
      ],
    };
    setOptions(option);
  };

  useEffect(() => {
    open && getSensorsData();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [open]);

  useEffect(() => {
    const { dataModel = [] } = sensorData;
    if (!dataModel.length) return setChartData([]);
    const count = Math.floor((24 * 60) / timeCycle);
    const times = moment().subtract(1, 'day').format('YYYY-MM-DD');
    const _dataModel = dataModel.map((item) => {
      return {
        ...item,
        time: moment(item.pt).format(times + ' HH:mm:ss'),
      };
    });
    const _chartData = [];
    const _clustered = [];
    for (let i = 0; i < count; i++) {
      const data = _dataModel.filter((item) => {
        const time = new Date(item.time).getTime();
        const min = new Date(moment(times + ' 00:00:00').add(i * timeCycle, 'minute')).getTime();
        const max = new Date(
          moment(times + ' 00:00:00').add((i + 1) * timeCycle, 'minute'),
        ).getTime();
        return time && time >= min && max >= time;
      });
      const clusteredArr = [];
      const dataArr = [];
      const pvArr = data.map((item) => {
        return item.pv;
      });
      const stdVal = pvArr.length ? std(pvArr) : 0;
      const medianVal = pvArr.length ? average(pvArr) : 0;
      const range = {
        min: medianVal - outlier * stdVal,
        max: medianVal + outlier * stdVal,
      };
      data.forEach((item) => {
        if (item.pv >= range.min && item.pv <= range.max) dataArr.push(item);
        clusteredArr.push([new Date(item.time).getTime(), item.pv]);
      });
      const clustered = clusteredArr.length ? skmeans(clusteredArr, 1) : {};
      const { centroids = [] } = clustered;
      _chartData.push(...dataArr);
      _clustered.push(...centroids);
    }
    renderChart(_chartData, _clustered);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [sensorData, timeType, outlier]);

  useEffect(() => {
    setOpen(props.open);
  }, [props.open]);

  return (
    <>
      <Modal
        title={`${sensors || ''}近7天历史数据`}
        centered
        okText={'确定'}
        width={width || '1200px'}
        cancelText={'取消'}
        open={open}
        onOk={onOk}
        onCancel={onCancel}
        wrapClassName={classNames(`${prefixCls}`)}
        getContainer={getContainer || document.body}
        destroyOnClose={true}
      >
        <div className={classNames(`${prefixCls}-box`)}>
          <div className={classNames(`${prefixCls}-header`)}>
            <div className={classNames(`${prefixCls}-header-list`)}>
              <span className={classNames(`${prefixCls}-header-item`)}>
                曲线选择：
                <Radio.Group
                  options={chartArr}
                  optionType={'button'}
                  value={curve}
                  onChange={(e) => {
                    setCurve(e.target.value);
                  }}
                />
              </span>
              <span className={classNames(`${prefixCls}-header-item`)}>
                取值方式：
                <Radio.Group
                  options={timeArr}
                  optionType={'button'}
                  value={timeType}
                  onChange={(e) => {
                    setTimeType(e.target.value);
                  }}
                />
              </span>
              <span className={classNames(`${prefixCls}-header-item`)}>
                异常过滤：
                <Radio.Group
                  options={outlierArr}
                  optionType={'button'}
                  value={outlier}
                  onChange={(e) => {
                    setOutlier(e.target.value);
                  }}
                />
              </span>
              <span className={classNames(`${prefixCls}-header-item`)}>
                浮动范围：
                <Slider
                  min={0}
                  max={100}
                  style={{ width: '100px' }}
                  onChange={(value) => {
                    setSensitive(value);
                  }}
                  value={typeof sensitive === 'number' ? sensitive : 0}
                />
                <InputNumber
                  min={1}
                  max={100}
                  style={{
                    margin: '0 16px',
                    width: '100px',
                  }}
                  addonAfter="%"
                  value={sensitive}
                  onChange={(value) => {
                    setSensitive(value);
                  }}
                />
              </span>
            </div>
            <div className={classNames(`${prefixCls}-header-list`)}>
              <span className={classNames(`${prefixCls}-header-item`)}>
                取值限制：
                <div className={classNames(`${prefixCls}-header-value`)}>
                  <Input
                    style={{
                      width: '150px',
                    }}
                    addonBefore="低低限"
                    disabled
                  />
                </div>
                <div className={classNames(`${prefixCls}-header-value`)}>
                  <Input
                    style={{
                      width: '150px',
                    }}
                    addonBefore="低限"
                    disabled
                  />
                </div>
                <div className={classNames(`${prefixCls}-header-value`)}>
                  <Input
                    style={{
                      width: '150px',
                    }}
                    addonBefore="高限"
                    disabled
                  />
                </div>
                <div className={classNames(`${prefixCls}-header-value`)}>
                  <Input
                    style={{
                      width: '150px',
                    }}
                    addonBefore="高高限"
                    disabled
                  />
                </div>
              </span>
              <span className={classNames(`${prefixCls}-header-item`)}>
                <Button type="primary">确定</Button>
              </span>
            </div>
          </div>
          <div className={classNames(`${prefixCls}-content`)}>
            <BasicChart
              ref={chartRef}
              option={options}
              notMerge
              style={{ width: '100%', height: '100%' }}
            />
          </div>
          {spinning && <div className={classNames(`${prefixCls}-load`)}><LoadBox spinning={spinning}/></div>}
        </div>
      </Modal>
    </>
  );
};

export default LimitCurve;
