import request from '@/config/axios'
import { isEmpty } from '@/utils/is'
import { jsonParse } from '@/utils'
import { handleTree } from '@/utils/tree'
import { defineComponent, ref, watch, onMounted, useAttrs } from 'vue'

interface TreeNode {
  id: string | number
  label: string
  children?: TreeNode[]
  isLeaf?: boolean
  [key: string]: any
}

interface ApiSelectTreeProps {
  // 选项标签字段
  labelField?: string
  // 选项值字段
  valueField?: string
  // API 接口
  url?: string
  // 请求方法
  method?: 'GET' | 'POST'
  // 请求参数
  data?: string
  // 自定义解析函数
  parseFunc?: string
  // 是否多选
  multiple?: boolean
  // 是否远程搜索
  remote?: boolean
  // 远程搜索字段
  remoteField?: string
  // 是否懒加载
  lazy?: boolean
  // 懒加载方法
  lazyLoad?: (node: TreeNode) => Promise<TreeNode[]>
  // 组件名称
  name?: string
}

export const useApiSelectTree = (option: ApiSelectTreeProps) => {
  return defineComponent({
    name: option.name || 'ApiSelectTree',
    props: {
      labelField: {
        type: String,
        default: () => option.labelField ?? 'label'
      },
      valueField: {
        type: String,
        default: () => option.valueField ?? 'value'
      },
      url: {
        type: String,
        default: () => option.url ?? ''
      },
      method: {
        type: String,
        default: () => option.method ?? 'GET'
      },
      parseFunc: {
        type: String,
        default: () => option.parseFunc ?? ''
      },
      data: {
        type: String,
        default: () => option.data ?? ''
      },
      multiple: {
        type: Boolean,
        default: () => option.multiple ?? false
      },
      remote: {
        type: Boolean,
        default: () => option.remote ?? false
      },
      remoteField: {
        type: String,
        default: () => option.remoteField ?? 'label'
      },
      lazy: {
        type: Boolean,
        default: () => option.lazy ?? false
      },
      lazyLoad: {
        type: Function,
        default: null
      }
    },
    setup(props, { emit }) {
      const attrs = useAttrs()
      const treeData = ref<TreeNode[]>([])
      const loading = ref(false)
      const queryParam = ref<any>()
      const expandedKeys = ref<(string | number)[]>([])
      const selectedKeys = ref<(string | number)[]>([])

      // 获取树数据
      const getTreeData = async () => {
        if (isEmpty(props.url)) {
          return
        }

        loading.value = true
        try {
          let url = props.url
          const data: any = jsonParse(props.data) || {}

          if (props.remote && queryParam.value !== undefined) {
            if (props.method === 'GET') {
              if (url.includes('?')) {
                url = `${url}&${props.remoteField}=${queryParam.value}`
              } else {
                url = `${url}?${props.remoteField}=${queryParam.value}`
              }
            } else {
              data[props.remoteField] = queryParam.value
            }
          }

          const response =
            props.method === 'GET'
              ? await request.get({ url })
              : await request.post({ url: props.url, data })
          console.log('response', response)

          parseTreeData(response)
        } finally {
          loading.value = false
        }
      }

      // 解析树数据
      const parseTreeData = (data: any) => {
        console.log(123, data)

        // 自定义解析函数优先
        if (!isEmpty(props.parseFunc)) {
          const parse = new Function(`return ${props.parseFunc}`)()
          treeData.value = formatTreeData(parse(data))
          return
        }

        // 直接返回数组的情况
        if (Array.isArray(data)) {
          treeData.value = formatTreeData(data)
          console.log('treeData', treeData.value)

          return
        }

        // 分页数据情况
        if (data.list && Array.isArray(data.list)) {
          treeData.value = formatTreeData(data.list)
          return
        }

        console.warn(`接口[${props.url}]返回结果不符合预期，建议使用自定义解析函数`)
      }

      // 格式化树数据
      const formatTreeData = (data: any[]): TreeNode[] => {
        const res1 = data.map((item) => ({
          id: parseExpression(item, props.valueField),
          label: parseExpression(item, props.labelField),
          value: parseExpression(item, props.valueField),
          isLeaf: !item.children || item.children.length === 0,
          ...item
        }))

        return handleTree(res1, 'id', 'parentId')
      }

      // 表达式解析
      const parseExpression = (data: any, template: string) => {
        if (template.indexOf('${') === -1) {
          return data[template]
        }
        const pattern = /\$\{([^}]*)}/g
        return template.replace(pattern, (_, expr) => {
          const result = data[expr.trim()]
          if (result === undefined) {
            console.warn(`模板[${template}]解析失败，属性[${expr.trim()}]不存在`)
          }
          return result || ''
        })
      }

      // 懒加载子节点
      const loadChildren = async (node: TreeNode) => {
        if (props.lazy && props.lazyLoad && !node.children) {
          loading.value = true
          try {
            const children = await props.lazyLoad(node)
            node.children = formatTreeData(children)
            node.isLeaf = children.length === 0
          } finally {
            loading.value = false
          }
        }
      }

      // 远程搜索
      const remoteMethod = async (query: string) => {
        if (!query) {
          return
        }
        queryParam.value = query
        await getTreeData()
      }

      // 处理节点展开
      const handleNodeExpand = (node: TreeNode) => {
        const index = expandedKeys.value.indexOf(node.id)
        if (index >= 0) {
          expandedKeys.value.splice(index, 1)
        } else {
          expandedKeys.value.push(node.id)
          // 懒加载
          if (props.lazy) {
            loadChildren(node)
          }
        }
      }

      // 处理节点选择
      const handleNodeSelect = (node: TreeNode) => {
        if (props.multiple) {
          const index = selectedKeys.value.indexOf(node.id)
          if (index >= 0) {
            selectedKeys.value.splice(index, 1)
          } else {
            selectedKeys.value.push(node.id)
          }
        } else {
          selectedKeys.value = [node.id]
        }
      }

      // 渲染树节点
      const renderTreeNodes = (nodes: TreeNode[]) => {
        return nodes.map((node) => (
          <el-tree-node key={node.id} node={node}>
            {{
              default: () => (
                <>
                  <span class="custom-tree-node">
                    <span>{node.label}</span>
                  </span>
                  {node.children && renderTreeNodes(node.children)}
                </>
              )
            }}
          </el-tree-node>
        ))
      }
      // 递归查找对象
      const findItemsByIds = (data, ids) => {
        const result = []
        const traverse = (nodes) => {
          nodes.forEach((node) => {
            if (ids.includes(node.id)) {
              result.push(node)
            }
            if (node.children) {
              traverse(node.children)
            }
          })
        }
        traverse(data)
        return result
      }
      // const selectedItems = ref([])
      // const handleChange = (ids) => {
      //   // 根据 ids 查找完整的对象
      //   selectedItems.value = findItemsByIds(treeData.value, ids)
      //   console.log('选中的对象:', selectedItems.value)
      //   emit('update:modelValue', selectedItems.value)
      //   emit('change', selectedItems.value)
      // }
      // 构建树选择器
      const buildTreeSelect = () => {
        return (
          <el-tree-select
            data={treeData.value}
            render-after-expand={false}
            multiple={props.multiple}
            style="width: 240px"
            props={{
              value: 'id', // 显示值用id
              label: 'label',
              children: 'children'
            }}
            onNodeClick={(item) => {
              // console.log('点击的节点数据:', item)
            }}
            onCheckChange={(item, checked) => {
              // console.log('复选框变化的节点数据:', item, checked)
            }}
            onCheck={(item, checkedInfo) => {
              // console.log('选中节点数据:', item, checkedInfo)
            }}
            onCurrentChange={(item) => {
              // console.log('当前节点数据:', item)
            }}
            onChange={(value, data) => {
              // data就是完整的节点数据
              // console.log('选中的完整数据:', value, data)
              // if (value && Array.isArray(value)) {
              //   handleChange(value)
              // } else {
              //   handleChange([value])
              // }
            }}
          />
          // <el-select
          //   class="w-1/1"
          //   multiple={props.multiple}
          //   loading={loading.value}
          //   {...attrs}
          //   remote={props.remote}
          //   {...(props.remote && { remoteMethod })}
          //   v-slots={{
          //     dropdown: () => (
          //       <el-tree
          //         data={treeData.value}
          //         node-key="id"
          //         props={{
          //           label: 'label',
          //           children: 'children',
          //           isLeaf: (node: TreeNode) => node.isLeaf
          //         }}
          //         expand-on-click-node={false}
          //         default-expand-all={!props.lazy}
          //         expanded-keys={expandedKeys.value}
          //         onNodeExpand={handleNodeExpand}
          //         onNodeClick={handleNodeSelect}
          //         load={props.lazy ? loadChildren : undefined}
          //         lazy={props.lazy}
          //       >
          //         {{
          //           default: ({ node, data }: { node: any; data: TreeNode }) => (
          //             <span class="custom-tree-node">
          //               <span>{data.label}</span>
          //             </span>
          //           )
          //         }}
          //       </el-tree>
          //     )
          //   }}
          // />
        )
      }

      // 初始化加载
      onMounted(() => {
        if (!props.remote) {
          getTreeData()
        }
      })

      return () => buildTreeSelect()
    }
  })
}
