<script setup>
import Sortable from "sortablejs";
import {assistanceDocInterence,businessCustomInterence} from "@/api/api.js"
//import dragTreeTable from "drag-tree-table";
import { reactive, ref, watch, computed, nextTick, onMounted } from 'vue'
import { Search } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'

let tableData = ref([]) //table展示数据
let flatedData = ref([]) //table数据平铺
let classifyForm = reactive({
    ParentId:0,
    HelpDocClassifyId:0,
    HelpDocClassifyName:'',
    Level:0,
})
let classifyFormRef = ref(null)
let noLevelThreeList = ref([])
let dialogTitle = ref("")
let showAddClassifyDia = ref(false)

let permissionFormRef = ref(null)
let merchantList = ref([])
let showPermissionDia = ref(false)
let permissionForm = reactive({
    HelpDocClassifyId:0,
    merchantIds:[]
})
let queryParams = reactive({
    KeyWord:''
})
function getmerchantList(){
    businessCustomInterence.getBusinessList({PageSize:9999999,CurrentIndex:1}).then(res=>{
        if(res.Ret == 200){
            merchantList.value = res.Data.List||[]
        }
    })
}
getmerchantList()
function getclassifyData(){
    assistanceDocInterence.getAssistanceClassifyList(queryParams).then(res=>{
        if(res.Ret == 200){
            tableData.value = res.Data?.AllNodes||[]
            flatedData.value = flatData(tableData.value)
            noLevelThreeList.value = res.Data?.TwoLevelNodes||[]
        }
    })
}
getclassifyData()

function addClassify(){
    dialogTitle.value = "添加分类"
    showAddClassifyDia.value = true
}

function editClassify(item){
    Object.assign(classifyForm,{
        ParentId:item.ParentId,
        HelpDocClassifyId:item.ClassifyId,
        HelpDocClassifyName:item.ClassifyName
    })
    dialogTitle.value = "编辑分类"
    showAddClassifyDia.value = true
}
function configClassify(row){
    Object.assign(permissionForm,{
        HelpDocClassifyId:row.ClassifyId,
        merchantIds:row.VisibleBusinessIds?row.VisibleBusinessIds.split(',').map(element => {
            return parseInt(element)
        }):[]
    })
    dialogTitle.value = "设置权限"
    showPermissionDia.value = true
}
function resetPermissonForm(){
    Object.assign(permissionForm,{
        HelpDocClassifyId:0,
        merchantIds:[]
    })
    permissionFormRef.value?.clearValidate()
}
function configSave(){
    assistanceDocInterence.editAssistanceClassifyVisible({
        HelpDocClassifyId:permissionForm.HelpDocClassifyId,
        VisibleBusinessIds:permissionForm.merchantIds.join(',')
    }).then(res=>{
        if(res.Ret == 200){
            ElMessage.success("设置成功")
            showPermissionDia.value=false
            resetPermissonForm()
            getclassifyData()
        }
    })
}

function deleteClassify(item){
    ElMessageBox.confirm('是否确认删除？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
    }).then(() => {
        assistanceDocInterence.deleteAssistanceClassify({ClassifyId:item.ClassifyId}).then(res=>{
            if(res.Ret == 200){
                ElMessage.success("删除分类成功")
                getclassifyData()
            }
        })
    }).catch(()=>{})
}
function resetForm(){
    Object.assign(classifyForm,{
        ParentId:0,
        HelpDocClassifyId:0,
        HelpDocClassifyName:'',
        Level:0,
    })
    classifyFormRef.value?.clearValidate()
}

let parentIdCascaderRef = ref(null)
function selectParentId(){
    classifyForm.Level = parentIdCascaderRef.value?.getCheckedNodes()[0].data.Level||0
}
function classifySave(){
    classifyFormRef.value?.validate(valid=>{
        if(valid){
            if(classifyForm.HelpDocClassifyId){
                //编辑
                assistanceDocInterence.editAssistanceClassify(classifyForm).then(res=>{
                    if(res.Ret == 200){
                        ElMessage.success(dialogTitle.value+"成功")
                        showAddClassifyDia.value = false
                        resetForm()
                        getclassifyData()
                    }
                })
            }else{
                //新增
                assistanceDocInterence.addAssistanceClassify(classifyForm).then(res=>{
                    if(res.Ret == 200){
                        ElMessage.success(dialogTitle.value+"成功")
                        showAddClassifyDia.value = false
                        resetForm()
                        getclassifyData()
                    }
                })
            }
        }
    })
}

