import React, { useState, useEffect } from 'react';
import {
  DatePicker,
  Table,
  Row,
  Col,
  Button,
  Select,
  Input,
  notification,
  message,
  Spin,
  Tooltip,
  Pagination,
} from 'antd';
import { SwapRightOutlined, SyncOutlined, CaretUpFilled, CaretDownFilled } from '@ant-design/icons';
import { Chart, Interval, Line, Axis } from 'bizcharts';
import { post, PUBLISH_SERVICE } from '@/services/index';
import moment from 'moment';
import 'moment/dist/locale/zh-cn';
import locale from 'antd/es/date-picker/locale/zh_CN';
import styles from './index.less';

const { Option } = Select;
const { Search } = Input;
const { RangePicker } = DatePicker;

const ServiceLog = () => {
  const [loading, setLoading] = useState(false); // 源数据
  const [dataTable, setDataTable] = useState([]); // 源数据
  const [visitedCount, setVisitedCount] = useState([]); // 访问量,统计数据
  const [pathCount, setPathCount] = useState([]); // 接口调用次数,统计数据
  const [reponseTime, setReponseTime] = useState([]); // 接口调用时长,统计数据
  const [timeInterval, setTimeInterval] = useState('4'); // 时间间隔,1/2/3/4(每分钟/5分钟/小时/天),默认每小时
  const [startTime, setStartTime] = useState(moment().startOf('month')); // 默认值,当天0点00:00:00
  const [endTime, setEndTime] = useState(
    moment(new Date(), 'YYYY-MM-DD HH:mm:ss'), // 默认值,当前时间
  );
  const [allTime, setAllTime] = useState([
    moment().startOf('month'),
    moment(new Date(), 'YYYY-MM-DD HH:mm:ss'),
  ]);
  const [logType, setLogType] = useState('9999'); // 请求参数,日志类型,默认是正常,0:成功 -1:异常 9999:全部
  const [searchWord, setSearchWord] = useState(''); // 关键字
  const [showSearchStyle, setShowSearchStyle] = useState(false); // 是否显示模糊查询样式
  const [total, setTotal] = useState();
  const [pageSize, setPageSize] = useState(20);
  const [currentPage, setCurrentPage] = useState(1);

  const [show1, setShow1] = useState('block');
  const [show2, setShow2] = useState('none');
  const [keepType, setKeepType] = useState('');
  const [keepOrder, setKeepOrder] = useState('');

  // 计算时间间隔(分钟)
  const start = new Date(allTime[0]).getTime();
  const end = new Date(allTime[1]).getTime();
  const minuteInterval = (end - start) / (60 * 1000); // 相隔多少分钟
  const countInterval = () => {
    if (minuteInterval > 0 && minuteInterval <= 30) {
      setTimeInterval('1');
    } else if (minuteInterval > 30 && minuteInterval <= 120) {
      setTimeInterval('2');
    } else if (minuteInterval > 120 && minuteInterval <= 60 * 24) {
      setTimeInterval('3');
    } else {
      setTimeInterval('4');
    }
  };
  // 计算时间间隔(月份),禁止跨月份查询
  const startMonth = new Date(allTime[0]).getMonth();
  const endMonth = new Date(allTime[1]).getMonth();
  const startYear = new Date(allTime[0]).getYear();
  const endYear = new Date(allTime[1]).getYear();
  if (minuteInterval <= 0) {
    console.log(start);
    console.log(end);
    console.log(allTime[0]);
    console.log(allTime[1]);
    console.log(minuteInterval);
    notification.error({
      message: '时间设置有误',
      description: '起始时间应该早于结束时间',
    });
  } else if ((startMonth !== endMonth && startYear === endYear) || startYear !== endYear) {
    notification.info({
      message: '时间设置提示',
      description: '不允许跨月份查询',
    });
  }

  const columns = [
    {
      title: '接口名称',
      dataIndex: 'Path',
      key: 'Path',
      fixed: 'left',
      width: 300,
      render: item => searchStyle(item),
    },
    {
      dataIndex: 'CallTime',
      key: 'CallTime',
      width: 160,
      title: (
        <div>
          录入时间
          <Tooltip title="点击降序">
            <CaretUpFilled
              style={{
                display: show1,
                color: '#1890ff',
                marginTop: '-13px',
                marginLeft: '60%',
              }}
              onClick={() => shengxu(1)}
            />
          </Tooltip>
          <Tooltip title="点击升序">
            <CaretDownFilled
              style={{
                display: show2,
                color: '#1890ff',
                marginTop: '-13px',
                marginLeft: '60%',
              }}
              onClick={() => jiangxu(1)}
            />
          </Tooltip>
        </div>
      ),
    },
    // {
    //   title: 'IP',
    //   dataIndex: 'DownstreamRequest',
    //   key: 'DownstreamRequest',
    //   width: 120,
    // },
    {
      title: '返回状态',
      dataIndex: 'Result',
      key: 'Result',
      width: 80,
    },
    {
      title: '异常信息',
      dataIndex: 'ErrorMsg',
      key: 'ErrorMsg',
      onCell: () => ({
        style: {
          maxWidth: 300,
          overflow: 'hidden',
          whiteSpace: 'nowrap',
          textOverflow: 'ellipsis',
          cursor: 'pointer',
        },
      }),
      render: record => (
        <Tooltip placement="topLeft" title={record}>
          {record}
        </Tooltip>
      ),
    },
    {
      title: '请求方法',
      dataIndex: 'Method',
      key: 'Method',
      width: 100,
    },
    {
      dataIndex: 'ConsumerTime',
      key: 'ConsumerTime',
      width: 100,
      title: (
        <div>
          耗时/ms
          <Tooltip title="点击降序">
            <CaretUpFilled
              style={{
                display: show1,
                color: '#1890ff',
                marginTop: '-13px',
                marginLeft: '60%',
              }}
              onClick={() => shengxu(2)}
            />
          </Tooltip>
          <Tooltip title="点击升序">
            <CaretDownFilled
              style={{
                display: show2,
                color: '#1890ff',
                marginTop: '-13px',
                marginLeft: '60%',
              }}
              onClick={() => jiangxu(2)}
            />
          </Tooltip>
        </div>
      ),
    },
    {
      title: '返回体大小/byte',
      dataIndex: 'ResponseSize',
      key: 'ResponseSize',
      width: 140,
    },
  ];

  const shengxu = e => {
    setKeepType(e);
    setKeepOrder('desc');
    console.log(e);
    setShow1('none');
    setShow2('block');
    setPageSize(20);
    setCurrentPage(1);
    setLoading(true);
    post(`${PUBLISH_SERVICE}/LogCenter/GetOMSLog`, {
      // 获取日志表数据时PageSize设置为200,其他接口默认值20
      PageIndex: 1,
      PageSize: 20,
      DateFrom: allTime[0].format('YYYY-MM-DD HH:mm:ss'),
      DateTo: allTime[1].format('YYYY-MM-DD HH:mm:ss'),
      IP: '',
      Module: searchWord,
      LogType: +logType,
      Description: '',
      LoginName: '',
      UserName: '',
      StaticsType: +timeInterval,
      sort: e == 1 ? 'callTime' : 'consumerTime',
      order: 'desc',
    })
      .then(res => {
        if (res.code === 0) {
          if (!res.data) {
            setDataTable([]);
          } else {
            const result = res.data.list;
            setTotal(res.data.TotalCount);
            setDataTable(
              result.map((item, index) => {
                item.key = index;
                return item;
              }),
            );
          }
        } else {
          notification.error({
            message: '数据获取失败',
            description: res.msg,
          });
        }
        setLoading(false);
      })
      .catch(err => {
        message.error(err);
        setLoading(false);
      });
  };
  const jiangxu = e => {
    setKeepType(e);
    setKeepOrder('asc');
    setShow2('none');
    setShow1('block');
    setPageSize(20);
    setCurrentPage(1);
    setLoading(true);
    post(`${PUBLISH_SERVICE}/LogCenter/GetOMSLog`, {
      // 获取日志表数据时PageSize设置为200,其他接口默认值20
      PageIndex: 1,
      PageSize: 20,
      DateFrom: allTime[0].format('YYYY-MM-DD HH:mm:ss'),
      DateTo: allTime[1].format('YYYY-MM-DD HH:mm:ss'),
      IP: '',
      Module: searchWord,
      LogType: +logType,
      Description: '',
      LoginName: '',
      UserName: '',
      StaticsType: +timeInterval,
      sort: e == 1 ? 'callTime' : 'consumerTime',
      order: 'asc',
    })
      .then(res => {
        if (res.code === 0) {
          if (!res.data) {
            setDataTable([]);
          } else {
            const result = res.data.list;
            setTotal(res.data.TotalCount);
            setDataTable(
              result.map((item, index) => {
                item.key = index;
                return item;
              }),
            );
          }
        } else {
          notification.error({
            message: '数据获取失败',
            description: res.msg,
          });
        }
        setLoading(false);
      })
      .catch(err => {
        message.error(err);
        setLoading(false);
      });
  };

  // 模糊查询匹配的样式
  const searchStyle = val => {
    let n;
    if (showSearchStyle) {
      n = val.replace(new RegExp(searchWord, 'g'), `<span style='color:red'>${searchWord}</span>`);
    } else {
      n = val;
    }
    return <div dangerouslySetInnerHTML={{ __html: n }} />;
  };
  // 在起止时间任意一个变化后获取数据,且起止时间应该早于结束时间,且不允许跨月查询
  useEffect(() => {
    if (allTime && end - start > 0 && startMonth === endMonth && startYear === endYear) {
      countInterval(); // 根据起止时间计算时间间隔
    }
  }, [allTime]);
  useEffect(() => {
    if (allTime && end - start > 0 && startMonth === endMonth && startYear === endYear) {
      setLoading(true);
      getData('/TrafficStatistics', setVisitedCount); // 访问量统计
    }
  }, [allTime, logType, timeInterval]);
  useEffect(() => {
    if (allTime && end - start > 0 && startMonth === endMonth && startYear === endYear) {
      setLoading(true);
      getData('/TopCountList', setPathCount); // 接口调用频次统计
      getData('/TopConsumeList', setReponseTime); // 接口平均耗时统计
      getData('/GetOMSLog', setDataTable); // 接口调用记录
    }
  }, [allTime, logType]);

  // 封装接口请求,参数url/设置方法set
  const getData = (url, set) => {
    post(`${PUBLISH_SERVICE}/LogCenter${url}`, {
      // 获取日志表数据时PageSize设置为200,其他接口默认值20
      PageIndex: 1,
      PageSize: 20,
      DateFrom: allTime[0].format('YYYY-MM-DD HH:mm:ss'),
      DateTo: allTime[1].format('YYYY-MM-DD HH:mm:ss'),
      IP: '',
      Module: url === '/GetOMSLog' ? searchWord : '',
      LogType: +logType,
      Description: '',
      LoginName: '',
      UserName: '',
      StaticsType: +timeInterval,
    })
      .then(res => {
        if (res.code === 0) {
          if (!res.data) {
            set([]);
          } else {
            const result = url === '/GetOMSLog' ? res.data.list : res.data;
            if (url === '/GetOMSLog') {
              setTotal(res.data.TotalCount);
            }
            set(
              result.map((item, index) => {
                item.key = index;
                if (url === '/TrafficStatistics') {
                  item.StartTime = item.StartTime.replace(' ', '-');
                }
                return item;
              }),
            );
          }
          setKeepType('');
          setKeepOrder('');
          setPageSize(20);
          setCurrentPage(1);
        } else {
          notification.error({
            message: '数据获取失败',
            description: res.msg,
          });
        }
        setLoading(false);
      })
      .catch(err => {
        message.error(err);
        setLoading(false);
      });
  };

  const getData1 = (url, set, page, size) => {
    console.log(keepType);
    console.log(keepOrder);
    let data = {};
    if (keepType) {
      data = {
        PageIndex: page,
        PageSize: size,
        DateFrom: allTime[0].format('YYYY-MM-DD HH:mm:ss'),
        DateTo: allTime[1].format('YYYY-MM-DD HH:mm:ss'),
        IP: '',
        Module: searchWord,
        LogType: +logType,
        Description: '',
        LoginName: '',
        UserName: '',
        StaticsType: +timeInterval,
        sort: keepType == 1 ? 'callTime' : 'consumerTime',
        order: keepOrder,
      };
    } else {
      data = {
        PageIndex: page,
        PageSize: size,
        DateFrom: allTime[0].format('YYYY-MM-DD HH:mm:ss'),
        DateTo: allTime[1].format('YYYY-MM-DD HH:mm:ss'),
        IP: '',
        Module: searchWord,
        LogType: +logType,
        Description: '',
        LoginName: '',
        UserName: '',
        StaticsType: +timeInterval,
      };
    }
    post(`${PUBLISH_SERVICE}/LogCenter${url}`, data)
      .then(res => {
        if (res.code === 0) {
          if (!res.data) {
            set([]);
          } else {
            const result = res.data.list;
            setTotal(res.data.TotalCount);
            set(
              result.map((item, index) => {
                item.key = index;
                return item;
              }),
            );
          }
        } else {
          notification.error({
            message: '数据获取失败',
            description: res.msg,
          });
        }
        setLoading(false);
      })
      .catch(err => {
        message.error(err);
        setLoading(false);
      });
  };

  // DatePicker改变点击确定时
  const changeStartTime = time => {
    console.log(time);
    setStartTime(time);
  };
  const changeEndTime = time => {
    console.log(time);
    setEndTime(time);
  };
  const changeTime = time => {
    console.log(time);
    setAllTime(time);
  };
  // 近1/6/12/24小时,同时设置对应的时间间隔
  const setTime = (time, value) => {
    setTimeInterval(value);
    setStartTime(moment(new Date(new Date().getTime() - time * 60 * 1000), 'YYYY-MM-DD HH:mm:ss'));
    setEndTime(moment(new Date(), 'YYYY-MM-DD HH:mm:ss'));
    setAllTime([
      moment(new Date(new Date().getTime() - time * 60 * 1000), 'YYYY-MM-DD HH:mm:ss'),
      moment(new Date(), 'YYYY-MM-DD HH:mm:ss'),
    ]);
  };
  // 设置返回状态
  const changeStatus = value => {
    setLogType(value);
  };
  // 设置时间间隔
  const selectChange = value => {
    setTimeInterval(value);
  };
  // 获取搜索框的值
  const handleSearch = e => {
    setSearchWord(e.target.value);
  };
  const handleReset = () => {
    setLogType('9999');
    setTimeInterval('4');
    setStartTime(moment().startOf('month'));
    setEndTime(moment(new Date(), 'YYYY-MM-DD HH:mm:ss'));
    setAllTime([moment().startOf('month'), moment(new Date(), 'YYYY-MM-DD HH:mm:ss')]);
    setSearchWord('');
    setShowSearchStyle(false);
  };

  const dayTime = () => {
    let date = new Date();
    return date.getDate() - 1;
  };

  // 监听分页
  const paginationChange = (page, pageSizes) => {
    getData1('/GetOMSLog', setDataTable, page, pageSizes);
    setCurrentPage(page);
    setPageSize(pageSizes);
  };
  return (
    <>
      <div className={styles.serviceLog}>
        <Row className={styles.head}>
          <Col span={24}>
            <span style={{ marginLeft: '27px' }}>时间:</span>
            <RangePicker
              locale={locale}
              showTime
              format="YYYY-MM-DD HH:mm:ss"
              onChange={changeTime}
              value={allTime}
              allowClear={false}
            />
            {/* <DatePicker
              locale={locale}
              showTime
              format="YYYY-MM-DD HH:mm:ss"
              placeholder="起始时间"
              value={startTime}
              onChange={changeStartTime}
              allowClear={false}
            />
            <SwapRightOutlined style={{ verticalAlign: '0.125em' }} />
            <DatePicker
              locale={locale}
              showTime
              format="YYYY-MM-DD HH:mm:ss"
              placeholder="结束时间"
              value={endTime}
              onChange={changeEndTime}
              style={{ marginRight: '10px' }}
              allowClear={false}
            /> */}
            <Button onClick={() => setTime(15, '1')} style={{ marginLeft: '10px' }}>
              近15分钟
            </Button>
            <Button onClick={() => setTime(60, '2')}>近1小时</Button>
            <Button onClick={() => setTime(12 * 60, '3')}>近12小时</Button>
            <Button onClick={() => setTime(24 * 60, '3')}>近1天</Button>
            <Button onClick={() => setTime(24 * 7 * 60, '4')}>近1周</Button>
            <Button onClick={() => setTime(24 * dayTime() * 60, '4')}>本月</Button>
            <br />
            <br />
            <span>返回状态:</span>
            <Select
              defaultValue="全部"
              value={logType}
              onChange={changeStatus}
              className={styles.sel}
            >
              <Option value="9999">全部</Option>
              <Option value="0">正常</Option>
              <Option value="-1">异常</Option>
            </Select>
            <Search
              allowClear
              style={{ width: 250, marginLeft: '20px' }}
              placeholder="请输入接口名称"
              onSearch={() => {
                getData('/GetOMSLog', setDataTable);
                setShowSearchStyle(true);
              }}
              onChange={e => handleSearch(e)}
              enterButton
              value={searchWord}
            />
            {/* <Button
              icon={<SyncOutlined className={styles.icon} />}
              onClick={handleReset}
              style={{
                marginLeft: '25px',
                verticalAlign: 'middle',
                marginTop: '-3px',
              }}
            >
              重置
            </Button> */}
          </Col>
        </Row>
        <Spin spinning={loading} tip="loading">
          <Row style={{ background: 'white' }}>
            <Col span={8} style={{ paddingTop: '8px', paddingLeft: '5px' }}>
              <span style={{ fontSize: '14px', fontWeight: '600' }}>访问量统计</span>
              <span style={{ float: 'right' }}>
                <span>间隔:</span>
                <Select
                  defaultValue="每小时"
                  size="small"
                  value={timeInterval}
                  onChange={selectChange}
                  className={styles.sel}
                >
                  <Option value="1">每分钟</Option>
                  <Option value="2">每5分钟</Option>
                  <Option value="3">每小时</Option>
                  <Option value="4">每天</Option>
                </Select>
              </span>
            </Col>
            <Col span={7} offset={1} style={{ paddingTop: '8px' }}>
              <span style={{ fontSize: '14px', fontWeight: '600' }}>接口调用频次统计</span>
            </Col>
            <Col span={7} offset={1} style={{ paddingTop: '8px' }}>
              <span style={{ fontSize: '14px', fontWeight: '600' }}>接口平均耗时统计</span>
            </Col>
          </Row>
          <Row className={styles.chart}>
            <Col span={8}>
              <Chart
                height={300}
                autoFit
                data={visitedCount}
                interactions={['active-region']}
                padding="auto"
                renderer="svg"
                scale={{
                  Count: { alias: '计数' },
                  StartTime: { alias: '访问开始时间' },
                }}
              >
                <Axis
                  name="StartTime"
                  label=""
                  title={{ offset: 20 }}
                  className={styles.fontColor}
                />
                <Axis name="Count" title />
                <Line shape="smooth" position="StartTime*Count" />
                <Tooltip shared lock />
              </Chart>
            </Col>
            <Col span={7} offset={1}>
              <Chart
                height={300}
                autoFit
                data={pathCount}
                interactions={['active-region']}
                padding="auto"
                renderer="svg"
                scale={{
                  Count: { alias: '计数' },
                  Path: { alias: '接口调用频次' },
                }}
              >
                <Axis name="Path" label="" title={{ offset: 20 }} className={styles.fontColor} />
                <Axis name="Count" title />
                <Interval position="Path*Count" />
                <Tooltip shared lock />
              </Chart>
            </Col>
            <Col span={7} offset={1}>
              <Chart
                height={300}
                autoFit
                data={reponseTime}
                interactions={['active-region']}
                padding="auto"
                renderer="svg"
                scale={{
                  AvgTime: { alias: '响应时长/ms' },
                  Path: { alias: '接口平均响应时长' },
                }}
              >
                <Axis name="Path" label="" title={{ offset: 20 }} />
                <Axis name="AvgTime" title />
                <Interval position="Path*AvgTime" />
                <Tooltip shared lock />
              </Chart>
            </Col>
          </Row>
          <div className={styles.table}>
            <Table
              size="small"
              bordered
              columns={columns}
              dataSource={dataTable}
              scroll={{ x: 'max-content', y: 'calc(100vh - 615px)' }}
              pagination={false}
            />
          </div>
          <Pagination
            style={{ display: 'flex', justifyContent: 'end', padding: '10px' }}
            total={total}
            showTotal={(aa, range) => `第${range[0]}-${range[1]} 条/共 ${total} 条`}
            defaultPageSize={pageSize}
            defaultCurrent={1}
            pageSizeOptions={[10, 20, 40, 100]}
            current={currentPage}
            onChange={paginationChange}
            size="small"
            showQuickJumper
          />
        </Spin>
      </div>
    </>
  );
};
export default ServiceLog;