/*
 * Copyright 2022 Nightingale Team
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
/* eslint-disable react/sort-comp */
/* eslint-disable prefer-template */
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import _ from 'lodash';
import { Dropdown, Menu, Select, Tag } from 'antd';
import { DownOutlined, PlusCircleOutlined } from '@ant-design/icons';
import Comparison from './Comparison';
import * as config from '../config';
import { fetchAggrGroups } from '../api';
import { Config } from 'react-sortable-hoc';

const { Option } = Select;

/**
 * graph 内置配置条组件
 */

interface Props {
  data: any;
  onChange: Function;
}
interface State {
  curAggrFunc: string;
  calcFunc: string;
  curAggrGroups: string[];
  aggrGroups: string[];
  curComparisonValue: any;
}
class GraphConfigInner extends Component<Props, State> {
  static defaultProps = {};

  constructor(props) {
    super(props);
    this.state = {
      curAggrFunc: 'avg',
      calcFunc: '',
      curAggrGroups: ['ident'],
      curComparisonValue: {},
      aggrGroups: [],
    };
  }

  componentDidMount() {
    this.fetchAggrGroups();
  }

  componentDidUpdate(prevProps) {
    const oldHosts = (prevProps.data.selectedHosts || []).map((h) => h.ident);
    const newHosts = (this.props.data.selectedHosts || []).map((h) => h.ident);
    const isHostsChanged = !_.isEqual(oldHosts, newHosts);
    if (isHostsChanged) {
      this.fetchAggrGroups();
    }
  }

  fetchAggrGroups() {
    const { metric, selectedHosts } = this.props.data;
    const idents = selectedHosts.map((host) => host.ident);
    fetchAggrGroups({
      start: Math.round(Number(this.props.data.start) / 1000),
      end: Math.round(Number(this.props.data.end) / 1000),
      match: [`${metric}{ident=~"${idents.join('|')}"}`],
    }).then((res) => {
      this.setState({
        aggrGroups: res.data,
      });
    });
  }

  handleAggrFuncChange = (val) => {
    const { data, onChange } = this.props;
    this.setState({
      curAggrFunc: val,
    });
    onChange('update', data.id, {
      changeType: 'aggrFuncChange',
      comparison: this.state.curComparisonValue.comparison,
      relativeTimeComparison: this.state.curComparisonValue.relativeTimeComparison,
      comparisonOptions: this.state.curComparisonValue.comparisonOptions,
      aggrFunc: val,
      calcFunc: this.state.calcFunc,
      aggrGroups: this.state.curAggrGroups,
    });
  };

  handleCalcFuncChange = (val) => {
    const { data, onChange } = this.props;
    this.setState({
      calcFunc: val,
    });
    onChange('update', data.id, {
      comparison: this.state.curComparisonValue.comparison,
      relativeTimeComparison: this.state.curComparisonValue.relativeTimeComparison,
      comparisonOptions: this.state.curComparisonValue.comparisonOptions,
      aggrFunc: this.state.curAggrFunc,
      calcFunc: val,
      aggrGroups: this.state.curAggrGroups,
    });
  };

  handleComparisonChange = (values) => {
    const { data, onChange } = this.props;
    this.setState({
      curComparisonValue: values,
    });
    onChange('update', data.id, {
      comparison: values.comparison,
      relativeTimeComparison: values.relativeTimeComparison,
      comparisonOptions: values.comparisonOptions,
      aggrFunc: this.state.curAggrFunc,
      calcFunc: this.state.calcFunc,
      aggrGroups: this.state.curAggrGroups,
    });
  };

  handleAggrGroupsChange = (values) => {
    const { data, onChange } = this.props;
    this.setState({
      curAggrGroups: values,
    });
    onChange('update', data.id, {
      comparison: this.state.curComparisonValue.comparison,
      relativeTimeComparison: this.state.curComparisonValue.relativeTimeComparison,
      comparisonOptions: this.state.curComparisonValue.comparisonOptions,
      aggrFunc: this.state.curAggrFunc,
      calcFunc: this.state.calcFunc,
      aggrGroups: values,
    });
  };