//平铺tableData
function flatData(data){
    let result = [];

    function recurse(nodes) {
        nodes.forEach((node) => {
        result.push(node);
        if (node.Children && node.Children.length) {
            recurse(node.Children);
        }
        });
    }

    recurse(data); 
    return result;
}
let isInvalidDrag = false //不合法的拖拽
let tableKey = ref(0) //刷新组件用
let sortableObj = null
function initSortable(){
    if(sortableObj){
        sortableObj = null
    }
    const el = document.querySelector('#sortableTable .el-table__body-wrapper tbody')
    if(!el) return 
    sortableObj = Sortable.create(el,{
        animation:100,
        filter:'.el-table__row--level-0',
        onEnd:(evt)=>{
            if(isInvalidDrag){
                isInvalidDrag = false
                //刷新组件
                tableKey.value++
                //刷新组件会导致绑定失效,重新绑定
                nextTick(()=>{
                    initSortable()
                })
                return
            }
            const { oldIndex, newIndex } = evt
            if(oldIndex===newIndex) return 

            let ClassifyId=0,ParentClassifyId=0,PrevClassifyId=0,NextClassifyId=0

            const draggedItem = flatedData.value[oldIndex]
            ClassifyId = draggedItem.ClassifyId

            //需要newIndex的ParentId
            ParentClassifyId = flatedData.value[newIndex].ParentId
            //sortable拖拽并不会改变data数据，调整flatedData数据的顺序
            flatedData.value.splice(oldIndex,1)
            flatedData.value.splice(newIndex,0,draggedItem)

            const preItem = flatedData.value[newIndex===0?0:newIndex-1]
            PrevClassifyId = (preItem.Level===draggedItem.Level)?preItem.ClassifyId:0

            const nextItem = flatedData.value[newIndex===flatedData.length-1?flatedData.length-1:newIndex+1]
            NextClassifyId = (nextItem.Level===draggedItem.Level)?nextItem.ClassifyId:0

            assistanceDocInterence.moveAssistanceClassify({
                ClassifyId,ParentClassifyId,PrevClassifyId,NextClassifyId
            }).then(res=>{
                if(res.Ret == 200){
                    ElMessage.success("移动分类成功")
                    getclassifyData()
                }
            })
        },
        onMove:(evt)=>{
            //判断拖动是否合法，不合法返回 false
            const {dragged, related } = evt
            const draggedItem = flatedData.value[dragged.rowIndex]
            const relatedItem = flatedData.value[related.rowIndex]
            //不同级不允许拖拽
            isInvalidDrag = !(draggedItem?.Level===relatedItem?.Level)
            return draggedItem?.Level===relatedItem?.Level
        }
    })
}
onMounted(()=>{
    initSortable()
})
</script>

