<script setup name="ChartETAList">
//ETA图库页面
import {ref,reactive,watch,computed} from 'vue'
import { useRouter } from 'vue-router'
import { showToast,showDialog} from "vant";
import { useWindowSize } from '@vueuse/core'
import CatalogTree from './components/CatalogTree.vue';
import CatalogItem from './components/CatalogItem.vue';
import OptionPopup from './components/OptionPopup.vue';
import AddChartToMyETA from './components/AddChartToMyETA.vue';
import TreeSelectPop from './components/TreeSelectPop.vue';
import apiChart from '@/api/chart';
import {chartLibBtn,useAuthBtn} from '@/hooks/useAuthBtn'
import { useNoAuth } from '@/hooks/useNoAuth'
const {checkAuthBtn} = useAuthBtn()
import {useCatalogList} from './hooks/useCatalogList';

const { width } = useWindowSize()
const router=useRouter()

const {
    optArrChart,//图表操作列表
    currentLang,//中英文标识
    catalogNodes,//目录列表
    getCatalogList,//获取图库目录
    UserInfo,//用户信息
    optArrNode,
    authOptArr,
} = useCatalogList()

//跳转至图表详情页
const goChartDetail = (item)=>{
    if(!item.HaveOperaAuth) return showToast(useNoAuth().chart)

    router.push({
        path:'/chartETA/chartdetail',
        query:{
            id:item.ChartInfoId,
            chartType:item.ChartType,
            chartClassifyId:listState.cid,
            IsShowMe:listState.IsShowMe,
            DateType:item.DateType,
            StartDate:(item.DateType===5||item.DateType===6)?item.StartDate:'',
            EndDate:(item.DateType===5||item.DateType===6)?item.EndDate:'',
            Calendar:item.Calendar?item.Calendar:'公历',
            SeasonStartDate:item.SeasonStartDate,
            SeasonEndDate:item.SeasonEndDate,
            StartYear:item.StartYear
        }
    })
}


//是否展示目录列表
const IsShowCatalog = ref(false)
//展开的目录
const activeCatalogs = ref([])

//展示目录列表
function showCatalog(){
    IsShowCatalog.value = true
}
//切换中英文
async function changeLang(){
    const res = await apiChart.setUserLang({
        ConfigCode:'chart_language',
        ConfigValue:currentLang.value==='EN'?'CN':'EN'
    })
    if(res.Ret!==200) return 
    showToast({message:`切换${currentLang.value==='EN'?'中文':'英文'}成功`,type:'success'})
    currentLang.value = currentLang.value==='EN'?'CN':'EN'
    localStorage.setItem('chartETALange',currentLang.value)
}
//激活的目录路径
const catalogMenu = ref('')
//目录被点击 type:['top'一级目录,'node'二级目录,'item'三级目录]
function catalogItemClick({item,type='node',parent={}}){
    const topMenu = type==='top'?item.ChartClassifyName:type==='node'?item.parentName:parent.parentName
    const nodeMenu = type==='node'?item.ChartClassifyName:type==='item'?parent.ChartClassifyName:''
    const itemMenu = type==='item'?item.ChartClassifyName:''

    catalogMenu.value = `${topMenu}${nodeMenu.length?`/${nodeMenu}`:''}${itemMenu.length?`/${itemMenu}`:''}`
    listState.cid = item.ChartClassifyId
    listState.list=[]
    listState.page=1
    getChartList()
}

//是否展示操作栏
const showOptPopup = ref(false)
//操作项
const currentOptArr = ref([])
//操作的节点
const currentNode = ref({})
//展示操作栏
function showFileOpt({node,optArr}){
    currentNode.value = node
    currentOptArr.value = authOptArr(node,optArr)
    showOptPopup.value = true
}

//目录/图表操作栏被点击,处理事件(添加图表分类,添加子分类,重命名,删除分类,移动分类,加入我的图库,移动图表)
function showFileOptClick({node,opt}){
    const eventMap = {
        'addNext':openEditNameDialog,
        'reName':openEditNameDialog,
        'delete':openDeleteDialog,
        'moveTo':openMoveDialog,
        'addChart':openAddChartDialog,
        'moveChart':openMoveChartDialog,
        'cancel':()=>{showOptPopup.value = false}
    }
    eventMap[opt.id](node,opt)
}

