// 核心库
import React, { Component } from 'react'
import { connect } from 'dva'
// 组件库
import { Tree, Icon, Tabs, Input, message } from 'antd'
import { Scrollbars } from 'react-custom-scrollbars'
import { PictureThumb } from '@woowalker/feui'
import ListPage from '../../components/Table/ListPage'
import Edit from '../../components/Edit/Edit'
import CombinationPage from '../../components/Combination/CombinationPage'
import FormPage from '../../components/FormPage'
// 工具库
import { cloneDeep, isEqual } from 'lodash'
import { getDataFieldValue, permissionUtils, getCustomParams, flatTreeData } from '../../utils/common'
// 样式
import classNames from 'classnames'
import styles from '../Component.css'
import customTabStyles from '../../components/Combination/combinationPage.css'

class VPage extends Component {
  constructor (props) {
    super(props)
    this.state = {
      activeKey: '',
      // 是否多选
      multiCheck: props.treeConfig.multiCheck,
      multiCheckCount: props.treeConfig.multiCheckCount,
      // 多选选中的节点
      selectedKeys: this.getDefaultSelectedKeys(props),
      // 拍平后的树数据
      flatedTreeData: [],
      searchTreeData: [],
      // 是否收起左侧树
      collapse: false
    }
  }

  componentDidMount () {
    const { treeData } = this.props
    this.checkFlatTreeData(treeData)
  }

  UNSAFE_componentWillReceiveProps (nextProps) {
    if (!isEqual(nextProps.treeData, this.props.treeData)) {
      this.checkFlatTreeData(nextProps.treeData)
    }
  }

  getThumbData = () => {
    const { treePicFilter } = this.props

    const thumbCodes = []
    const thumbConfigs = []
    if (Array.isArray(treePicFilter) && treePicFilter.length) {
      treePicFilter.forEach(({ Nav_PicFilterDetail = [], Nav_Picture }) => {
        thumbCodes.push(Nav_Picture.CODE)
        thumbConfigs.push({
          target: Nav_Picture.CODE,
          rules: Nav_PicFilterDetail.map(npd => ({
            field: npd.FIELD_TYPE === 1 ? `Node.${npd.NAME}` : npd.NAME,
            operate: Number(npd.OPERATE),
            value: typeof npd.VALUE === 'string' ? npd.VALUE.toLowerCase() : npd.VALUE
          }))
        })
      })
    }
    return { thumbCodes, thumbConfigs }
  }

  getDefaultSelectedKeys = (props) => {
    const { multiCheck, multiCheckCount } = props.treeConfig
    const defaultSelectedKeys = []
    if (props.treeData && Array.isArray(props.treeData)) {
      props.treeData.forEach(({ node = { id: '' } }) => {
        node.id && defaultSelectedKeys.push(node.id)
      })
    }
    return multiCheck ? (multiCheckCount ? defaultSelectedKeys.slice(0, multiCheckCount) : defaultSelectedKeys) : [defaultSelectedKeys[0]]
  }

  getDefaultExpandedKeys = () => {
    const { treeData, treeConfig } = this.props
    const { expandLevel } = treeConfig
    if (expandLevel) {
      const keys = []
      function checkTreeDataLevel (data) {
        data.forEach(item => {
          if (item.level < expandLevel) {
            keys.push(item.node.id)
            if (Array.isArray(item.children) && item.children.length) {
              checkTreeDataLevel(item.children)
            }
          }
        })
      }
      checkTreeDataLevel(treeData)
      return keys
    }
    return []
  }