  render() {
    const { data, onChange } = this.props;
    const { now, start, end, comparison } = data;
    const handleAggrFuncClick = (e) => {
      this.handleAggrFuncChange(e.key);
    };
    const aggrFuncMenu = (
      <Menu onClick={handleAggrFuncClick} selectedKeys={[this.state.curAggrFunc]}>
        <Menu.Item key='sum'>sum</Menu.Item>
        <Menu.Item key='avg'>avg</Menu.Item>
        <Menu.Item key='max'>max</Menu.Item>
        <Menu.Item key='min'>min</Menu.Item>
      </Menu>
    );

    const calcFuncMenu = (
      <Menu onClick={(e) => this.handleCalcFuncChange(e.key === 'clear' ? '' : e.key)} selectedKeys={[this.state.calcFunc]}>
        <Menu.Item key='rate_1m'>rate_1m</Menu.Item>
        <Menu.Item key='rate_5m'>rate_5m</Menu.Item>
        <Menu.Item key='increase_1m'>increase_1m</Menu.Item>
        <Menu.Item key='increase_5m'>increase_5m</Menu.Item>
        <Menu.Divider></Menu.Divider>
        <Menu.Item key='clear'>clear</Menu.Item>
      </Menu>
    );

    const handleAggrGroupsClick = (ag) => {
      const index = this.state.curAggrGroups.findIndex((cag) => cag === ag.key);
      let newCurAggrGroups;
      if (index === -1) {
        newCurAggrGroups = [...this.state.curAggrGroups, ag.key];
        this.setState({
          curAggrGroups: newCurAggrGroups,
        });
      } else {
        let curComparisonCopy = [...this.state.curAggrGroups];
        curComparisonCopy.splice(index, 1);
        newCurAggrGroups = curComparisonCopy;
        this.setState({
          curAggrGroups: curComparisonCopy,
        });
      }
      this.handleAggrGroupsChange(newCurAggrGroups);
    };

    const aggrGroupsMenu = (
      <Menu onClick={handleAggrGroupsClick} selectedKeys={this.state.curAggrGroups}>
        {this.state.aggrGroups
          .filter((n) => n !== '__name__')
          .map((ag) => (
            <Menu.Item key={ag}>{ag}</Menu.Item>
          ))}
      </Menu>
    );

    const handleDeleteAggrGroupClick = (ag) => {
      let newCurAggrGroups = [...this.state.curAggrGroups];
      let idx = newCurAggrGroups.findIndex((cag) => cag === ag);
      if (idx >= 0) newCurAggrGroups.splice(idx, 1);
      this.handleAggrGroupsChange(newCurAggrGroups);
    };

    return (
      <div className='graph-config-inner'>
        <div className='graph-config-inner-item'>
          计算函数 :
          <Dropdown overlay={calcFuncMenu}>
            <a className='ant-dropdown-link' onClick={(e) => e.preventDefault()}>
              {this.state.calcFunc} <DownOutlined />
            </a>
          </Dropdown>
        </div>
        <div className='graph-config-inner-item'>
          环比:
          <Comparison
            comparison={comparison}
            relativeTimeComparison={data.relativeTimeComparison}
            comparisonOptions={data.comparisonOptions}
            graphConfig={data}
            onChange={this.handleComparisonChange}
          />
          <input
            style={{
              position: 'fixed',
              left: -10000,
            }}
            id={`hiddenInput${data.id}`}
          />
        </div>
        <div className='graph-config-inner-item'>
          聚合函数 :
          <Dropdown overlay={aggrFuncMenu}>
            <a className='ant-dropdown-link' onClick={(e) => e.preventDefault()}>
              {this.state.curAggrFunc} <DownOutlined />
            </a>
          </Dropdown>
        </div>
        {this.state.curAggrFunc ? (
          <div className='graph-config-inner-item'>
            <span>聚合维度 :</span>
            {/* <Select
                mode="multiple"
                size="small"
                style={{ minWidth: 60 }}
                dropdownMatchSelectWidth={false}
                value={this.state.curAggrGroups}
                onChange={this.handleAggrGroupsChange}
              >
                {this.state.aggrGroups.map(ag => <Option key={ag} value={ag}>{ag}</Option>)}
              </Select> */}
            {this.state.curAggrGroups.map((ag) => (
              <Tag
                key={ag}
                closable
                onClose={(e) => {
                  handleDeleteAggrGroupClick(ag);
                }}
              >
                {ag}
              </Tag>
            ))}
            <Dropdown overlay={aggrGroupsMenu} overlayStyle={{ maxHeight: 400, overflow: 'auto' }}>
              <a className='ant-dropdown-link' onClick={(e) => e.preventDefault()}>
                <PlusCircleOutlined />
              </a>
            </Dropdown>
          </div>
        ) : null}
      </div>
    );
  }
}

export default GraphConfigInner;