<template>
    <div>
        <el-dialog v-model="dialogVisible" title="装置端子关系配置" width="60%" @close="handleClose"
            :close-on-click-modal="false">
            <div class="masBox" v-loading="pastLoading">
                <div class="leftBox">
                    <h1 style="
                    border-bottom: 1px solid #7484AB;
                    width: 73%;
                    margin: 25px auto;
                    padding-bottom: 10px;
                    ">{{ startTxt }}</h1>
                    <div style="height: auto;">
                        <div style="margin-bottom: 10px;" v-for="(item, index) in curList"
                            @click="setIndex(item, index)">
                            <span :class="index == leftIndex ? 'result' : 'anther'">{{ index + 1 }}</span>
                            <span :class="index == leftIndex ? 'results' : 'anthers'" :id="item.id">{{ item.fcda_name
                                }}</span>
                        </div>
                    </div>
                </div>
                <div class="middleBox">
                    <p class="background" :style="{ 'background-image': `url(${setBackground})`, 'color': setColor }">{{
            setGooseOrSv }}</p>
                </div>
                <div class="rightBox" v-loading="loading">
                    <h1 style="
                    border-bottom: 1px solid #7484AB;
                    width: 73%;
                    margin: 25px auto;
                    padding-bottom: 10px;
                    ">{{ endTxt }}</h1>
                    <div style="height: auto;">
                        <div v-for="(item, index) in outList">
                            <el-checkbox-group v-model="checkList" @change="checkChange(item)">
                                <el-checkbox :id="item.id" :label="item.id" :key="item.id">
                                    {{ item.fcda_name }}
                                </el-checkbox>
                            </el-checkbox-group>
                        </div>
                        <!-- <div style="margin-bottom: 10px;" v-for="(item, index) in outList" :id="item.id" class="anthers">
                            <el-radio-group v-if="item.from_ied_type==''" v-model="checkList" @change="checkChange">
                                <el-radio :label="item.id" :key="item.id"> {{ item.fcda_name }}</el-radio>
                            </el-radio-group>
                            <span v-else >{{ item.fcda_name }}</span>
                        </div> -->
                    </div>
                </div>
                <div id="wrapper"></div>
            </div>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="cancels">取消</el-button>
                    <el-button type="primary" @click="sureClick">确定</el-button>
                </span>
            </template>
        </el-dialog>
        <SureCancel v-if="sureModal" :showCaptionText="fcdaRelationDlgTitle" :sureModal="sureModal" :reload="reload" :checkObj="checkObj" @cancelBack="cancelBack"></SureCancel>
    </div>
</template>