//编辑目录参数
const editNameState = reactive({
    isShowDialog:false,//是否展示编辑名称弹窗
    ChartClassifyId:0,//目录id,为0表示新增
    ChartClassifyName:'',
    Level:1,//层级,大于1时parentName有值
    parentNames:[],
    parentName:'',//上级目录的名称
    type:'addNew',//编辑类型
    title:'添加图表分类',//弹窗标题 ['添加图表分类','添加子分类','重命名']
})
//编辑目录
function openEditNameDialog(node,opt){
    const {Level,ChartClassifyId,ChartClassifyName,parentName} = node
    editNameState.Level = Level

    if(editNameState.Level>1){
        //找到目录的所有父级目录,并获取目录名称
        const parentNodes = findParentNodeHandle(catalogNodes.value,ChartClassifyId)
        editNameState.parentNames = parentNodes.reverse().map(i=>i.ChartClassifyName)
        opt.id!=='addNext'&&editNameState.parentNames.pop()
    }else{
        editNameState.parentNames = []
    }

    editNameState.ChartClassifyId = opt.id==='addNext'?0:ChartClassifyId||0
    editNameState.ChartClassifyName = opt.id==='addNext'?'':ChartClassifyName||''
    editNameState.parentName = opt.id==='addNext'?ChartClassifyName:parentName||''
    editNameState.ParentId=opt.id==='addNext'?node.ChartClassifyId:node.ParentId||0
    editNameState.title = opt.label
    editNameState.type = opt.id
    editNameState.isShowDialog = true
}
//根据editNameState调用对应接口
function handleConfirmEditClassify(){
    //先判断输入框有无内容
    if(!editNameState.ChartClassifyName.length){
        showToast('请填写分类名称！')
        return
    }
    if(editNameState.type==='reName'){
        editClassify()
    }else{
        addNewClassify()
    }
}
function handleAddClassifyBeforeClose(action){
    return action==='cancel'
}

//添加图表分类,添加子分类
async function addNewClassify(){
    const {ChartClassifyName,ParentId,Level} = editNameState
    const res = await apiChart.addNewClassify({
        ChartClassifyName:ChartClassifyName||'',
        Level,
        ParentId
    })
    if(res.Ret!==200) return 
    showToast({message:'添加成功',type:'success'})
    getCatalogList()
    editNameState.isShowDialog = false
}
//重命名
async function editClassify(){
    const {ChartClassifyId,ChartClassifyName} = editNameState
    const res  = await apiChart.editClassify({
        ChartClassifyId,ChartClassifyName
    })
    if(res.Ret!==200) return 
    showToast({message:'重命名成功',type:'success'})
    getCatalogList()
    editNameState.isShowDialog=false
}

//删除分类
async function openDeleteDialog(node){
    const res = await apiChart.deleteCheck({
        ChartClassifyId:node.ChartClassifyId,
        ChartInfoId:node.ChartInfoId
    })
    if(res.Ret!==200) return
    //可删除包括删除图表和删除图表分类两种情况,但列表里只能删除分类
    const hintTextMap = {
        0:'确定删除当前分类吗？',
        1:'该分类下关联图表不可删除!',
        2:'确认删除当前分类及包含的子分类吗？'
    }
    showDialog({
        title: '提示',
        message: hintTextMap[res.Data.DeleteStatus||0],
        showCancelButton:res.Data.DeleteStatus!==1
    }).then(() => {
        if(res.Data.DeleteStatus!==1){
            apiChart.deleteClassify({
                ChartClassifyId:node.ChartClassifyId,
                ChartInfoId:node.ChartInfoId
            }).then(res=>{
                if(res.Ret!==200) return 
                showToast({message:'删除成功',type:'success'})
                getCatalogList()
            })
        }
    }).catch(()=>{})
}