<template>
  <div class="doc-classifyMana-container">
    <div class="doc-classifyMana-top-zone">
      <el-button type="primary" @click="addClassify">添加分类</el-button>
      <el-input :prefix-icon="Search" placeholder="分类名称" v-model="queryParams.KeyWord" @input="getclassifyData" clearable 
      style="width:500px;margin-left: 20px;">
      </el-input>
    </div>
    <!-- 原先使用drag-tree-table，这个组件几年前就不维护了而且没有vue3版本，用sortablejs重写了拖拽排序逻辑 -->
    <el-table :data="tableData" row-key="ClassifyId" id="sortableTable" default-expand-all :key="tableKey"
        :tree-props="{children:'Children',hasChildren:'hasChildren'}">
        <el-table-column prop="ClassifyName" label="一级分类" align="center">
            <template #default="{row}">
                <span>{{row.Level===1?row.ClassifyName:''}}</span>
            </template>
        </el-table-column>
        <el-table-column prop="ClassifyName" label="二级分类" align="center">
            <template #default="{row}">
                <span>{{row.Level===2?row.ClassifyName:''}}</span>
            </template>
        </el-table-column>
        <el-table-column prop="ClassifyName" label="三级分类" align="center">
            <template #default="{row}">
                <span>{{row.Level===3?row.ClassifyName:''}}</span>
            </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="400px">
            <template #default="{row}">
                <el-link :underline="false" type="primary" style="margin-right: 10px;" @click="configClassify(row)">权限配置</el-link>
                <el-link :underline="false" type="primary" style="margin-right: 10px;" @click="editClassify(row)">编辑</el-link>
                <el-link :underline="false" type="danger" @click="deleteClassify(row)" >删除</el-link>
            </template>
        </el-table-column>
    </el-table>
    <!-- 添加分类弹窗 -->
    <el-dialog :title="dialogTitle" v-model="showAddClassifyDia" width="625px"
    append-to-body :close-on-click-modal="false" @close="resetForm">
        <div style="display: flex;flex-direction: column; align-items: center;margin-bottom: 35px;">
        <el-form :model="classifyForm" ref="classifyFormRef" label-width="85px">
            <el-form-item label="上级目录" prop="ParentId">
            <el-cascader v-model="classifyForm.ParentId" :options="noLevelThreeList" @change="selectParentId"
                placeholder="请选择上级目录（不选默认添加的是一级分类）" ref="parentIdCascaderRef"
                :props="{ value:'ClassifyId',label:'ClassifyName',children:'Children',checkStrictly:true,emitPath:false,disabled:'Disabled'}" 
                class="lastCatalogCascader" :disabled="dialogTitle.indexOf('编辑分类')!=-1" />
            </el-form-item>
            <el-form-item label="分类名称" prop="HelpDocClassifyName" :rules="{required:true,message:'分类名称不能为空',trigger:'blur'}">
            <el-input v-model="classifyForm.HelpDocClassifyName" placeholder="请输入分类名称" style="width: 337px;"
                maxlength="10"></el-input>
            </el-form-item>
        </el-form>
        <div style="margin-top: 40px;">
            <el-button type="primary" style="width:120px;margin-right:10px" @click="classifySave" >保存</el-button>
            <el-button  style="width:120px;" @click="showAddClassifyDia=false">取消</el-button>
        </div>
        </div>
    </el-dialog>
    <!-- 设置权限弹窗 -->
    <el-dialog :title="dialogTitle" v-model="showPermissionDia" width="625px" class="doc-classify-dialog"
    append-to-body :close-on-click-modal="false" @close="resetPermissonForm">
      <div style="display: flex;flex-direction: column; align-items: center;margin-bottom: 35px;">
        <el-form :model="permissionForm" ref="permissionFormRef" label-width="80px">
          <el-form-item label="可见权限" prop="merchantIds">
            <el-select v-model="permissionForm.merchantIds" placeholder="请选择商家" 
            multiple style="width:337px;" collapse-tags clearable filterable >
              <el-option :label="item.BusinessName" :value="item.EtaBusinessId" 
              v-for="item in merchantList" :key="item.merchantId"></el-option>
            </el-select>
          </el-form-item>
        </el-form>
        <div style="margin-top: 40px;">
          <el-button type="primary" style="width:120px;margin-right:10px" @click="configSave">保存</el-button>
          <el-button  style="width:120px;" @click="showPermissionDia=false" >取消</el-button>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<style lang="scss" scoped>
.doc-classifyMana-container{
  background-color: white;
  min-height: calc(100vh - 110px);
  padding: 30px;
  box-sizing: border-box;
  border: solid 1px #ECECEC;
  .doc-classifyMana-top-zone{
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    margin-bottom: 20px;
  }
}
</style>
<style lang="scss">
.doc-classify-dialog{
    .el-select{
        .el-input{
            width:100% !important;
        }
    }
}
.lastCatalogCascader{
  width: 337px;
  .el-input{
    width: 337px;
  }
}
.has-child-row {
    background-color: #f2f6fa!important;
}
.table-button{
    color:#4099ef; 
    cursor: pointer;
    margin-right: 10px;
  }
</style>