<script>
import { ref, onMounted, watch, toRefs, computed, onBeforeUnmount } from 'vue';
import flow from '@/api/flow/flow';
import { ElMessage } from 'element-plus';
import LeaderLine from "../../../../public/leader-line.min.js";
import SureCancel from './SureCancel.vue';
export default {
    props: {
        ldModal: {
            type: Boolean,
            required: true,
        },
        startTarget: {
            type: Object,
            required: true
        },//开始数据
        endTarget: {
            type: Object,
            required: true,
        },//结尾数据
        modelId: {
            type: String,
            required: true,
        },//模型id
        numCase: {
            type: Number,
            required: true
        },//用于判断goose还是sv，0为sv，1为goose
        startText: {
            type: String,
            required: true
        },//开始节点文本
        endText: {
            type: String,
            required: true
        },//结束文本
        lineType: {
            type: String,
            required: true
        },//用于判断goose还是sv
    },
    setup(props, { emit }) {
        let dialogVisible = ref(false)//模态框开关
        let starts = ref({})//开始装置数据
        let ends = ref({})//结束装置数据
        let modelIds = ref("")//本组件的模型id
        let startTxt = ref("")//本组件开始文本
        let endTxt = ref("")//本组件结束文本
        let curList = ref([])//箭头开始list
        let outList = ref([])//箭头结束list
        let numStatus = ref(0)//判断goose还是sv
        let visibleItems = ref([])//选择的数组
        let fcdaIds = ref("")//需要的fcda_ids
        let leftIndex = ref(-1)//左侧选择的输出下标
        let leftFcda = ref("")//左侧的fcdaid
        let together = ref("")//绑定的id
        let oldCheckList=ref([])//存储最后一次操作后，已选中的目标装置端子列表数据。用于与checklist对比，已判断当前是取消关联还是建立关联
        let checkList = ref([])//当前已选中的目标装置端子列表数据
        let loading = ref(false)
        let arrNew = ref([])//新的存储fdcdids
        let gv = ref('')
        let pastLoading = ref(false)
        let sureModal = ref(false)//SureCancel.vue组件展示开关
        let leaderLineList = ref({})//组件leader-line数据，以方便离开组件时清除画线
        let checkObj = ref({})//选择的对象
        let fcdaRelationDlgTitle = ref('')
        watch(() => props.modelId, (newVal) => {
            modelIds.value = newVal
        })
        watch(() => props.startText, (newVal) => {
            startTxt.value = newVal
        })
        watch(() => props.endText, (newVal) => {
            endTxt.value = newVal
        })
        watch(() => props.numCase, (newVal) => {
            numStatus.value = newVal
        })
        watch(() => props.lineType, (newVal) => {
            gv.value = newVal
        })
        // 初始化函数
        async function reload() {
            checkList.value=[]
            oldCheckList.value=[]
            pastLoading.value = true
            dialogVisible.value = props.ldModal
            modelIds.value = props.modelId
            starts.value = props.startTarget
            ends.value = props.endTarget
            if(props.startText==null || props.startText==''){
                startTxt.value = starts.value.ied_type
            }else{
                startTxt.value = props.startText
            }
            if(props.endText==null || props.endText==''){
                endTxt.value = ends.value.ied_type
            }else{
                endTxt.value = props.endText
            }
            numStatus.value = props.numCase
            gv.value = props.lineType
            await flow.getModelAndIed({
                model_id: modelIds.value - 0,
                ied_type: starts.value.ied_type,
                sv_or_goose: gv.value,
                in_or_out: "输出",
                ref_ied_type: ends.value.ied_type
            }).then(res => {
                //if ( res.data) {
                //liling:避免提示空错误提示，res.data为空不代表接口有错误，所以先判断接口code值
                pastLoading.value = false
                if (res.code == 0) {
                    if (res.data == null || res.data=="") {
                        curList.value = [];
                        return;
                    }
                    
                    let tmpList = [];
                    //对结果进行重排排序：将已关联到输出装置的端子排在前面
                    res.data.forEach((item, index) => {
                        if (item.to_ied_type == ends.value.ied_type) {
                            tmpList.unshift(item)
                        } else {
                            //未关联的端子按原结果顺序排列
                            tmpList.push(item)
                        }
                    })
                    
                    curList.value = tmpList
                    //pastLoading.value = false
                } else {
                    ElMessage({
                        message: res.msg,
                        type: "error"
                    })
                }
            })
            await flow.getModelAndIed({
                model_id: modelIds.value - 0,
                ied_type: ends.value.ied_type,
                sv_or_goose: gv.value,
                in_or_out: "接收",
                ref_ied_type: starts.value.ied_type
            }).then(res => {
                //if ( res.data) {
                //liling:避免提示空错误提示，res.data为空不代表接口有错误，所以先判断接口code值
                if (res.code == 0) {
                    if (res.data == null || res.data=="") {
                        outList.value = [];
                        return;
                    }                    
                    //对结果进行重排排序：将已关联到输出装置的端子排在前面
                    let tmpList = [];
                    res.data.forEach((item, index) => {
                        if (item.from_ied_type == starts.value.ied_type) {
                            tmpList.unshift(item)
                        } else {
                            //未关联的端子按原结果顺序排列
                            tmpList.push(item)
                        }
                    })
                    
                    outList.value = tmpList;
                    setIndex()
                    // 将 setTimeout 移动到 then 方法中
                    setTimeout(() => {
                        res.data.forEach((item, index) => {

                            let line = {
                                start: item.from_fcda_id,
                                end: item.id
                            };
                            let starts = document.getElementById(line.start);
                            let ends = document.getElementById(line.end).parentNode;
                            // console.log(starts, ends, '??????');
                            // 检查 starts 和 ends 是否存在
                            if (starts && ends) {
                                /*
                                leaderLineList.value.push();
                                */
                               const key=line.start+','+line.end
                               leaderLineList.value[key] = new LeaderLine(starts, ends, {
                                    color: "#ccc",
                                    size: 2,
                                    path: "straight",
                                    startSocket: "right",
                                    endSocket: "left",
                                    endPlug: 'arrow3',
                                    endPlugSize: 2
                                })
                                hiddenLine();
                                pastLoading.value = false
                            } else {
                                //console.error(`Element with ID ${line.start} or ${line.end} not found.`);
                            }
                        });
                    }, 100);
                } else {
                    ElMessage({
                        message: res.msg,
                        type: "error"
                    });
                }
            });
            curList.value.sort((obj1, obj2) => {
                if (outList.value[0] == null) return 1;
                const nameB = outList.value[0].fcda_name;
                if (obj1.fcda_name === nameB) return -1; // 将 name 与数组 b 中第一个对象的 name 属性相等的对象移到数组的第一位
                if (obj2.fcda_name === nameB) return 1;
                return 0;
            });
        }
        // 关闭模态框
        function closeModal() {
            removeLine3()
            dialogVisible.value = false
            emit("lineBack", dialogVisible.value)
        }
        // 确认关闭模态框
        function sureClose() {
            dialogVisible.value = false
            removeLine3()
        }
        // 返回goose还是sv
        const setGooseOrSv = computed(() => {
            if (gv.value == "SV") {
                return "SV"
            } else if (gv.value == "GOOSE") {
                return "GOOSE"
            }
        })
        // 返回图片
        const setBackground = computed(() => {
            if (gv.value == "SV") {
                return require("../../../assets/image/sv_orange.png")
            } else if (gv.value == "GOOSE") {
                return require("../../../assets/image/goose_blue.png")
            }
        })
        // 返回文字颜色
        const setColor = computed(() => {
            if (gv.value == "SV") {
                return 'orange'
            } else if (gv.value == "GOOSE") {
                return 'blue'
            }
        })
        // 下标选择
        function setIndex(row, num) {
            if (row && num) {
                leftFcda.value = row.id
                // checkList.value = [row.to_fcda_id]
                fcdaIds.value = row.to_fcda_id
                leftIndex.value = num
            } else {      
                if (curList.value.length > 0) {
                    curList.value.map(item => {
                        if (item.to_fcda_id != '0' && item.to_fcda_id != '') {
                            console.log(item)
                            checkList.value.push(item.to_fcda_id)
                        }
                    })
                    oldCheckList.value = checkList.value
                    leftFcda.value = curList.value[0].id
                    // checkList.value = [curList.value[0].to_fcda_id]
                    fcdaIds.value = curList.value[0].to_fcda_id
                    leftIndex.value = 0
                } else {
                    ElMessage({
                        type: "info",
                        message: "您还没有配置装置端子"
                    })
                    loading.value = false
                }
            }
        }
        function checkChange(e) {
            checkObj.value = e
            //const subItem = oldCheckList.value.filter(item => !checkList.value.includes(item)); //是否取消选择，取差集
            const addItem = checkList.value.filter(item => !oldCheckList.value.includes(item)); //是否新选择的，取差集
            let no = false
            let hintTxt = ''
            if(addItem.length>0){
                //判断是否选择源端子以及是否未关联任何其他端子，否则不允许关联                
                if(leftFcda.value==''){
                    hintTxt = "请选择关联的源(左侧)端子！"
                    no=true                    
                }
                if(fcdaIds.value!='' && fcdaIds.value!='0'){
                    //源端子已有关联
                    hintTxt = "选择源(左侧)端子已有关联，请先取消关联或选择其它端子！"
                    no=true
                }              
                fcdaRelationDlgTitle.value = "确定在当前2个端子间建立关联关系？"
            }
            if(no){
                    ElMessage({
                        type: "info",
                        message: hintTxt
                    })
                    //恢复未选状态
                    let ind = checkList.value.indexOf(addItem[0])
                    checkList.value.splice(ind,1)
                    return
            }
            sureModal.value = true
        }
        //弹窗打开后使得线条在指定区域中
        function hiddenLine() {
            const elmWrapper = document.getElementById("wrapper");
            // 移动 line
            document.body.querySelectorAll("body .leader-line").forEach((node) => {
                elmWrapper.appendChild(node);
            });
            elmWrapper.style.transform = "none";
            var rectWrapper = elmWrapper.getBoundingClientRect();
            // Move to the origin of coordinates as the document
            elmWrapper.style.transform = `translate(${(rectWrapper.left + window.scrollY) * -1
                }px, ${(rectWrapper.top + window.scrollX) * -1}px)`;
        };
        // 稳定leader-line函数
        function removeLine3() {
            leaderLineList.value = {};
            const elmWrapper = document.getElementById("wrapper");
            if (elmWrapper) {
                document.body.querySelectorAll("#wrapper .leader-line").forEach((node) => {
                    elmWrapper.removeChild(node);
                });
            }
        };
        //取消端子关联确认框返回事件处理
        function cancelBack(data){
            // 本事件处理选择框
            sureModal.value = false
            const subItem = oldCheckList.value.filter(item => !checkList.value.includes(item)); //是否取消选择，取差集
            const addItem = checkList.value.filter(item => !oldCheckList.value.includes(item)); //是否新选择的，取差集
            if(!data.ok){
                if(subItem.length>0){
                    //恢复选中状态
                    checkList.value.push(subItem[0])
                }
                if(addItem.length>0){
                    //恢复未选状态
                    let ind = checkList.value.indexOf(addItem[0])
                    checkList.value.splice(ind,1)
                }
                return
            }
            fcdaIds.value = checkObj.value.id
            if(subItem.length>0){
                flow.delModelFcdaOn({
                    model_id: modelIds.value - 0,
                    from_fcda_id :checkObj.value.from_fcda_id - 0,
                    to_fcda_id :fcdaIds.value
                }).then(res=>{
                    if (res.code == 0) {
                        ElMessage({
                            type: "success",
                            message: "操作成功！"
                        })
                        reload()                        
                        removeLine3()
                        emit("lineBack", dialogVisible.value)
                    } else {
                        ElMessage({
                            type: "error",
                            message: res.msg
                        })
                    }
                }).catch(res=>{
                    ElMessage({
                        type: "error",
                        message: '服务器发生异常'
                    })
                })
            }
            if(addItem.length>0){
                flow.saveModelOn({
                    model_id: modelIds.value - 0,
                    from_ied_type: starts.value.ied_type,
                    to_ied_type: ends.value.ied_type,
                    from_fcda_id: leftFcda.value - 0,
                    to_fcda_ids: fcdaIds.value,
                    goosesv: setGooseOrSv.value,
                }).then(res => {
                    if (res.code == 0) {
                        ElMessage({
                            type: "success",
                            message: "关联成功！"
                        })
                        reload()
                        removeLine3()
                        emit("lineBack", dialogVisible.value)
                    } else {
                        ElMessage({
                            type: "error",
                            message: res.msg
                        })
                    }
                }).catch(res=>{
                    ElMessage({
                        type: "error",
                        message: '服务器发生异常'
                    })
                })
            }
        }
        onMounted(async () => {
            await reload()
        })
        onBeforeUnmount(() => {
            for(let key in leaderLineList.value){
                leaderLineList.value[key].remove();
            }
            //leaderLineList.value.forEach(line => line.remove());//离开当前组件时清除连线
            removeLine3()
        })
        return {
            dialogVisible,//模态框开关
            reload,//初始化函数
            starts,//开始节点数据
            ends,//结束节点数据
            handleClose: closeModal,//关闭模态框
            cancels: closeModal,//关闭模态框
            sureClick: sureClose,//确认关闭模态框
            modelIds,//本组件的模型id
            startTxt,//本组件开始文本
            endTxt,//本组件结束文本
            curList,//渲染list
            setGooseOrSv,//判断显示goose还是sv
            setBackground,//判断显示背景图
            setColor,//判断文字颜色
            visibleItems,//选择的数组
            // toggleVisibility,//模拟多选框方法
            fcdaIds,//需要的fcda_ids
            leftIndex,//左侧下标选择
            setIndex,//下标选择函数
            // getClass,//设置多选span的class函数
            leftFcda,//左侧单选的fcdaid
            outList,//箭头指向端list
            together,//绑定的id
            // isVisible,
            loading,
            checkList,
            checkChange,
            arrNew,//新的存储ids
            gv,
            pastLoading,//maxbox加载动画
            leaderLineList,//组件库leader-line数据，以方便离开组件时清除画线
            hiddenLine,//使leader-line显示在模态框内
            removeLine3,// 稳定leader-line函数
            sureModal,//SureCancel.vue组件展示开关
            cancelBack,//SureCancel.vue返回模态框状态
            checkObj,//选择的对象
            fcdaRelationDlgTitle,
        }
    },
    components:{
        SureCancel,//确认取消关系组件
    }
}
</script>