//移动分类参数
const moveClassState = reactive({
    isShowPopup:false,//是否显示移动分类弹窗
    ClassifyId:0,//移动的分类id
    ParentClassifyId:0,//移动至哪个分类下
    PrevClassifyId:0,//移动后所处的位置,由于不能拖拽,一直为0
    NextClassifyId:0,
    Level:1,//用于判断移动的是二级目录还是三级目录
    ParentId:0,
    isShowPickerPop:false,//是否显示移动二级分类弹窗
    isShowTreePop:false,//是否显示移动三级分类弹窗
})
moveClassState.isShowPickerPop = computed(()=>{
    return moveClassState.isShowPopup&&moveClassState.Level===2
})
moveClassState.isShowTreePop = computed(()=>{
    return moveClassState.isShowPopup&&moveClassState.Level!==2
})
//移动分类
function openMoveDialog(node){
    const {ChartClassifyId,Level,ParentId} = node
    moveClassState.ClassifyId = ChartClassifyId
    moveClassState.Level = Level
    moveClassState.ParentId = ParentId
    moveClassState.isShowPopup = true
}
function handleMoveClassify({selectedValues}){
    moveClassState.ParentClassifyId = selectedValues[0]||0
    moveClassify()
}
function closeMoveDialog(){
    moveClassState.isShowPopup = false
    moveClassState.ClassifyId = 0
    moveClassState.ParentClassifyId = 0
    moveClassState.PrevClassifyId = 0
    moveClassState.NextClassifyId = 0
    moveClassState.Level = 1
    moveClassState.ParentId = 0
}
async function moveClassify(){
    const {ClassifyId,ParentClassifyId,PrevClassifyId,NextClassifyId,Level} = moveClassState
    const res = await apiChart.moveClassify({
        ClassifyId,ParentClassifyId,PrevClassifyId,NextClassifyId
    })
    if(res.Ret!==200) return 
    showToast({message:'移动成功',type:'success'})
    await getCatalogList()
    //选中移动后的目录，并展开父级目录
    const parentNodes = findParentNodeHandle(catalogNodes.value,ClassifyId)
    catalogItemClick({
        item:parentNodes[0],
        type:Level===2?'node':'item',
        parent:parentNodes[1]
    })
    console.log(parentNodes)
    /* if(Level===2){
        const parentNode = catalogNodes.value.find(node=>node.ChartClassifyId===ParentClassifyId)
        const moveNode = parentNode?parentNode.Children.find(node=>node.ChartClassifyId===ClassifyId):null
        moveNode&&catalogItemClick({item:moveNode,type:'item',parent:parentNode})
    }else{

    }
     */
    moveClassState.isShowPopup = false

}

//找到节点的所有父节点
function findParentNodeHandle(arr, id) {
    for (let i of arr) {
        if (i.ChartClassifyId === id) {
            return [i];
        }
        if (i.Children) {
            let node = findParentNodeHandle(i.Children, id);
            if (node) {
                return node.concat(i);
            }
        }
    }
}

//添加我的图库参数
const addChartState = reactive({
    isShowDialog:false,
    chartInfo:{}
})
function openAddChartDialog(node){
    addChartState.chartInfo = node
    addChartState.isShowDialog = true
}
//移动图表参数
const moveChartState = reactive({
    isShowDialog:false,
    popTitle:'移动至',
    catalogNodes:catalogNodes,
    chartInfo:{}
})
function openMoveChartDialog(node){
    moveChartState.chartInfo = node
    moveChartState.isShowDialog = true
}

async function MoveChart(moveId){
    const res = await apiChart.moveChart({
        ChartClassifyId:moveId,
        ChartInfoId:moveChartState.chartInfo.ChartInfoId,
        PrevChartInfoId:0,
        NextChartInfoId:0
    })
    if(res.Ret!==200) return 
    showToast({message:'移动图表成功',type:'success'})
    //如果分类id未0 手动修改移动的图表
    if(listState.cid===0){
        listState.list.find(item=>{
            if(item.ChartInfoId===moveChartState.chartInfo.ChartInfoId){
                item.ChartClassifyId = moveId
            }
        })
    }else{//如果在分类下，重新获取chartList
        window.scrollTo({top:0})
        listState.list=[]
        listState.page=1
        //设置数据已加载完毕，因为当滚动条不在顶部时，清空列表内容会触发onLoad
        listState.finished = true 
        //这个函数调用完成后，会把finished重置成正确的值
        getChartList()
    }
    
    moveChartState.isShowDialog = false
}