  checkShowBtn = (btn, nodeData) => {
    let isShow = !btn.btn_condition
    if (btn.btn_condition) {
      // 菜单参数
      const { currActivatedMenu } = this.props.app || {}
      const menuFormParameter = currActivatedMenu?.MENU_FORM_PARAMS
      // 按钮配置条件
      const conditionsOr = btn.btn_condition.split('|')
      const conditionsAnd = btn.btn_condition.split('&')
      if (conditionsOr.length === 1 && conditionsAnd.length === 1) {
        // 只配置了一个条件
        const fields = btn.btn_condition.split(',')
        const val = getDataFieldValue(nodeData, fields[0].toLowerCase())
        // 条件直接命中菜单参数，则直接显示
        if (btn.btn_condition === menuFormParameter) {
          isShow = true
        }
        // 1 等于
        else if (parseInt(fields[1], 10) === 1) {
          if (String(val) === String(fields[2].toLowerCase())) {
            isShow = true
          }
        }
        // 2 不等于
        else if (parseInt(fields[1], 10) === 2) {
          if (String(val) !== String(fields[2].toLowerCase())) {
            isShow = true
          }
        }
      } else if (conditionsOr.length > 1) {
        // 或条件
        for (let conditionOr of conditionsOr) {
          const fields = conditionOr.split(',')
          const val = getDataFieldValue(nodeData, fields[0].toLowerCase())
          // 条件直接命中菜单参数，则直接显示
          if (conditionOr === menuFormParameter) {
            isShow = true
            break
          }
          // 1 等于
          else if (parseInt(fields[1], 10) === 1) {
            if (String(val) === String(fields[2].toLowerCase())) {
              isShow = true
              break
            }
          }
          // 2 不等于
          else if (parseInt(fields[1], 10) === 2) {
            if (String(val) !== String(fields[2].toLowerCase())) {
              isShow = true
              break
            }
          }
        }
      } else if (conditionsAnd.length > 1) {
        // 与条件
        const showResults = []
        for (let conditionAnd of conditionsAnd) {
          const fields = conditionAnd.split(',')
          const val = getDataFieldValue(nodeData, fields[0].toLowerCase())
          // 条件直接命中菜单参数，则直接显示
          if (conditionAnd === menuFormParameter) {
            showResults.push(true)
          }
          // 1 等于
          else if (parseInt(fields[1], 10) === 1) {
            if (String(val) === String(fields[2].toLowerCase())) {
              showResults.push(true)
            }
          }
          // 2 不等于
          else if (parseInt(fields[1], 10) === 2) {
            if (String(val) !== String(fields[2].toLowerCase())) {
              showResults.push(true)
            }
          }
        }
        isShow = showResults.length === conditionsAnd.length
      }
    }
    return isShow
  }

  checkMultiShowBtn = (btn) => {
    const { currActivatedMenu } = this.props.app || {}
    const menuFormParameter = currActivatedMenu?.MENU_FORM_PARAMS

    let isShow = !btn.btn_condition || !menuFormParameter
    if (btn.btn_condition && menuFormParameter) {
      const conditionsOr = btn.btn_condition.split('|')
      const conditionsAnd = btn.btn_condition.split('&')
      if (conditionsOr.length === 1 && conditionsAnd.length === 1) {
        // 只配置了一个条件
        if (btn.btn_condition === menuFormParameter) {
          isShow = true
        }
      } else if (conditionsOr.length > 1) {
        // 或条件
        for (let conditionOr of conditionsOr) {
          if (conditionOr === menuFormParameter) {
            isShow = true
            break
          }
        }
      } else if (conditionsAnd.length > 1) {
        // 与条件
        const showResults = []
        for (let conditionAnd of conditionsAnd) {
          if (conditionAnd === menuFormParameter) {
            showResults.push(true)
          }
        }
        isShow = showResults.length === conditionsAnd.length
      }
    }

    return isShow
  }

  checkRenderBtn = (nodeData, treeConfig) => {
    const { btns = [] } = treeConfig
    const btnsTmp = []
    btns.forEach(btn => {
      if (!btn.isRule || permissionUtils(this.props.login).checkBtn(treeConfig.formId, btn.pId || btn.id)) {
        // 如果配置了树多选，那么直接显示所配置的所有页面
        if (treeConfig.multiCheck ? this.checkMultiShowBtn(btn) : this.checkShowBtn(btn, nodeData)) {
          btn.btnType === 3 && btn.isSameLevel && (btn.btnType = -1) // 新增同级
          btnsTmp.push(btn)
        }
      }
    })
    return btnsTmp
  }

