import React, { useEffect, useMemo, useState, useCallback } from 'react'
import { Table, Spin, Button, Icon, notification } from 'antd'
import { fetchList, fetch, apis } from '@/utils/request'
import { groupBy, orderBy } from 'lodash'
import Prompt from '@/components/Prompt'
import BuildingLevelRow from './BuildingLevelRow'

const fetchBuildingList = fetchList(apis.buildingOwnerInfo.getAllRoomNoList)
const addNode = fetch(apis.buildingOwnerInfo.addNode)
const deleteNode = fetch(apis.buildingOwnerInfo.deleteNode)

const getNumFromStr = str => {
  return ((str || '').match(/\d+/g) || []).join('') - 0
}

/**
 * 房间排序规则
 * 1、维护内容必须有数字
 * 2、单元 从小到大
 * 3、楼层 从大到小
 * 4、房号 从小到大
 * @param {*} room 
 */
const sortRoomList = roomList => {
  return orderBy(roomList,
    [
      room => getNumFromStr(room.unitName),
      room => getNumFromStr(room.levelName),
      room => getNumFromStr(room.name),
    ],
    [
      'asc',
      'desc',
      'asc'
    ]
  )
}

export default props => {
  const [loading, setLoading] = useState(false)
  const [unitVisible, setUnitVisible] = useState(false)
  const [roomList, setRoomList] = useState([])
  const [roomGroup, setRoomGroup] = useState({})
  
  const handleAddUnit = v => {
    addNode({ data: {
      id: props.building.id,
      name: props.building.name,
      type: 'unit',
      nodeNumber: v,
      communityId: props.community,
    }}).then((res) => {
      // 构造房间数据
      const roomInfo = {
        ...res,
        unitId: res.id,
        unitName: res.name,
        id: undefined,
        name: undefined,
        levelId: undefined,
        levelName: undefined,
      }

      setRoomList(roomList.concat(roomInfo))
      notification.success({message: '添加成功'})
    })
    setUnitVisible(false)
  }

  const handleDeleteUnit = room => {
    setRoomList(roomList.filter(r => r.unitId !== room.unitId))
  }

  const addHouse = useCallback(
    room => {
      // 如果有空房间, 直接替换空房间，否则新增一条记录
      let nvlRoom = false
  
      let newList = roomList.map(item => {
        if (room.phaseId === item.phaseId &&
          room.buildingId === item.buildingId &&
          room.unitId === item.unitId &&
          room.levelId === item.levelId &&
          !item.id && !nvlRoom) {
            nvlRoom = true
            return room
          } else {
            return item
          }
      })
  
      if (!nvlRoom) {
        newList = newList.concat(room)
      }
  
      setRoomList(sortRoomList(newList))
    },
    [roomList],
  )

  const handleHouseAdd = room => {
    addHouse(room)
  }

  // 如果编辑 # 的房间, 实际上是新增房间
  const handleHouseEdit = room => {
    let edited = false
    const newList = roomList.map(r => {
      if (r.id === room.id) {
        edited = true
        return room
      } else {
        return r
      }
    })

    if (edited) {
      setRoomList(newList)
    } else {
      addHouse(room)
    }
  }

  const handleHouseDelete = room => {
    let newList = []
    // 如果本层只有一个房间, 那么替换为空, 不删除数据
    const sameLevelRooms = roomList.filter(r => r.levelId === room.levelId)
    if (sameLevelRooms.length === 1) {
      newList = roomList.map(item => {
        if (item.id === room.id) {
          return {
            ...room,
            id: undefined,
            name: undefined,
          }
        } else {
          return item
        }
      })
    } else {
      newList = roomList.filter(r => r.id !== room.id)
    }
    setRoomList(newList)
  }

  const handleLevelAdd = room => {
    // 如果有空房间，替换空房间
    let nvlRoom = false
  
    let newList = roomList.map(item => {
      if (room.phaseId === item.phaseId &&
        room.buildingId === item.buildingId &&
        room.unitId === item.unitId &&
        !item.levelId && !nvlRoom) {
          nvlRoom = true
          return room
        } else {
          return item
        }
    })

    if (!nvlRoom) {
      newList = newList.concat(room)
    }

    setRoomList(sortRoomList(newList))
  }

  const handleLevelEdit = room => {
    setRoomList(roomList.map(item => {
      return item.levelId === room.levelId ?
        {...item, levelName: room.levelName} :
        item
    }))
  }

  const handleLevelDelete = room => {
    setRoomList(roomList.filter(r => r.levelId !== room.levelId))
  }

  useEffect(() => {
    if (props.building && props.phase && props.building.id && props.phase.id) {
      setLoading(true)
      fetchBuildingList({pageNum: 1, pageSize: 9999, phaseId: props.phase.id, buildingId: props.building.id}).then(res => {
        const [list = []] = res || []
        setRoomList(sortRoomList(list))
        setLoading(false)
      }).catch(e => console.error(e) || setLoading(false))
    }
  }, [props.building, props.phase])

  useEffect(() => {
    const groupByUnit = groupBy(roomList, row => [row.unitId, row.unitName].join(','))
    const groupByLevel = Object.keys(groupByUnit).reduce((acc, key) => {
      const groupWithLevelKey = groupBy(groupByUnit[key], row => [row.levelId, row.levelName].join(','))
      const pureLevelArr = Object.keys(groupWithLevelKey).map(k => groupWithLevelKey[k])

      return {
        ...acc,
        [key]: pureLevelArr
      }
    }, {})

    setRoomGroup(groupByLevel)
  }, [roomList])

  return (
    <div>
      <Button style={{marginLeft: 24}} onClick={() => setUnitVisible(true)}><Icon type="plus" />单元</Button>
      <Spin spinning={loading}>
        <div style={{display: 'flex', overflowX: 'auto'}}>
        {
          Object.keys(roomGroup).map(key => {
            return (
              <div style={{flex: 'none', marginLeft: 48}} key={key}>
                <BuildingLevelRow
                  dataSource={roomGroup[key]}
                  community={props.community}
                  onUnitDelete={handleDeleteUnit}
                  onHouseAdd={handleHouseAdd}
                  onHouseEdit={handleHouseEdit}
                  onHouseDelete={handleHouseDelete}
                  onLevelAdd={handleLevelAdd}
                  onLevelEdit={handleLevelEdit}
                  onLevelDelete={handleLevelDelete}
                />
              </div>
            )
          })
        }
        </div>
      </Spin>
      <Prompt visible={unitVisible} onOk={handleAddUnit} onCancel={() => setUnitVisible(false)} placeholder="请填写单元名称" />
    </div>
  )
}