//图表列表
const listState = reactive({
    cid:0,
    list:[],
    page:1,
    pageSize:15,
    finished:false,
    loading:false,
    total:0,
    IsShowMe:false
})
//获取图表列表
async function getChartList(){
    const {pageSize,cid,page,IsShowMe} = listState
    const res = await apiChart.pubChartList({
        PageSize: pageSize,
        CurrentIndex: page,
        ChartClassifyId: cid,
        IsShowMe,
    })
    if(res.Ret!==200) return 
    const arr = res.Data?res.Data.List:[]
    listState.list = [...listState.list,...arr]
    listState.total = res.Data?res.Data.Paging.Totals:0
    listState.finished = res.Data?res.Data.Paging.IsEnd:true
    listState.loading=false
}

watch(()=>listState.IsShowMe,()=>{
    window.scrollTo({top:0})
    listState.list=[]
    listState.page=1
    //设置数据已加载完毕，因为当滚动条不在顶部时，清空列表内容会触发onLoad
    listState.finished = true 
    //这个函数调用完成后，会把finished重置成正确的值
    getChartList()
})

//下拉加载
function onLoad(){
    if(IsShowCatalog.value) return
    listState.page++
    getChartList()
}

getCatalogList()
getChartList()
</script>

<template>
    <div class="chart-eta-list-wrap">
        <div class="select-wrap">
            <div class="search-box">
                <van-search 
                    shape="round" 
                    readonly 
                    placeholder="请输入图表名称"
                    style="flex:1;padding-left:0"
                    @click-input="$router.push('/chartETA/search')"
                />
                <div class="lang-icon icon" @click="changeLang" v-permission="chartLibBtn.chartLib_switchEn">
                    <img v-if="currentLang==='CN'" src="@/assets/imgs/chartETA/lang-icon.png" alt="">
                    <img v-if="currentLang==='EN'" src="@/assets/imgs/chartETA/langEn-icon.png" alt="">
                </div>
                <div class="list-icon icon" @click="showCatalog">
                    <img src="@/assets/imgs/chartETA/list-icon.png" alt="">
                </div>
            </div>
            <p style="font-weight: bold;word-break: break-all;margin-bottom: 5px;">{{ catalogMenu }}</p>
            <div class="select-box">
                <span>共{{listState.total}}张图表</span>
                <span v-permission="chartLibBtn.chartLib_isOnlyMine"> <van-checkbox v-model="listState.IsShowMe">只看我的</van-checkbox></span>
            </div>
        </div>
        <div class="chart-list-wrap">
            <van-list
                v-model:loading="listState.loading"
                :finished="listState.finished"
                :finished-text="listState.list.length>0?'没有更多了':'暂无图表'"
                :immediate-check="false"
                @load="onLoad"
            >
                <img v-if="listState.list.length==0&&listState.finished" class="list-empty-img" src="https://hzstatic.hzinsights.com/static/ETA_mobile/empty_img.png" alt="">
                <ul class="chart-list">
                    <li 
                        class="chart-list-item" 
                        v-for="item in listState.list" 
                        :key="item.ChartInfoId"
                        @click="goChartDetail(item)"
                    >
                        <div class="title">{{currentLang==='EN'?(item.ChartNameEn||item.ChartName):item.ChartName}}</div>
                        <img class="img" :src="!item.HaveOperaAuth?useNoAuth().noAuthImg:item.ChartImage" alt="">   
                        <div class="time">
                            <span>{{item.CreateTime.slice(0,10)}}</span>
                            <span class="tool-icon" @click.stop="showFileOpt({node:item,optArr:optArrChart})" v-if="authOptArr(item,optArrChart).length&&item.HaveOperaAuth">
                                <img class="icon" src="@/assets/imgs/ppt/ppt_icon_menu.png" alt="">
                            </span>
                        </div>
                    </li>
                </ul>
            </van-list>
        </div>
        <!-- 目录列表 -->
        <van-popup v-model:show="IsShowCatalog" position="right" class="catalog-list-wrap" style="height:100%">
            <div class="catalog-list">
                <div class="top sticky-part">
                    <h3>分类</h3>
                    <van-icon name="cross" @click.stop="IsShowCatalog=false"/>
                </div>
                <!-- 将目录改为三级 -->
                <div class="list-box catalog-tree-wrap">
                    <van-collapse v-model="activeCatalogs" :border="false">
                        <van-collapse-item 
                            v-for="catalog in catalogNodes" :key="catalog.UniqueCode" :name="catalog.UniqueCode"
                            @click.stop="catalogItemClick({item:catalog,type:'top'})">
                            <template #title>
                                <CatalogItem 
                                    :node="catalog" 
                                    :optArr="optArrNode"
                                    :authOptArr="authOptArr"
                                    @showPopup="showFileOpt"/>
                            </template>
                            <CatalogTree 
                                :catalog-nodes="catalog.Children"
                                :showFileOpt="showFileOpt"
                                :activeId="listState.cid"
                                @handleCatalogItemClick="catalogItemClick"
                            />
                        </van-collapse-item>
                    </van-collapse>
                </div>
                <div class="bottom sticky-part" v-if="['rai_admin', 'ficc_admin','admin'].includes(UserInfo.RoleTypeCode)&&checkAuthBtn(chartLibBtn.chartLib_classifyOpt_add)">
                    <span @click.stop="openEditNameDialog({Level:0},{id:'addNew',label:'添加图表分类'})">添加图表分类</span>
                </div>
            </div>
        </van-popup>
        <!-- 操作栏 -->
        <OptionPopup 
            :show-popup="showOptPopup"
            :node="currentNode"
            :optArr="currentOptArr"
            :showFileOptClick="showFileOptClick"
            @close="showOptPopup=false"
        />
        <!-- 添加/重命名一二级分类 弹窗 -->
        <van-dialog 
            v-model:show="editNameState.isShowDialog" 
            :title="editNameState.title" 
            show-cancel-button
            confirmButtonText="确定"
            @confirm="handleConfirmEditClassify"
            :before-close="handleAddClassifyBeforeClose"
        >
            <div class="rename-wrap">
                <!-- <div class="label" v-if="editNameState.Level>1||editNameState.type==='addNext'">一级目录：{{editNameState.parentName}}</div> -->
                <template v-if="editNameState.Level>1||editNameState.type==='addNext'">
                    <div class="label" v-for="(name,index) in editNameState.parentNames" :key="index">{{index+1===1?'一':'二'}}级目录：{{name}}</div>
                </template>
                <input type="text" placeholder="请输入分类名称" v-model="editNameState.ChartClassifyName">
            </div>
        </van-dialog>
        <!-- 移动二级分类 弹窗-->
        <van-popup 
            v-model:show="moveClassState.isShowPickerPop" round :position="width>650?'center':'bottom'" class="move-popup">
            <van-picker
                title="移动至"
                :columns="catalogNodes"
                :columns-field-names="{text:'ChartClassifyName',value:'ChartClassifyId'}"
                @confirm="handleMoveClassify"
                @cancel="closeMoveDialog"
            />
        </van-popup>
        <!-- 移动三级分类 弹窗 -->
        <TreeSelectPop 
            :isShowDialog="moveClassState.isShowTreePop"
            popTitle="移动至"
            renderType="catalog"
            :catalogNodes="catalogNodes"
            :chartInfo="moveClassState"
            :dialogPosition="width>650?'center':'bottom'"
            @close="closeMoveDialog"
            @confirmMove="(id)=>{moveClassState.ParentClassifyId=id;moveClassify()}"
        />
        <!-- 加入我的图库 弹窗 -->
        <AddChartToMyETA 
            :isShowDialog="addChartState.isShowDialog"
            :chartInfo="addChartState.chartInfo"
            :dialogPosition="width>650?'center':'bottom'"
            @close="addChartState.isShowDialog=false"
        />
        <!-- 移动/另存为图表 弹窗 -->
        <TreeSelectPop 
            :isShowDialog="moveChartState.isShowDialog"
            :popTitle="moveChartState.popTitle"
            :catalogNodes="moveChartState.catalogNodes"
            :chartInfo="moveChartState.chartInfo"
            :dialogPosition="width>650?'center':'bottom'"
            @close="moveChartState.isShowDialog=false"
            @confirmMove="MoveChart"
        />
    </div>