  checkFlatTreeData = (treeData) => {
    // 拍平树数据
    const flatedTreeData = []
    flatTreeData(treeData, flatedTreeData)
    this.setState({
      flatedTreeData: cloneDeep(flatedTreeData)
    }, () => {
      const { flatedTreeData, selectedKeys } = this.state
      const allKeys = flatedTreeData.map(({ node }) => node.id)
      const validKeys = selectedKeys.filter(item => allKeys.indexOf(item) !== -1)
      this.handleTreeNodesSelect(validKeys.length ? validKeys : this.getDefaultSelectedKeys(this.props))
    })
  }

  checkFlatTreeNodes = (treeData, treeConfig, selectedKeys) => {
    const selectedNodes = this.state.flatedTreeData.filter(item => selectedKeys.indexOf(item.node.id) !== -1)
    treeData.forEach(item => {
      const showBtns = this.checkRenderBtn(item, treeConfig)

      item.btns = showBtns.map(btnConfig => {
        // false 以按钮形式展示 true 以页面形式展示
        let typePage = btnConfig.btnType === 5 || btnConfig.btnType === 12 || btnConfig.btnType === 14 || btnConfig.btnType === 0
        // component 的赋值逻辑请参考 TreeBaseComponent -> Hindex -> getRenderBtn （取的是 modal 里面的表单）
        const { getRenderBtn, onSave } = this.props
        let component = getRenderBtn({ record: item.node, btnConfig })
        // 表单编辑
        if (btnConfig.btnType === 5) {
          const params = {
            id: item.node.id,
            parentId: item.node.id,
            formCode: treeConfig.formCode,
            data: {
              record: item.node
            },
            onSave: (params) => {
              onSave instanceof Function && onSave(params)
            }
          }
          component = <Edit {...params} />
        }
        // 列表查看
        else if (btnConfig.btnType === 12) {
          const params = {
            formCode: btnConfig.formCode,
            formParam: this.props.formParam,
            data: {
              // 当前选中的节点
              selectedNodes,
              // 传递给页面选中的节点参数
              TreeSelected: selectedKeys,
              TreeSelectId: btnConfig.customParams,
              // 页面操作取消树节点选中
              setTreeNodeUnCheck: this.handleTreeNodesUnCheck,
              rules: [
                {
                  field: 'TreeSelected',
                  operator: 1,
                  value: selectedKeys,
                  isCustom: true
                }
              ]
            },
            isQuery: true
          }
          if (btnConfig.customParams) {
            params.data.rules.push({
              field: btnConfig.customParams,
              operator: 1,
              value: item.node.id
            })
          }
          component = <ListPage {...params} />
        }
        // 组合表单
        else if (btnConfig.btnType === 14) {
          const params = {
            formCode: btnConfig.formCode,
            formParam: this.props.formParam,
            data: {
              // 当前选中的节点
              selectedNodes,
              // 传递给页面选中的节点参数
              TreeSelected: selectedKeys,
              // 页面操作取消树节点选中
              setTreeNodeUnCheck: this.handleTreeNodesUnCheck,
              rules: [
                {
                  field: btnConfig.customParams,
                  operator: 1,
                  value: item.node.id,
                  isCustom: true
                }
              ]
            }
          }
          component = <CombinationPage {...params} />
        }
        // 自定义弹窗
        else if (btnConfig.btnType === 0) {
          const record = item.node
          const custParams = getCustomParams(btnConfig.customParams)
          const params = {
            id: record.id,
            parentId: record.id,
            formCode: btnConfig.formCode,
            formParam: this.props.formParam,
            data: {
              ...record,
              ...custParams,
              customParams: btnConfig.customParams,
              // 当前选中的节点
              selectedNodes,
              // 传递给页面选中的节点参数
              TreeSelected: selectedKeys,
              // 页面操作取消树节点选中
              setTreeNodeUnCheck: this.handleTreeNodesUnCheck
            }
          }
          component = <FormPage {...params} />
        }
        return {
          typePage,
          component,
          btnConfig
        }
      })
    })
  }

