import React, { useContext, useEffect, useRef, useState, useMemo } from 'react';
import { ConfigProvider, Modal, Radio, Select, InputNumber, Spin, message } from 'antd';
import classNames from 'classnames';
import { BasicChart } from '@wisdom-components/basicchart';
import { getStatisticsInfo } from '../apis';
import { getOptions, experiTypeOptions, compareOptions, valTakeOptions } from './utils';
import moment from 'moment';
import _ from 'lodash';
import './index.less';

const FORMAT = 'yyyy-MM-DD HH:mm:ss';
const PredictionCurve = (props) => {
  const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
  const prefixCls = getPrefixCls('empirical-curve');

  const {
    width,
    deviceCode,
    sensors,
    deviceType,
    getContainer,
    title,
    visible,
    onClose,
    valTakeType = '按偏移量',
    compareType = '同比',
    experiType = 'h',
    highLimit = 2,
    higherLimit = 0,
  } = props;
  const [loading, setLoading] = useState(false);
  const [experiVal, setExperiVal] = useState(experiType); // 经验值类型
  const [compareVal, setCompareVal] = useState(compareType); // 对比目标
  const [valTake, setValTake] = useState(valTakeType); // 取值方式
  const [realData, setRealData] = useState([]); // 原始数据
  const [compareData, setCompareData] = useState([]); // 对比数据
  const [highLimitVal, setHighLimitVal] = useState(highLimit); // 高限值
  const [higherLimitVal, setHigherLimitVal] = useState(higherLimit); // 高限值
  const [sensorData, setSensorData] = useState({ sensorName: sensors }); // 指标配置数据
  const chartRef = useRef(null);
  const dayStart = moment().format('yyyy-MM-DD 00:00:00');
  const dayEnd = moment().format('yyyy-MM-DD 23:59:59');
  const monthStart = moment().startOf('month').format('yyyy-MM-DD 00:00:00');
  const monthEnd = moment().endOf('month').format('yyyy-MM-DD 23:59:59');

  // 当前时间
  const [dateFrom1, dateTo1] = useMemo(() => {
    if (experiVal === 'h') {
      return [dayStart, dayEnd];
    } else {
      return [monthStart, monthEnd];
    }
  }, [experiVal]);

  // 对比时间
  const [dateFrom2, dateTo2] = useMemo(() => {
    // 小时-同比:今日0点-24点对应昨日0点-24点
    if (experiVal === 'h' && compareVal === '同比') {
      return [
        moment(dayStart).subtract(1, 'days').format(FORMAT),
        moment(dayEnd).subtract(1, 'days').format(FORMAT),
      ];
    }
    // 小时-环比:今日0点-24点对比当前时间往前推1小时
    if (experiVal === 'h' && compareVal === '环比') {
      return [
        moment(dayStart).subtract(1, 'hours').format(FORMAT),
        moment(dayEnd).subtract(1, 'hours').format(FORMAT),
      ];
    }

    // 日-同比:本月1日-31日对比上个月1日-31日
    if (experiVal === 'day' && compareVal === '同比') {
      return [
        moment(monthStart).subtract(1, 'months').format(FORMAT),
        moment(monthEnd).subtract(1, 'months').format(FORMAT),
      ];
    }

    // 日-环比:本月1日-31日对比当前时间往前推一天
    if (experiVal === 'day' && compareVal === '环比') {
      return [
        moment(monthStart).subtract(1, 'days').format(FORMAT),
        moment(monthEnd).subtract(1, 'days').format(FORMAT),
      ];
    }

    return ['', ''];
  }, [experiVal, compareVal]);

  //chart options
  const options = useMemo(() => {
    const _options = getOptions(
      realData,
      compareData,
      experiVal,
      compareVal,
      highLimitVal,
      higherLimitVal,
      valTake,
      sensorData,
    );
    return _options;
  }, [realData, compareData, highLimitVal, higherLimitVal, , valTake, sensorData]);

  // 确定
  const onOk = () => {
    onClose();
  };

  // 取消
  const onCancel = () => {
    onClose();
  };

  // 获取统计服务数据
  const getStatisticsData = async () => {
    try {
      const params1 = {
        pageIndex: 1,
        pageSize: 1,
        q_DeviceReports: [
          {
            accountName: deviceType,
            nameTypeList: [
              {
                name: sensors,
                type: sensors.includes('累计') ? 'Sub' : 'Avg',
              },
            ],
            dateType: experiVal,
            dateFrom: dateFrom1,
            dateTo: dateTo1,
            deviceCode,
          },
        ],
        dateType: experiVal,
      };
      const params2 = _.cloneDeep(params1);
      params2.q_DeviceReports[0].dateFrom = dateFrom2;
      params2.q_DeviceReports[0].dateTo = dateTo2;
      setLoading(true);
      const req1 = getStatisticsInfo(params1);
      const req2 = getStatisticsInfo(params2);
      const results = await Promise.all([req1, req2]);
      setLoading(false);
      const [res1, res2] = results;
      if (res1.code === 0 && res2.code === 0) {
        let _realData = res1?.data?.list?.[0]?.dNameDataList?.[0]?.nameDate ?? [];
        let _compareData = res2?.data?.list?.[0]?.dNameDataList?.[0]?.nameDate ?? [];
        _realData = _realData.map((item) => ({
          ...item,
          value: typeof item.value === 'number' ? item.value.toFixed(2) * 1 : 0,
        }));
        _compareData = _compareData.map((item) => ({
          ...item,
          value: typeof item.value === 'number' ? item.value.toFixed(2) * 1 : 0,
        }));
        setRealData(_realData);
        setCompareData(_compareData);
        setSensorData({
          ...sensorData,
          unit: res1?.data?.list?.[0]?.dNameDataList?.[0]?.unit ?? '',
        });
      } else {
        setRealData([]);
        setCompareData([]);
      }
    } catch (error) {
      setLoading(false);
      console.log(error);
    }
  };

  useEffect(() => {
    getStatisticsData();
  }, [experiVal, dateFrom1, dateTo1, dateFrom2, dateTo2]);

  return (
    <>
      <Modal
        title={title}
        centered
        okText={'确定'}
        width={width || '1200px'}
        cancelText={'取消'}
        open={visible}
        onOk={onOk}
        onCancel={onCancel}
        wrapClassName={classNames(`${prefixCls}`)}
        getContainer={getContainer || document.body}
      >
        <Spin spinning={loading}>
          <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={experiTypeOptions}
                    optionType={'button'}
                    value={experiVal}
                    onChange={(e) => {
                      setExperiVal(e.target.value);
                    }}
                  />
                </span>
                <span className={classNames(`${prefixCls}-header-item`)}>
                  对比目标:
                  <Radio.Group
                    options={compareOptions}
                    optionType={'button'}
                    value={compareVal}
                    onChange={(e) => {
                      setCompareVal(e.target.value);
                    }}
                  />
                </span>
                <span className={classNames(`${prefixCls}-header-item`)}>
                  取值方式:
                  <Select options={valTakeOptions} value={valTake} onChange={setValTake} />
                </span>
                <span className={classNames(`${prefixCls}-header-item`)}>
                  偏差范围: 高限
                  <InputNumber
                    addonAfter={valTake === '按偏移率' ? '%' : ''}
                    style={{
                      marginLeft: '2px',
                      marginRight: '8px',
                      width: valTake === '按偏移率' ? '110px' : '90px',
                    }}
                    value={highLimitVal}
                    onChange={(val) => {
                      if (val && higherLimitVal && val > higherLimitVal)
                        return message.info('高限值不能大于或等于高高限值!');
                      setHighLimitVal(val);
                    }}
                    min={0}
                  />
                  高高限
                  <InputNumber
                    addonAfter={valTake === '按偏移率' ? '%' : ''}
                    style={{ marginLeft: '2px', width: valTake === '按偏移率' ? '110px' : '90px' }}
                    value={higherLimitVal}
                    onChange={(val) => {
                      if (val && highLimitVal && val <= highLimitVal)
                        return message.info('高高限值不能小于或等于高限值!');
                      setHigherLimitVal(val);
                    }}
                    min={0}
                  />
                </span>
              </div>
            </div>
            <div className={classNames(`${prefixCls}-content`)}>
              <BasicChart
                ref={chartRef}
                option={options}
                notMerge
                style={{ width: '100%', height: '100%' }}
              />
            </div>
          </div>
        </Spin>
      </Modal>
    </>
  );
};

export default PredictionCurve;