<script setup lang="ts">
import Sortable from 'sortablejs'
import type { SortableEvent } from 'sortablejs'
import { getCategoryList, delCategory, moveCategory } from '../api'
import { ElMessage, ElMessageBox } from 'element-plus'
import { checkPermission } from '@/utils/permission'
import AddDialog from '../components/AddDialog.vue'
import AppList from '@/components/base/AppList.vue'
const appList = ref<null | InstanceType<typeof AppList>>(null)

const prevCategoryName = ref('')
const title = ref('')
const dialogVisible = ref(false)

interface ICategory {
  pid?: string
  category_name: string
  depth: string
  id: string
  lft?: string
  need_pass?: string
  rgt: string
  status_name: string
  children?: ICategory[]
}
const tableData = ref<ICategory[]>([])
const editData = ref({})
const isEdit = ref(false)
const handleEdit = (row: ICategory) => {
  title.value = '编辑类别'
  isEdit.value = true
  dialogVisible.value = true
  editData.value = row
  if (row.depth > '0') {
    prevCategoryName.value = getParent(row.id, tableData.value[0]).category_name
  } else {
    prevCategoryName.value = ''
  }
}
// 删除分类
const handleDelete = (row: ICategory) => {
  ElMessageBox.confirm('确定要删除吗？', '提示').then(() => {
    const params = { id: row.id }
    delCategory(params).then(() => {
      ElMessage.success('删除成功')
      handleUpdate()
    })
  })
}
// 行内新增类别
const handleAddRow = (row: ICategory) => {
  isEdit.value = false
  dialogVisible.value = true
  title.value = '新增类别'
  editData.value = row
  // if (row.depth > '0') {
  //   prevCategoryName.value = getParent(row.id, tableData[0]).category_name
  // } else {
  //   prevCategoryName.value = ''
  // }
}
// // 外部新增类别
const handleAddCategory = () => {
  isEdit.value = false
  dialogVisible.value = true
  title.value = '新增类别'
  editData.value = tableData.value[0]
  prevCategoryName.value = tableData.value[0].category_name
}
// 获取上级类别
const getParent = (node: string, tree: any) => {
  let result: any = []
  function find(node: string, tree: any) {
    tree.children.forEach((item: any) => {
      if (item.id === node) {
        result.push(tree)
      }
      if ('children' in item) {
        find(node, item)
      }
    })
  }
  find(node, tree)
  return result[0]
}

// 获取分类列表
const handleUpdate = () => {
  appList.value?.refetch()
}

// 扁平列表数据
const tableDataList = ref<ICategory[]>([])
// 列表配置
const listOptions = computed(() => {
  return {
    remote: {
      httpRequest: getCategoryList,
      params: { type: 'tree', category_name: '' },
      callback(data: ICategory[], params: any) {
        const list = rebuildData(params.category_name, data)
        tableData.value = list
        tableDataList.value = flatten(list)
        return { list }
      },
    },
    filters: [{ type: 'input', prop: 'category_name', label: '类别名称：', placeholder: '请输入类别名称' }],
    columns: [
      { label: '类别名称', prop: 'category_name' },
      { label: '层级', prop: 'depth', align: 'center' },
      { label: '状态', prop: 'status_name', align: 'center' },
      { label: '操作', slots: 'table-operate', width: 230, align: 'center', fixed: 'right' },
    ],
    data: tableData.value,
  }
})
// 数据扁平化
function flatten(data: any[], pid = '0') {
  return data.reduce((acc: any[], item: any) => {
    item.pid = pid
    acc.push(item)
    if (item.children) {
      acc.push(...flatten(item.children, item.id))
    }
    return acc
  }, [])
}
// 拖拽
function useSortable() {
  const el = appList.value?.$el.querySelector('.el-table__body-wrapper tbody')
  if (!el) return

  Sortable.create(el, {
    animation: 300,
    // onMove(evt: MoveEvent) {
    // const dragged = evt.dragged as HTMLTableRowElement
    // const related = evt.related as HTMLTableRowElement
    // const draggedRow = tableDataList[dragged.rowIndex]
    // const relatedRow = tableDataList[related.rowIndex]
    // 禁止跨级拖拽
    // if (draggedRow.depth !== relatedRow.depth || draggedRow.pid !== relatedRow.pid) {
    //   return false
    // }
    // },
    onEnd(evt: SortableEvent) {
      const { oldIndex, newIndex } = evt
      if (oldIndex === undefined || newIndex === undefined || oldIndex === newIndex) return
      const draggedRow = tableDataList.value[oldIndex]
      const relatedRow = tableDataList.value[newIndex]
      moveCategory({
        id: draggedRow.id,
        brother_id: relatedRow.id,
        type: newIndex > oldIndex ? 'after' : 'before',
      }).then(() => {
        // 修复拖拽后数据顺序不对的问题
        if (oldIndex < newIndex) {
          tableData.value = []
        }
        handleUpdate()
      })
    },
  })
}

// 展开行
const expandRowKeys = ref<string[]>([])
function onExpandChange(row: ICategory, expanded: boolean) {
  if (expanded) {
    expandRowKeys.value.push(row.id)
  } else {
    expandRowKeys.value = expandRowKeys.value.filter((id) => id !== row.id)
  }
}

// 重点代码 根据name字段模糊匹配树状结构数据，最后将处理好的数据返回出来
const rebuildData = (value: any, arr: any) => {
  if (value === '' || value === undefined) {
    return arr
  }
  if (!arr) {
    return []
  }
  let newArr: any = []
  arr.forEach((element: any) => {
    // indexOf用来判读当前节点name字段是否包含所搜索的字符串value
    // 返回值：包含则返回索引值，反之返回-1
    if (element.category_name.indexOf(value) > -1) {
      const ab = rebuildData(value, element.children)
      const obj = {
        ...element,
        children: ab,
      }
      newArr.push(obj)
    } else {
      // 判断当前节点知否有子节点，并且子节点中有数据，有数据继续递归查找
      if (element.children && element.children.length > 0) {
        const ab = rebuildData(value, element.children)
        const obj = {
          ...element,
          children: ab,
        }
        if (ab && ab.length > 0) {
          newArr.push(obj)
        }
      }
    }
  })
  return newArr
}

onMounted(() => {
  checkPermission('v1-backend-category-drag') && useSortable()
})
</script>
<template>
  <AppCard title="类别管理">
    <AppList
      v-bind="listOptions"
      :has-pagination="false"
      row-key="id"
      ref="appList"
      :expand-row-keys="expandRowKeys"
      @expand-change="onExpandChange"
      border
      stripe>
      <el-button
        type="primary"
        @click="handleAddCategory"
        style="margin-bottom: 20px"
        v-permission="'v1-backend-category-create'"
        >新增类别</el-button
      >
      <template #table-operate="{ row }">
        <el-link
          type="primary"
          style="margin-right: 5px"
          @click="handleEdit(row)"
          v-permission="'v1-backend-category-update'"
          >编辑</el-link
        >
        <el-link
          type="primary"
          style="margin-right: 5px"
          @click="handleAddRow(row)"
          v-permission="'v1-backend-category-create'"
          >新增</el-link
        >
        <el-link type="primary" @click="handleDelete(row)" v-permission="'v1-backend-category-delete'">删除</el-link>
      </template>
    </AppList>
  </AppCard>
  <AddDialog
    v-model:dialogVisible="dialogVisible"
    @updatePage="handleUpdate"
    :editData="editData"
    :isEdit="isEdit"
    :title="title"
    :prevCategoryName="prevCategoryName"
    v-if="dialogVisible" />
</template>