  renderTreeNodes = (treeData, thumbData) => {
    return treeData.map(item => {
      const { children, node } = item
      const { name, is_exist_alarm, child_exist_alarm, appliance_id, nav_appliance } = node

      const alert = `${name}${is_exist_alarm ? '(节点异常)' : child_exist_alarm ? '(存在子节点异常)' : (appliance_id != null && nav_appliance?.is_report == false) ? '(器具未采集数据)' : ''}`
      const color = is_exist_alarm ? 'red' : child_exist_alarm ? 'orange' : (appliance_id != null && nav_appliance?.is_report == false) ? 'rgba(170, 170, 170)' : 'inhert'
      const title = (
        <span title={alert}>
          <span style={{ color }}>{name}</span>
          {
            is_exist_alarm || child_exist_alarm || (appliance_id != null && nav_appliance?.is_report == false)
              ? (
                <Icon
                  type={is_exist_alarm || child_exist_alarm ? 'alert' : 'disconnect'}
                  style={{ color: is_exist_alarm ? 'red' : child_exist_alarm ? 'orange' : 'rgba(170, 170, 170)', marginLeft: 2 }}
                />
              )
              : ''
          }
        </span>
      )
      const style = { width: 24, height: 24, position: 'relative', top: '-1px' }
      if (children) {
        return (
          <Tree.TreeNode
            title={title}
            key={node.id}
            icon={
              <PictureThumb
                thumbCodes={thumbData.thumbCodes}
                thumbConfigs={thumbData.thumbConfigs}
                nodeData={item}
                defaultThumb={require('../../assets/file.png')}
                style={style}
              />
            }
          >
            {this.renderTreeNodes(children, thumbData)}
          </Tree.TreeNode>
        )
      }
      return (
        <Tree.TreeNode
          title={title}
          key={node.id}
          icon={
            <PictureThumb
              thumbCodes={thumbData.thumbCodes}
              thumbConfigs={thumbData.thumbConfigs}
              defaultThumb={require('../../assets/file.png')}
              nodeData={item}
              style={style}
            />
          }
        />
      )
    })
  }

  handleTreeNodesSelect = (selectedKeys) => {
    const { treeConfig } = this.props
    const { flatedTreeData, activeKey } = this.state
    // 获取选中节点所配置的按钮页面，并直接附在 flatedTreeData 数据之上
    this.checkFlatTreeNodes(flatedTreeData, treeConfig, selectedKeys)
    // 查找被激活 tab 的 key 值
    const findNode = flatedTreeData.find(item => item.node.id === selectedKeys[0])
    const pageBtns = findNode && findNode.btns ? findNode.btns.filter(btn => btn.typePage) : []
    const currActived = pageBtns.find(item => item.btnConfig.id === activeKey)
    this.setState({
      selectedKeys,
      activeKey: !currActived ? (pageBtns.length > 1 ? pageBtns[0].btnConfig.id : '') : activeKey
    })
  }

  handleTreeNodesCheck = ({ checked: selectedKeys }) => {
    const { multiCheckCount } = this.state
    if (multiCheckCount && selectedKeys.length > multiCheckCount) {
      message.error(`最多可选${multiCheckCount}个节点`)
      return
    }
    this.handleTreeNodesSelect(selectedKeys)
  }

  handleTreeNodesUnCheck = (applianceId) => {
    const { flatedTreeData, selectedKeys } = this.state
    const find = flatedTreeData.find(item => item.node?.appliance_id === applianceId)
    if (find) {
      const copyKeys = cloneDeep(selectedKeys)
      const findIndex = copyKeys.findIndex(item => item === find.node?.id)
      findIndex !== -1 && copyKeys.splice(findIndex, 1)
      this.handleTreeNodesCheck({ checked: copyKeys })
    }
  }

  renderTabBar = (pageBtns) => {
    const { activeKey } = this.state
    return (
      <div className={customTabStyles.tabBar__wrap}>
        {
          pageBtns.map(item => {
            return (
              <div
                key={`${item.btnConfig.id}--customTabBar`}
                onClick={() => this.setState({ activeKey: item.btnConfig.id })}
                className={classNames(customTabStyles.tabBar__tab, { [customTabStyles.activated]: item.btnConfig.id === activeKey })}>
                {item.btnConfig.label}
              </div>
            )
          })
        }
      </div>
    )
  }

