/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */


import React, { PureComponent } from 'react';
import { connect } from 'dva';
import { Row, Col, Card, Icon, Radio, Avatar, Select, Input } from 'antd';
import { ChartCard } from '../../components/Charts';
import { AppTopology } from '../../components/Topology';
import { Panel } from '../../components/Page';
import ApplicationLitePanel from '../../components/ApplicationLitePanel';
import DescriptionList from '../../components/DescriptionList';
import { redirect } from '../../utils/utils';

const { Description } = DescriptionList;
const { Option } = Select;

const colResponsiveProps = {
  xs: 24,
  sm: 24,
  md: 24,
  lg: 12,
  xl: 12,
  style: { marginTop: 8 },
};

const layouts = [
  {
    name: 'dagre',
    icon: 'img/icon/dagre.png',
    rankDir: 'LR',
    minLen: 4,
    animate: true,
  },
  {
    name: 'concentric',
    icon: 'img/icon/concentric.png',
    minNodeSpacing: 10,
    animate: true,
  },
  {
    name: 'cose-bilkent',
    icon: 'img/icon/cose.png',
    idealEdgeLength: 200,
    edgeElasticity: 0.1,
    randomize: false,
  },
];

const layoutButtonStyle = { height: '90%', verticalAlign: 'middle', paddingBottom: 2 };

@connect(state => ({
  topology: state.topology,
  duration: state.global.duration,
  globalVariables: state.global.globalVariables,
}))
export default class Topology extends PureComponent {
  static defaultProps = {
    graphHeight: 600,
  };

  findValue = (id, values) => {
    const v = values.find(_ => _.id === id);
    if (v) {
      return v.value;
    }
    return null;
  }

  handleChange = (variables) => {
    const { dispatch } = this.props;
    dispatch({
      type: 'topology/fetchData',
      payload: { variables },
    });
  }

  handleLayoutChange = ({ target: { value } }) => {
    const { dispatch } = this.props;
    dispatch({
      type: 'topology/saveData',
      payload: { layout: value },
    });
  }

  handleLoadMetrics = (ids, idsS, idsC) => {
    const { dispatch, globalVariables: { duration } } = this.props;
    dispatch({
      type: 'topology/fetchMetrics',
      payload: { variables: {
        duration,
        ids,
        idsS,
        idsC,
      }},
    });
  }

  handleSelectedApplication = (appInfo) => {
    const { dispatch, topology: { data: { metrics: { sla, nodeCpm, nodeLatency } } } } = this.props;
    if (appInfo) {
      dispatch({
        type: 'topology/saveData',
        payload: { appInfo: { ...appInfo,
          sla: this.findValue(appInfo.id, sla.values),
          cpm: this.findValue(appInfo.id, nodeCpm.values),
          avgResponseTime: this.findValue(appInfo.id, nodeLatency.values),
        } },
      });
    } else {
      dispatch({
        type: 'topology/saveData',
        payload: { appInfo: null },
      });
    }
  }

  handleChangeLatencyStyle = (e) => {
    const { value } = e.target;
    const latencyRange = value.split(',').map(_ => parseInt(_.trim(), 10));
    const { dispatch } = this.props;
    dispatch({
      type: 'topology/setLatencyStyleRange',
      payload: { latencyRange },
    });
  }

  handleFilterApplication = (aa) => {
    const { dispatch } = this.props;
    dispatch({
      type: 'topology/filterApplication',
      payload: { aa },
    });
  }

  renderActions = () => {
    const { data: { appInfo } } = this.props.topology;
    return [
      <Icon type="appstore" onClick={() => redirect(this.props.history, '/monitor/service', { key: appInfo.id, label: appInfo.name })} />,
      <Icon
        type="exception"
        onClick={() => redirect(this.props.history, '/trace',
        { values: {
            serviceId: appInfo.id,
            duration: { ...this.props.duration, input: this.props.globalVariables.duration },
          },
          labels: { applicationId: appInfo.name },
        })}
      />,
      appInfo.isAlarm ? <Icon type="bell" onClick={() => redirect(this.props.history, '/monitor/alarm')} /> : null,
    ];
  }

  renderNodeType = (topologData) => {
    const typeMap = new Map();
    topologData.nodes.forEach((_) => {
      if (typeMap.has(_.type)) {
        typeMap.set(_.type, typeMap.get(_.type) + 1);
      } else {
        typeMap.set(_.type, 1);
      }
    });
    const result = [];
    typeMap.forEach((v, k) => result.push(<Description term={k}>{v}</Description>));
    return result;
  }

  render() {
    const { data, variables: { appRegExps, appFilters = [], latencyRange } } = this.props.topology;
    const { metrics, layout = 0 } = data;
    const { getGlobalTopology: topologData } = data;
    return (
      <Panel globalVariables={this.props.globalVariables} onChange={this.handleChange}>
        <Row gutter={8}>
          <Col {...{ ...colResponsiveProps, xl: 18, lg: 16 }}>
            <ChartCard
              title="Topology Map"
              avatar={<Avatar icon="fork" style={{ color: '#1890ff', backgroundColor: '#ffffff' }} />}
              action={(
                <Radio.Group value={layout} onChange={this.handleLayoutChange} size="normal">
                  {layouts.map((_, i) => (
                    <Radio.Button value={i} key={_.name}>
                      <img src={_.icon} alt={_.name} style={layoutButtonStyle} />
                    </Radio.Button>))}
                </Radio.Group>
              )}
            >
              {topologData.nodes.length > 0 ? (
                <AppTopology
                  height={this.props.graphHeight}
                  elements={topologData}
                  metrics={metrics}
                  onSelectedApplication={this.handleSelectedApplication}
                  onLoadMetircs={this.handleLoadMetrics}
                  layout={layouts[layout]}
                  latencyRange={latencyRange}
                  appRegExps={appRegExps}
                />
              ) : null}
            </ChartCard>
          </Col>
          <Col {...{ ...colResponsiveProps, xl: 6, lg: 8 }}>
            {data.appInfo ? (
              <Card
                title={data.appInfo.name}
                bodyStyle={{ height: 568 }}
                actions={this.renderActions()}
              >
                <ApplicationLitePanel appInfo={data.appInfo} />
              </Card>
            )
            : (
              <Card title="Overview" style={{ height: 672 }}>
                <Select
                  mode="tags"
                  style={{ width: '100%', marginBottom: 20 }}
                  placeholder="Filter application"
                  onChange={this.handleFilterApplication}
                  tokenSeparators={[',']}
                  value={appFilters}
                >
                  {data.getGlobalTopology.nodes.filter(_ => _.sla)
                    .map(_ => <Option key={_.name}>{_.name}</Option>)}
                </Select>
                <h4>Latency coloring thresholds</h4>
                <Input style={{ width: '100%', marginBottom: 20 }} onChange={this.handleChangeLatencyStyle} value={latencyRange.join(',')} />
                <h4>Overview</h4>
                <DescriptionList layout="vertical">
                  <Description term="Total">{topologData.nodes.length}</Description>
                  {this.renderNodeType(topologData)}
                </DescriptionList>
              </Card>
            )}
          </Col>
        </Row>
      </Panel>
    );
  }
}