<style scoped>
.masBox {
    width: 100%;
    height: calc(100vh - 400px);
    /* border: 1px solid red; */
    display: flex;
    justify-content: space-around;
    align-items: center;
    overflow-y: auto;
    position: relative;
}

.leftBox {
    width: 33%;
    /* height: calc(100vh - 420px); */
    text-align: center;
    background-color: #F7F8FB;
    border: 2px dashed #A3ADE0;
    position: absolute;
    top: 2%;
    left: 5%;
}

.middleBox {
    width: 22%;
    height: calc(100vh - 420px);
    display: flex;
    justify-content: space-around;
    align-items: center;
    position: absolute;
    top: 5%;
    left: 39%;
}

.rightBox {
    width: 33%;
    /* height: calc(100vh - 420px); */
    text-align: center;
    background-color: #EDF3FF;
    border: 2px dashed #A3ADE0;
    position: absolute;
    top: 2%;
    right: 5%;
}

.result {
    display: inline-block;
    width: 11%;
    height: 40px;
    border: 1px solid blue;
    text-align: center;
    line-height: 40px;
    background-color: #D9E6FE;
    color: blue;
    margin-right: 10px;
}

.anther {
    display: inline-block;
    width: 11%;
    height: 40px;
    border: 1px solid black;
    text-align: center;
    line-height: 40px;
    background-color: #F5FAFE;
    color: black;
    margin-right: 10px;
}