  handleSearch = (evt) => {
    const { value } = evt.target
    const searchTreeData = this.state.flatedTreeData.filter(({ node = {} }) => (node.name || '').indexOf(value) !== -1)
    this.setState({ searchTreeData: value ? searchTreeData : [] })
  }

  render () {
    const { treeData, treeConfig } = this.props
    const thumbData = this.getThumbData()
    const defaultExpandedKeys = this.getDefaultExpandedKeys()
    const expandProps = defaultExpandedKeys.length ? { defaultExpandedKeys } : { defaultExpandAll: true }

    const { activeKey, multiCheck, selectedKeys, flatedTreeData, searchTreeData, collapse } = this.state
    // 多选时，所有节点都会展示全部配置的页面，单选时，就一个 selectedKeys[0]，所以直接取 selectedKeys[0] 来获取配置的页面
    const targetNodes = flatedTreeData.find(item => item.node.id === selectedKeys[0]) || { node: {} }
    const toolBtns = targetNodes.btns ? targetNodes.btns.filter(btn => !btn.typePage) : []
    const pageBtns = targetNodes.btns ? targetNodes.btns.filter(btn => btn.typePage) : []
    const selectedTitle = multiCheck && selectedKeys.length > 1 ? `${selectedKeys.length}个` : targetNodes.node.name
    const selectedEvtKey = multiCheck && selectedKeys.length > 1 ? selectedKeys.join(';') : targetNodes.node.id
    return (
      <div className={styles.treeV}>
        <div className={classNames(styles.treeVLeft, { [styles.treeVCollapse]: collapse })}>
          <Icon
            type={collapse ? 'menu-unfold' : 'menu-fold'}
            title={collapse ? '展开' : '收起'}
            onClick={() => this.setState({ collapse: !collapse })}
            className={styles.treeVFold}
          />
          <div onClick={() => collapse && this.setState({ collapse: false })} className={styles.treeVWrap}>
            <span className={styles.treeVTitle}>{treeConfig.labelName}</span>
            <div className={styles.treeVDivider}></div>
            <div className={styles.treeVSelect}>
              <div title={selectedTitle || '无'} className={styles.treeVSelectTitle}>当前选中：{selectedTitle || '无'}</div>
              <div className={styles.treeVSelectBtns}>
                {
                  !multiCheck || selectedKeys.length === 1
                    ? toolBtns.map(tb => tb.component)
                    : null
                }
              </div>
            </div>
            <Input.Search
              allowClear
              onChange={this.handleSearch}
              placeholder='关键字搜索'
              className={styles.treeVSearch}
            />
            <div className={styles.treeVTree}>
              <Scrollbars autoHide autoHideTimeout={1000} autoHideDuration={200}>
                <Tree
                  showIcon
                  checkStrictly
                  checkable={multiCheck}
                  selectable={!multiCheck}
                  checkedKeys={selectedKeys}
                  selectedKeys={selectedKeys}
                  {...expandProps}
                  switcherIcon={<Icon type='caret-down' style={{ fontSize: 18 }} />}
                  onSelect={this.handleTreeNodesSelect}
                  onCheck={this.handleTreeNodesCheck}
                >
                  {this.renderTreeNodes(searchTreeData.length ? searchTreeData : treeData, thumbData)}
                </Tree>
              </Scrollbars>
            </div>
          </div>
        </div>
        <div key={selectedEvtKey} className={classNames(styles.treeVRight, { [styles.treeVCollapse]: collapse })}>
          {
            pageBtns.length
              ? (
                pageBtns.length > 1
                  ? (
                    <Tabs
                      activeKey={activeKey}
                      renderTabBar={() => this.renderTabBar(pageBtns)}
                      animated={false}
                      className='combination-page__mainTab'
                    >
                      {
                        pageBtns.map(pb => (
                          <Tabs.TabPane key={pb.btnConfig.id} tab={pb.btnConfig.label}>{pb.component}</Tabs.TabPane>
                        ))
                      }
                    </Tabs>
                  )
                  : pageBtns[0].component
              )
              : null
          }
        </div>
      </div>
    )
  }
}

export default connect(({ login, app }) => ({ login, app }))(VPage)
