import consts from '@/consts'
import { queryUsageSelectOptions } from '@/services/statistic'
import { getAuthCache, setAuthCache } from '@/utils/auth'
import { STATISTIC_OPTION_KEY } from '@/utils/cache/cacheEnum'
import { useDebounceFn } from 'ahooks'
import { Select, TreeSelect } from 'antd'
import React, { useState, useEffect, useMemo } from 'react'

enum statisticOptionMap {
  STAFF = 'staff',
  DEPARTMENT = 'department',
  SINGLE_STAFF = 'singleStaff',
  SINGLE_DEPARTMENT = 'singleDepartment'
}

type OptionSelectProps = {
  /** @name 是否多选 */
  multiple?: boolean
  type: string
  onChange: (type: 'staff' | 'department', value) => void
}

const options = [
  { label: '按部门', value: 'department' },
  { label: '按员工', value: 'staff' },
  { label: '指定部门', value: 'singleDepartment' },
  { label: '指定员工', value: 'singleStaff' }
]

function generateTree(tree) {
  return tree.map(item => {
    const newItem = { ...item }
    if (item.children?.length) {
      newItem.children = generateTree(item.children)
    }
    if (!item.isLeaf) {
      newItem.disabled = true
    }
    return newItem
  })
}

const OptionSelect: React.FC<OptionSelectProps> = ({ multiple = true, type, onChange }) => {
  const authOptions = getAuthCache(STATISTIC_OPTION_KEY)
  const { optionType, dataIds } = authOptions?.[type] || {}

  const [state, setState] = useState({
    loading: false,
    optionType: optionType || (multiple ? statisticOptionMap.STAFF : statisticOptionMap.SINGLE_STAFF),
    dataIds: null,
    department: [],
    staff: []
  })

  useEffect(() => {
    setState({ ...state, loading: true })
    const queryStaffAndDepartment = async () => {
      const { code = -1, data: { department = [], staff = [] } = {} } = await queryUsageSelectOptions()
      if (code === consts.RET_CODE.SUCCESS) {
        setState({
          ...state,
          department,
          staff,
          dataIds,
          loading: false
        })
      }
    }
    queryStaffAndDepartment()
    if (optionType && dataIds?.length) {
      onChange(optionType, dataIds)
    }
  }, [])

  const { run: trySetOpIds } = useDebounceFn(
    ids => {
      setState({ ...state, dataIds: ids })
      onChange(state.optionType, ids)
      setAuthCache(STATISTIC_OPTION_KEY, {
        ...authOptions,
        [type]: { optionType: state.optionType, dataIds: ids }
      })
    },
    { wait: 500 }
  )

  const treeOptions = useMemo(() => {
    const base = {
      className: 'min-w-45',
      dropdownMatchSelectWidth: true,
      onChange: value => trySetOpIds(value),
      treeDefaultExpandAll: true,
      treeNodeFilterProp: 'title',
      maxTagCount: 5
    }
    if ([statisticOptionMap.STAFF, statisticOptionMap.DEPARTMENT].includes(state.optionType)) {
      base.multiple = true
    }

    if ([statisticOptionMap.STAFF, statisticOptionMap.SINGLE_STAFF].includes(state.optionType)) {
      base.showCheckedStrategy = 'SHOW_PARENT'

      base.treeData =
        state.optionType === statisticOptionMap.SINGLE_STAFF ? generateTree(state.staff) : state.staff
    }

    if ([statisticOptionMap.DEPARTMENT, statisticOptionMap.SINGLE_DEPARTMENT].includes(state.optionType)) {
      base.treeCheckable = state.optionType === statisticOptionMap.SINGLE_DEPARTMENT ? false : true
      base.treeData = state.department
    }

    return base
  }, [state.optionType, state.department, state.staff])

  return (
    <div>
      <span className="mr-2">
        <Select
          defaultValue={state.optionType}
          options={options.filter(item => {
            if (!multiple) {
              return ['singleDepartment', 'singleStaff'].includes(item.value)
            } else {
              return ['department', 'staff'].includes(item.value)
            }
          })}
          onChange={val => setState({ ...state, optionType: val, dataIds: [] })}
        />
      </span>
      <TreeSelect value={state.dataIds} {...treeOptions} loading={state.loading} />
    </div>
  )
}

export default OptionSelect