.results {
    display: inline-block;
    width: 75%;
    height: 40px;
    border: 1px solid blue;
    text-align: left;
    line-height: 40px;
    background-color: #D9E6FE;
    color: blue;
    padding-left: 5px;
}

.anthers {
    display: inline-block;
    width: 75%;
    height: 40px;
    border: 1px solid black;
    text-align: left;
    line-height: 40px;
    background-color: #F5FAFE;
    color: black;
    padding-left: 5px;
}

.background {
    width: 90%;
    height: calc(100vh - 850px);
    /* background-position: 100%; */
    background-repeat: no-repeat;
    background-size: 100%;
    text-align: center;
    background-position: 100% 50%;
    line-height: calc(100vh - 850px);
}

:deep(.el-checkbox__inner) {
    width: 40px !important;
    height: 40px !important;
    background-color: white !important;
}

:deep(.el-checkbox__inner::after) {
    height: 30px !important;
    left: 11px !important;
    width: 15px !important;
    top: -2px !important;
    border-color: #2B5AE5;
}

:deep(.el-checkbox__input.is-checked .el-checkbox__inner::after) {
    border-color: #2B5AE5;
}

:deep(.el-checkbox) {
    width: 300px !important;
    height: 42px !important;
    margin-right: 0 !important;
    margin-bottom: 10px !important;
}

:deep(.el-checkbox__label) {
    width: 202px !important;
    height: 42px !important;
    margin-left: 10px !important;
    line-height: 42px !important;
    text-align: center;
}

.leader-line {
    z-index: 3000;
}

#wrapper {
    width: 0;
    height: 0;
    position: relative;
    /* Origin of coordinates for lines, and scrolled content (i.e. not `absolute`) */
}

:deep(.el-radio__inner) {
    width: 32px;
    height: 32px;
}

:deep(.el-radio__input.is-checked .el-radio__inner::after) {
    width: 15px;
    height: 15px;
}

:deep(.el-radio-group) {
    width: 100%;
    justify-content: space-between;
    margin: 4px;
}
</style>