import React, { useState, useEffect, useCallback, useRef } from 'react'
import { Tree, Button, Icon, Modal } from 'antd'
import router from 'umi/router'
import Prompt from '@/components/Prompt'
import { fetch, fetchList, apis } from '@/utils/request'
import NodeLabel from './components/NodeLabel'

const getTrees = fetch(apis.buildingOwnerInfo.getTrees)
const addNode = fetch(apis.buildingOwnerInfo.addNode)
const deleteNode = fetch(apis.buildingOwnerInfo.deleteNode)

const noticeAndReload = (content, type = 'success') => {
  Modal[type]({
    content,
    onOk: () => {
      window.location.reload()
    }
  })
}

export default props => {
  const nodeRef = useRef()
  const [promptVisible, setPromptVisible] = useState(false)
  const [treeData, setTreeData] = useState()

  const updateTreeData = (origin, parent, nodes) => {
    if (!parent) {
      const newData = [
        ...(origin || []),
        ...(Array.isArray(nodes) ? nodes : [nodes])
      ]
      return newData
    }

    const newData = (origin || []).map(x => {
      if (x.id === parent) {
        if (Array.isArray(nodes)) {
          x.children = [
            ...(x.children || []),
            ...nodes
          ]
        } else {
          x.children = [
            ...(x.children || []),
            nodes
          ]
        }
      } else {
        if (x.children && x.children.length) {
          x.children = updateTreeData(x.children, parent, nodes)
        }
      }

      return x
    })

    return newData
  }

  const getTreeData = (nodeData, refresh) => {

    const query = nodeData ? {
      id: nodeData.props.dataRef.id,
      name: nodeData.props.dataRef.name,
      treeType: nodeData.props.dataRef.type,
      nodeNumber: nodeData.props.dataRef.nodeNumber,
    } : { treeType: 'phase' }

    return new Promise((resolve, reject) => {
      getTrees({ params: query }).then(res => {
        if (refresh) {
          setTreeData(res)
        } else {
          const data = updateTreeData(treeData, query.id, res)
          setTreeData(data)
        }
        resolve()
      }).catch(err => reject(err))
    })
  }

  const showPrompt = (data) => {
    nodeRef.current = data
    setPromptVisible(true)
  }

  const handleNodeAdd = (promptData) => {
    setPromptVisible(false)
    const nodeData = nodeRef.current
    addNode({ data: {
      id: nodeData.id,
      name: nodeData.name,
      type: nodeData.type,
      nodeNumber: promptData,
    }}).then(() => {
      // 刷新页面, 重新请求数据
      // 直接刷数据, ant 有 bug
      // getTreeData(null, true)
      noticeAndReload('添加成功')
    })
  }

  const handleNodeDelete = (nodeData) => {
    deleteNode({ data: {
      id: nodeData.id,
      name: nodeData.name,
      type: nodeData.type,
      nodeNumber: nodeData.nodeNumber,
    }}).then(() => {
      // 刷新页面, 重新请求数据
      // 直接刷数据, ant 有 bug
      // getTreeData(null, true)
      noticeAndReload('删除成功')
    })
  }

  const handleBatchImport = () => {
    router.push('/property/buildingInfo/importExcel')
  }

  useEffect(() => {
    getTreeData(null, true)
  }, [])

  const renderTreeNodes = data => data.map(node => {
    return (      
      <Tree.TreeNode
        {...node}
        key={node.id}
        dataRef={node}
        isLeaf={node.type === 'end'}
        title={(<NodeLabel data={node} onAdd={showPrompt} onDelete={handleNodeDelete} />)}
      >
        {
          node.children ? renderTreeNodes(node.children) : null
        }
      </Tree.TreeNode>
    )
  })

  return (
    <>
      <div style={{ marginBottom: '24px' }}>
        <Button onClick={() => showPrompt({ type: 'phase' })}><Icon type="plus" />增加顶级节点</Button>
        <Button type="link" onClick={handleBatchImport} style={{ marginLeft: '24px' }}><Icon type="upload"/>批量导入小区楼栋信息</Button>
      </div>
      {
        treeData && treeData.length ? (
          <Tree loadData={getTreeData}>
            {renderTreeNodes(treeData)}
          </Tree>
        ) : (
          <p style={{ color: '#aaa', fontSize: '0.8em', textAlign: 'center', marginTop: '16px' }}>暂无数据</p>
        )
      }
      <Prompt visible={promptVisible} onOk={handleNodeAdd} onCancel={() => setPromptVisible(false)} />
    </>
  )
}
