import React, { useState, useEffect, useContext, useMemo } from 'react';
import PropTypes from 'prop-types';
import Empty from '@wisdom-components/empty';
import classNames from 'classnames';
import { Modal, Button, Tabs, Input, Radio, ConfigProvider, message } from 'antd';
import BasicTable from '@wisdom-components/basictable';
import {
  getMonitorConfig,
  getSensorType,
  getDeviceRealInfo,
  getPointAddressEntry,
  getPointAddress,
} from './apis';
import './index.less';

const { TabPane } = Tabs;

const defaultColumns = [
  {
    title: '序号',
    dataIndex: 'index',
    width: 60,
  },
  {
    title: '指标名称',
    dataIndex: 'name',
    width: 150,
  },
  {
    title: '最新指标',
    dataIndex: 'value',
    render: (text) => <a>{text}</a>,
  },
  {
    title: '单位',
    dataIndex: 'unit',
  },
  {
    title: '指标类型',
    dataIndex: 'type',
  },
  {
    title: '数据描述',
    dataIndex: 'desc',
  },
  {
    title: '更新时间',
    dataIndex: 'time',
  },
];

const RealTimeInfo = (props) => {
  const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
  const prefixCls = getPrefixCls('realtime-info');

  const { deviceParams, infoData, user, placeholder, defaultTargetValue, modalTitle, buttonText } =
    props;

  const [isModalVisible, setIsModalVisible] = useState(false);
  const [targetValue, setTargetValue] = useState(defaultTargetValue); // 重点/全部
  const [searchValue, setSearchValue] = useState(''); // 搜索框内容
  const [tabKey, setTabKey] = useState('');
  const [guid, setGuid] = useState('');
  const [deviceConf, setDeviceConf] = useState([]); // 设备配置
  const [deviceInfo, setDeviceInfo] = useState({}); // 设备实时数据
  const [sensorType, setSensorType] = useState([]); // sensorType
  const [pointAddress, setPointAddress] = useState([]); // pointAddress

  const tabData = useMemo(() => {
    const data = deviceInfo;
    let tData = [];
    if (!data) return tData;
    tData.push({
      key: data.code,
      title: data.name,
      guid: data.guid,
      versionID: data.versionID,
      deviceType: data.aName,
    });
    if (data.child && data.child.length) {
      data.child.forEach((child) => {
        tData.push({
          key: child.code,
          title: data.name + child.name,
          guid: child.guid,
          versionID: child.versionID,
          deviceType: child.aName,
        });
      });
    }
    return tData;
  }, [deviceInfo]);

  // 过滤重点指标(带搜索)
  const filterEmphasis = (dataSource, searchValue) => {
    const cur = tabData.filter((item) => item.key === tabKey);
    const conf =
      cur.length > 0 ? deviceConf.filter((item) => item.deviceType === cur[0].deviceType) : [];
    const dPoints = conf.length > 0 && conf[0].dPoints ? conf[0].dPoints.split(',') : [];
    const data = dataSource.filter((item) =>
      searchValue
        ? dPoints.indexOf(searchValue) > -1 && dPoints.includes(item.name)
        : dPoints.includes(item.name),
    );
    return data;
  };

  // 过滤普通指标(带搜索)
  const filterSearch = (dataSource, searchValue) => {
    return !searchValue ? dataSource : dataSource.filter((item) => item.name.includes(searchValue));
  };

  const getData = () => {
    let deviceType = '';
    if (infoData) {
      let devices = [infoData.aName];
      infoData.child?.forEach(function (val) {
        let k = devices.find(function (a) {
          return a == val.aName;
        });
        if (!k) {
          devices.push(val.aName);
        }
      });
      deviceType = devices.join(',');
    } else {
      deviceType =
        deviceParams.length > 0
          ? Array.from(new Set(deviceParams.map((item) => item.deviceType))).join(',')
          : '二供泵房,二供机组';
    }

    const configReq = getMonitorConfig({
      params: {
        user,
        showAll: true,
        deviceType: deviceType,
      },
    });
    const sensorReq = getSensorType();
    const realDataReq = getDeviceRealInfo({
      data: {
        pageIndex: 1,
        pageSize: 200,
        param: deviceParams,
        useID: user,
      },
    });
    Promise.all([configReq, sensorReq, realDataReq])
      .then((results) => {
        if (results.some((item) => item.code !== 0)) message.error('获取数据失败');
        const [configRes, sensorRes, realDataRes] = results;
        setSensorType(sensorRes.data);
        setDeviceConf(configRes.data);
        setDeviceInfo(realDataRes.data.list[0]);
        setTabKey(realDataRes?.data?.list?.[0]?.code);
      })
      .catch((err) => {
        message.error('获取数据失败');
      });
  };

  useEffect(() => {
    if (!isModalVisible || !deviceParams || !deviceParams.length) return;
    getData();
  }, [deviceParams, user, isModalVisible]);

  const GetPointAddressEntry = () => {
    const cur = tabData.filter((item) => item.key === tabKey);
    !!cur.length &&
      getPointAddressEntry({
        params: {
          versionId: cur[0].versionID,
        },
      }).then((res) => {
        if (res.code === 0 && res.data.length) {
          setPointAddress(res.data);
        }
      });
  };

  useEffect(() => {
    if (!tabKey || !tabData || !tabData.length) return;
    GetPointAddressEntry();
    const g = tabData.filter((item) => item.key === tabKey);
    setGuid(g?.[0]?.guid);
  }, [tabKey]);

  const formatData = (data = [], sensorType = [], deviceInfo = {}) => {
    if (!deviceInfo) return [];
    let time = deviceInfo.pt;
    if (time) time = time.slice(5, 19).replace('-', '/');
    let newData = data.map((item, index) => {
      return {
        id: item.id,
        key: item.id,
        index: index + 1,
        name: item.name,
        value: 0,
        unit: '--',
        type: '--',
        time: time,
        desc: item.valDesc || '--',
        ...item,
      };
    });
    newData.forEach((item) => {
      let curData1 = sensorType.filter((child) => child.id == item.sensorTypeID);
      let curData2 = deviceInfo.dataList.filter((child) => child.paid == item.id);
      if (curData1.length) {
        item.unit = curData1[0].unit || '--';
        item.type = curData1[0].name || '--';
      }
      if (curData2.length) {
        item.value = curData2[0].pv || '--';
      }
    });
    return newData;
  };

  const tableData = useMemo(() => {
    // 过滤数据
    let points = [];
    if (targetValue === 'emphasis') {
      points = filterEmphasis(pointAddress, searchValue);
    } else {
      points = filterSearch(pointAddress, searchValue);
    }

    const deviceData =
      deviceInfo.code === tabKey
        ? deviceInfo
        : deviceInfo?.child?.find((item) => item.code === tabKey);
    const newData = formatData(points, sensorType, deviceData);
    return newData;
  }, [targetValue, searchValue, pointAddress, deviceInfo]);

  const columns = useMemo(() => {
    return defaultColumns;
  }, []);

  const showModal = () => {
    setIsModalVisible(true);
  };

  const handleOk = () => {
    setIsModalVisible(false);
  };

  const handleCancel = () => {
    setIsModalVisible(false);
  };

  const changeSearch = (e) => {
    e.target && e.target.value === '' && setSearchValue('');
  };

  const onSearch = (value) => {
    // 前端搜索
    setSearchValue(value);
  };

  const onTabChange = (key) => {
    setTabKey(key);
  };

  const onRadioChange = (e) => {
    setTargetValue(e.target.value);
  };

  const renderTitle = () => {
    return (
      <div className={classNames(`${prefixCls}-modal-title`)}>
        <Tabs
          tabBarExtraContent={{ left: <h3 style={{ fontWeight: 'bold' }}>{modalTitle}</h3> }}
          activeKey={tabKey}
          onChange={onTabChange}
          centered
        >
          {tabData.map((item) => (
            <TabPane tab={item.title} key={item.key} />
          ))}
        </Tabs>
      </div>
    );
  };

  return (
    <div className={classNames(prefixCls)}>
      <Button type="link" onClick={showModal}>
        {buttonText}
      </Button>
      <Modal
        className={classNames(`${prefixCls}-modal`)}
        width={915}
        title={renderTitle()}
        footer={null}
        visible={isModalVisible}
        onOk={handleOk}
        onCancel={handleCancel}
      >
        <div className={classNames(`${prefixCls}-modal-content`)}>
          <div className={classNames(`${prefixCls}-search-wrap`)}>
            <div className={classNames(`${prefixCls}-search`)}>
              <div className={classNames(`${prefixCls}-label`)}>搜索:</div>
              <Input.Search placeholder={placeholder} onSearch={onSearch} onChange={changeSearch} />
            </div>
            <div className={classNames(`${prefixCls}-target`)}>
              <div className={classNames(`${prefixCls}-label`)}>指标:</div>
              <Radio.Group onChange={onRadioChange} defaultValue={targetValue}>
                <Radio.Button value="emphasis">重点指标</Radio.Button>
                <Radio.Button value="all">全部</Radio.Button>
              </Radio.Group>
            </div>
          </div>
          <div className={classNames(`${prefixCls}-code-wrap`)}>
            <div>采集编码:{guid || '--'}</div>
            <div>更新时间:{(tableData.length && tableData[0].time) || '--'}</div>
          </div>
          <div className={classNames(`${prefixCls}-modal-table`)}>
            <BasicTable
              bordered
              columns={columns}
              locale={{ emptyText: <Empty /> }}
              pagination={false}
              dataSource={tableData}
              {...props}
            />
          </div>
        </div>
      </Modal>
    </div>
  );
};

RealTimeInfo.defaultProps = {
  buttonText: '查看更多',
  modalTitle: '实时指标监控',
  placeholder: '输入指标名称等',
  defaultTargetValue: 'emphasis',
  user: null,
  deviceParams: [],
  deviceRealInfoParams: {},
  deviceConfService: () => {},
  pointAddressEntryService: () => {},
  sensorTypeService: () => {},
  deviceRealInfoService: () => {},
};

RealTimeInfo.propTypes = {
  buttonText: PropTypes.string,
  modalTitle: PropTypes.string,
  placeholder: PropTypes.string,
  defaultTargetValue: PropTypes.string,
  user: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  deviceParams: PropTypes.array,
  deviceRealInfoParams: PropTypes.object,
  deviceConfService: PropTypes.func,
  pointAddressEntryService: PropTypes.func,
  sensorTypeService: PropTypes.func,
  deviceRealInfoService: PropTypes.func,
};

export default RealTimeInfo;