</template>
<style lang="scss">
.chart-eta-list-wrap{
    .catalog-list-wrap{
        width: 65%;
    }
    .rename-wrap{
        padding:48px;
        input{
            padding: 24px 32px;
            border-radius: 12px;
            background-color: #F6F6F6;
            width: 100%;
        }
        .label{
            color: #666666;
            margin-bottom: 32px;
            text-align: center;
        }
    }
    @media screen and (min-width:$media-width){
        .catalog-list-wrap{
            width: 30%;
        }
        .move-popup{
            width:375px;
        }
        .rename-wrap{
            padding:24px;
            input{
                padding: 12px 16px;
                border-radius: 6px;
                background-color: #F6F6F6;
                width: 100%;
            }
            .label{
                margin-bottom: 16px;
            }
        }
    }
}
</style>
<style scoped lang="scss">
.chart-eta-list-wrap{
    .select-wrap{
        padding: 30px;
        position: sticky;
        top:0;
        background-color: #fff;
        .search-box{
            display: flex;
            align-items: center;
            .icon{
                margin-left: 10px;
                width: 70px;
                height:70px;
                background-color: #F2F3FF;
                border-radius: 50%;
                display: flex;
                align-items: center;
                justify-content: center;
                img{
                    width:45px;
                    height:45px;
                }
            }
        }
        .select-box{
            display: flex;
            justify-content: space-between;
            flex-wrap: wrap;
        }
    }
    .chart-list-wrap{
        //margin-top:15px;
        padding: 0 30px; 
        padding-bottom: 30px;
        .chart-list{
            display: flex;
            justify-content: space-between;
            flex-wrap: wrap;
            gap: 30px 0;
            .chart-list-item{
                box-sizing: border-box;
                width: 330px;
                padding: 10px 14px;
                border: 1px solid $border-color;
                border-radius: 12px;
                .title{
                    min-height: 70px;
                    overflow: hidden;
                    -webkit-line-clamp: 2;
                    text-overflow: ellipsis;
                    display:-webkit-box !important;
                    -webkit-box-orient:vertical;
                    word-break: break-word;
                }
                .img{
                        width: 100%;
                        height: 220px;
                        display: block;
                        margin: 10px 0;
                    }
                .time{
                    display: flex;
                    justify-content: space-between;
                    font-size: 28px;
                    color: $font-grey_999;
                    .tool-icon{
                        width:30px;
                        text-align: right;
                        img{
                            width:5px;
                        }
                    }
                }
                
            }
        }
    }
    .catalog-list{
        box-sizing: border-box;
        height: 100%;
        .sticky-part{
            position:sticky;
            background-color: white;
            z-index: 99;
            left:0;
            right:0;
        }
        .top{
            display: flex;
            justify-content: space-between;
            border-bottom: 1px solid #DCDFE6;
            padding: 0 15px;
            align-items: center;
            top:0;
        }
        .bottom{
            display: flex;
            padding:48px;
            bottom:0;
            span{
                flex: 1;
                background-color: #0052D9;
                color: white;
                text-align: center;
                border-radius: 6px;
                padding:16px;
                box-sizing: border-box;
            }
        }
    }

    @media screen and (min-width:$media-width){
        .select-wrap{
            top:60px;
            padding:30px;
            .search-box{
                .icon{
                    margin-left: 10px;
                    width: 40px;
                    height:40px;
                    background-color: #F2F3FF;
                    border-radius: 50%;
                    img{
                        width:25px;
                        height:25px;
                    }
                }
            }
            .select-box{
                margin-top:20px;
            }
        }
        .chart-list-wrap{
            padding:0 30px;
            .chart-list{
                gap: 20px 4%;
                justify-content:flex-start;
                .chart-list-item{
                    box-sizing: border-box;
                    width: 22%;
                    padding: 10px 14px;
                    border: 1px solid $border-color;
                    border-radius: 6px;
                    .title{
                        min-height: 36px;
                    }
                    .img{
                        width: 100%;
                        height: auto;
                        display: block;
                        margin: 10px 0;
                    }
                    .time{
                        font-size: 14px;
                        .tool-icon>img{
                            width:3px;
                        }
                    }
                }
            }
        }
        .catalog-list{
            .bottom{
                display: flex;
                padding:24px;
                bottom:0;
                span{
                    flex: 1;
                    background-color: #0052D9;
                    color: white;
                    text-align: center;
                    border-radius: 6px;
                    padding:8px;
                    box-sizing: border-box;
                }
            }
        }
    }
}
</style>
