// 核心库
import React, { Component } from 'react'
// 组件库
import ReactEcharts from "echarts-for-react"
import DataLoading from '../common/DataLoading'
import { Search, IFComponent } from '@woowalker/feui'
// 样式
import classNames from 'classnames'
import styles from './chart.css'

class SanChart extends Component {
  getSanChartContentHeight (Nodes, Levels) {
    const minHeight = 12 // value 为 0 时，只有文字的高度，line-height: 12
    const nodeGap = 12 // 节点之间的距离
    const topAndBottomSpace = 50 + 20 // top 和 bottom 的距离
    const minUsage = Math.min(...(Nodes.map(node => node.value).filter(item => item > 0)))

    const totalHeights = Levels.map(({ nodes = [] }) => {
      return nodes.reduce((sum, node, index) => {
        return sum + (node.value ? node.value / minUsage * minHeight : minHeight) + (index < nodes.length - 1 ? nodeGap : 0)
      }, 0)
    })
    const maxHeight = Math.max(...totalHeights) + topAndBottomSpace

    return maxHeight > 0 ? (maxHeight > 1600 ? 1600 : maxHeight) : 480
  }

  getSanChartOption = (option, length) => {
    const { title, Links, Nodes } = option || {}
    // const colors = ['#25c677', '#ffba03', '#1aaf8d', '#6e85f5', '#6e9ade']
    const sourceData = Nodes || []
    for (let d = 0; d < sourceData.length; d++) {
      sourceData[d].itemStyle = {
        color: sourceData[d].LossRate > 50 ? '#f9517d' : sourceData[d].LossRate > 30 ? '#ffc45e' : '#25c4ac'
      }
      sourceData[d].tooltip = {
        formatter: function (params) {
          const { name, value, data } = params
          const { views } = data
          if (views && Array.isArray(views) && views.length) {
            return views.map(item => `${item.name}：${item.value}${item.unit}`).join('<br />')
          }
          return `${name}：${value}`
        }
      }
    }
    // 计算桑基图节点宽度
    const sankeyWrapEle = document.getElementById('chart-base-component-sankey')
    const sankeyWrapEleWidth = sankeyWrapEle ? sankeyWrapEle.clientWidth : 0
    let nodeWidth = length && sankeyWrapEleWidth ? sankeyWrapEleWidth / (length * 2 - 1) : 130
    nodeWidth < 130 && (nodeWidth = 130)
    return {
      title: {
        text: title,
        left: 38,
        top: 8,
        textStyle: {
          fontSize: 14
        }
      },
      tooltip: {
        trigger: 'item'
      },
      toolbox: {
        show: true,
        top: 8,
        right: 38,
        feature: {
          restore: { show: true },
          saveAsImage: { show: true }
        }
      },
      series: [
        {
          type: 'sankey',
          data: sourceData,
          links: Links || [],
          left: 18.0,
          top: 50.0,
          right: 18.0,
          bottom: 20.0,
          nodeWidth,
          nodeGap: 12,
          nodeAlign: 'left',
          focusNodeAdjacency: true,
          label: {
            align: 'center',
            verticalAlign: 'middle',
            position: ['50%', '50%'],
            offset: [0, 1],
            fontSize: 12,
            lineHeight: 12,
            distance: 0
          },
          lineStyle: {
            color: 'source',
            curveness: 0.5
          },
          itemStyle: {
            borderWidth: 0,
            borderColor: 'transparent'
          }
        }
      ]
    }
  }

  render () {
    const { config, option, getChartData } = this.props
    const {
      code,
      formCode
    } = config

    const Levels = option ? (option.Levels || []) : []
    const Nodes = option ? (option.Nodes || []) : []
    const chartOption = this.getSanChartOption(option, Levels.length)
    const contentHeight = this.getSanChartContentHeight(Nodes, Levels)
    const nodeWidth = chartOption.series[0].nodeWidth
    return (
      <>
        <IFComponent IF={!!formCode}>
          <Search
            formCode={formCode}
            onSearch={getChartData}
            code={code}
          />
        </IFComponent>
        <IFComponent
          IF={!!option}
          ELSE={<DataLoading style={{ height: 480 }} />}
        >
          <div id='chart-base-component-sankey' className={classNames(styles.sanChart_wrap, { [styles.sanChart_wrapLevel]: Levels.length })}>
            <div className={classNames(styles.sanChart_header, { [styles.sanChart_headerLevel]: Levels.length })}>
              {
                Levels.map((level, index) => {
                  const { views = [] } = level
                  return (
                    <>
                      <div className={styles.sanChart_headerTitle} style={{ width: nodeWidth }}>
                        <IFComponent IF={!!level.name}>
                          <span>{level.name}{views.length ? <br /> : ''}</span>
                        </IFComponent>
                        {
                          views.map((v, i) => {
                            return <span>{v.name}：{v.value}{v.unit}{i === views.length - 1 ? '' : <br />}</span>
                          })
                        }
                      </div>
                      <IFComponent IF={index < Levels.length - 1}>
                        <div className={styles.sanChart_headerAttach} />
                      </IFComponent>
                    </>
                  )
                })
              }
            </div>
            <div className={classNames(styles.sanChart_zone, { [styles.sanChart_zoneLevel]: Levels.length })}>
              <ReactEcharts
                notMerge
                lazyUpdate
                option={chartOption}
                style={{ height: contentHeight }}
              />
            </div>
          </div>
        </IFComponent>
      </>
    )
  }
}

export default SanChart
