<template>
    <div class="sfcbox">
        <!-- 第一个服务器的文件列表 -->
        <div class="sfcon">
            <div class="sfind">
                <span class="scdesc">源服务器：</span>
                <!-- 选择服务器 -->
                <select class="selbox" name="fsip" ref="fsip" @change="changeSer">
                    <option value="0">请选择源服务器</option>
                    <option v-for="item in uslist" :value="item.addr + ':' + item.port">{{ item.addr + ':' + item.port
                        }}
                    </option>
                </select>
                <input name="path" class="inputbox" type="text" placeholder="/" autocomplete="off" v-model="fspath">
                <button @click="getFlist">Go</button>
                <button @click="goParent">🔙</button>
           
            </div>
            <div class="sflist">
                <form  method="post" ref="fsform">
                <ul>
                    <li v-for="(item, index) in fsclist" :key="item" :data-index="index" :id="'fs_'+rc32(item.path)" :class="{'diff': item.path in diffFiles}">
                        <input type="checkbox" :value="item.path" class="sfchkbox" :name="'fsbox' + index" :ref="'fsbox' + index"/>
                        <a class="haschild" @click="goIntoDir(item.path, 1)" v-if="item.isdir"><i></i>{{ item.path }}</a>
                        <span v-else><i :class="'tb tb-'+item.suffix"></i>{{ item.path }}</span>
                    </li>
                    
                </ul>
                <div class="fbdiv" v-if="fsclist.length > 0">
                    <input type="hidden" name="curpath" :value="fspath" />
                    <!-- <button class="fbtn">同步选中的文件</button> -->
                </div>
                </form>
            </div>

            <div class="tips">
                <span v-if="fsclist.length > 0"> 服务器：{{ this.$refs.fsip.value }} 路径：{{ fspath }} ,文件数量：{{ fsclist.length
                    }}</span>
                <span v-else>当前服务器：{{ fsip }}</span>
            </div>
        </div>
        <!-- 第二个服务器的文件列表 -->
        <div class="sfcon">
            <div class="sfind">
                <span class="scdesc">目标服务器：</span>
                <!-- 选择服务器 -->
                <select class="selbox" name="ssip" ref="ssip">
                    <option value="0">请选择目标服务器</option>
                    <option v-for="item in uslist" :value="item.addr + ':' + item.port">{{ item.addr + ':' + item.port}}</option>
                </select>
                <input name="path" class="inputbox" type="text" placeholder="/" autocomplete="off" v-model="sspath">
                <button @click="getSflist">GO</button>
                <button @click="goParent">🔙</button>

            </div>

            <div class="sflist">
                <ul>
                    <li v-for="item in ssclist" :key="item" :data-index="index">
                        <input type="checkbox" :value="item.path" class="sfchkbox" :name="'ssbox' + index" :ref="'fsbox' + index"/>
                        <a class="haschild" @click="goIntoDir(item.path, 2)" v-if="item.isdir "><i></i>{{ item.path }}</a>
                        <span v-else><i :class="'tb tb-'+item.suffix"></i>{{ item.path }}</span>
                    </li>

                </ul>
            </div>

            <div class="tips">
                <span v-if="ssclist.length > 0">服务器：{{ this.$refs.fsip.value }} 路径：{{ sspath }} ,文件数量：{{ ssclist.length }}</span>
                <span v-else>当前服务器：{{ ssip }}</span>
            </div>
        </div>

        <!-- 右键菜单 -->
        <div class="sftrans" v-if="isMenuVisible" @contextmenu.prevent
            :style="{ top: menuTop + 'px', left: menuLeft + 'px' }">
            <ul class="sfbcon">
                <li><span href="javascript:void(0)" @click="handleMenuAction('upload')">同步文件</span></li>
                <li><span href="javascript:void(0)" @click="handleMenuAction('download')">压缩下载</span></li>
                <li class="divider"></li>
                <li><span href="javascript:void(0)" @click="handleMenuAction('delete')">删除文件</span></li>
            </ul>
        </div>

        <!-- 待发送文件 -->
         <div class="fsend" v-if="hasTwolist">
            <div class="fsendcon">
                <!-- 暂未想好放啥 -->
                 <button class="fbtn" @click="submitForm">同步选中的文件</button>
            </div>

         </div>

         <!-- 弹框提示 -->
          <div class="dialog" v-if="dialogShow">
            <div class="alert alert-success">
                同步成功！
            </div>
          </div>



    </div>
</template>

<script>
import { GetFileList, SerlistInUsing,SendZipFile } from '@/api/scinfo'

export default {
    name: 'Sfilecompare',
    data() {
        return {
            fsip: '',
            ssip: '',
            fsclist: {}, // 第一台文件列表
            ssclist: {}, // 第二台文件列表
            uslist: [], //使用中的服务器
            fspath: '/', // 第一个服务器的路径
            sspath: '/', // 第二个服务器的路径

            chkfiles: [], // 选中的文件
            selectedFiles: [], // 选中的文件

            isMenuVisible: false,  // 菜单是否可见
            menuTop: 0,            // 菜单顶部位置
            menuLeft: 0,          // 菜单左侧位置
            dialogShow: false, // 对话框是否可见
            isShowDir: false, // 只显示目录
            hasTwolist: false, // 是否有两个服务器的文件列表

            diffFiles: [], // 差异文件
        }
    },
    mounted() {
        // 点击文档其他区域隐藏菜单
        document.addEventListener('click', (event) => {
            //避免快速点击时的冲突
            if (this.isMenuVisible) {
                this.hideMenu()
            }
        })
        // 使用中的服务器
        SerlistInUsing().then(res => {
            this.uslist = res.data;
        })

    },
    beforeMount() {
        // 移除事件监听
        document.removeEventListener('click', this.hideMenu);
    },
    methods: {

        // 获取第一个服务器的文件列表
        getFlist() {
            // 获取第一个服务器
            let fsip = this.$refs.fsip.value
            let sstr = fsip.split(":")
            let sport = sstr[1]
            let scip = btoa(sstr[0])
            // 获取文件列表
            GetFileList({ srcip: scip, path: this.fspath, sport: sport }).then(res => {
                this.fsclist = res.data.list
            })
        },
        // 获取第二个服务器的文件列表
        getSflist() {
            let ssip = this.$refs.ssip.value
            let sstr = ssip.split(":")
            let sport = sstr[1]
            let scip = btoa(sstr[0])
            // 获取文件列表
            GetFileList({ srcip: scip, path: this.sspath, sport: sport }).then(res => {
                this.ssclist = res.data.list
            })
            // 3s 后执行对比
            setTimeout(() => {
                this.diffFlist()
            }, 3000)

            // 如果存在第一条
            if (this.fsclist.length > 0  && this.ssclist.length > 0) {
                this.hasTwolist=true
            }
  
        },
        // 对比web端文件列表
        diffFlist(){
            let alist = this.fsclist;
            let blist = this.ssclist;
            // 对比alist 与 blist 的差异
            let diff = [...alist].filter(item =>
                !blist.some(i => 
                    // i.hash == item.hash
                    i.path == item.path
                )
            )
            // diff 转为一维数组
            // diff = diff.flatMap(item => item.hash)
            diff = diff.map(item => item.path)
            // 
            this.diffFiles = diff
        },
        // 计算rc32的结果,剔除负数的情况
        rc32(str) {
            // 转换为utf-8编码
            str = encodeURIComponent(str)
            let rc = 0xffff
            for (let i = 0; i < str.length; i++) {
                rc = (rc << 5) + rc + str.charCodeAt(i)
                // 使用掩码确保结果为非负数
                rc = rc & 0x7FFFFFFF
            }
            return rc
        },
        // 对比两个list
        compareList(){
            let alist = this.fsclist;
            let blist = this.ssclist;
            
            // 对比alist 与 blist 的差异
            let diff = [...alist].filter(item =>
                !blist.some(i => 
                    // i.hash == item.hash
                    i.path == item.path
                )
            )
            // diff 转为一维数组
            // diff = diff.flatMap(item => item.hash)
            diff = diff.map(item => item.path)
            // 
            this.diffFiles = diff
        },
        // 进入子目录
        goIntoDir(path, nflag) {
            // 根据nflag 来判断
            let npath, sel
            if (nflag == 1) {
                sel = this.$refs.fsip.value
                // 拼装url
                if (this.fspath == '/') {
                    npath = '/' + path
                } else {
                    npath = this.fspath + '/' + path
                }
            }
            if (nflag == 2) {
                sel = this.$refs.ssip.value

                if (this.sspath == path) {
                    this.sspath = '/'
                }
                if (this.sspath == '/') {
                    npath = '/' + path
                } else {
                    npath = this.sspath + '/' + path
                }
            }
            let rrarr = this.preIp(sel)
            // ip转为base64
            let ip = btoa(rrarr[0])
            this.queryFlist(ip, rrarr[1], npath, nflag)
        },
        // 查询内容
        // nflag 1 第一个服务器 2 第二个服务器
        async queryFlist(ip, port, npath, nflag) {
            let rlist = []
            await GetFileList({
                srcip: ip, path: npath, sport: port
            }).then(res => {
                var vlist = res.data.list
                if (vlist) {
                    // 绑定数据
                    if (nflag == 1) {
                        this.fspath = npath
                        this.fsclist = vlist
                    }
                    if (nflag == 2) {
                        this.sspath = npath
                        this.ssclist = vlist
                    }
                } else {
                    npath = "/"
                }

            })
            return rlist;
        },
        // 拆分组装ip
        preIp(ssip) {
            // 返回数组
            let iparr = []
            let sstr = ssip.split(":")
            iparr.push(sstr[0])
            iparr.push(sstr[1])
            return iparr
        },
        // 选择服务器
        changeSer() {
            // 清空路径
            this.fspath = '/'
            this.sspath = '/'
        },

        // 上一级目录
        // 移除最后一个文件
        goParent() {
            // 第一个服务器
            if (this.fspath != '/') {
                let npath = this.fspath.split('/')
                // 弹出最后一个元素
                npath.pop()
                this.fspath = npath.join('/')
                // 调用方法
                this.getFlist()
            }
            // 第二个服务器
            if (this.sspath != '/') {
                let npath = this.sspath.split('/')
                npath.pop()
                this.sspath = npath.join('/')
                // 调用方法
                this.getSflist()
            }
        },
        // 右键菜单内容
        showMenu(event) {
            // 计算菜单位置（基于点击坐标）
            this.menuTop = event.clientY;
            this.menuLeft = event.clientX;

            // 确保菜单不会超出视口
            this.adjustMenuPosition();
            // 显示菜单
            this.isMenuVisible = true;
            // 获取到当前行的索引值
            let index = event.target.dataset.index
            // 对应的box 也要选中
            let chkbox = document.getElementsByName('fsbox' + index)
            chkbox[0].checked = true
            console.log(chkbox,"chkbox")
            // 第二个服务器
            // let schkbox = document.getElementsByName('ssbox'+index)
            // schkbox[0].checked = true
        },
        // 隐藏右键菜单
        hideMenu() {
            this.isMenuVisible = false;
        },
        // 调整菜单位置，避免超出视口
        adjustMenuPosition() {
            const menuWidth = 200;  // 菜单宽度（px）
            const menuHeight = 160; // 菜单高度（px）

            // 右侧超出视口时向左调整
            if (this.menuLeft + menuWidth > window.innerWidth) {
                this.menuLeft = window.innerWidth - menuWidth;
            }

            // 底部超出视口时向上调整
            if (this.menuTop + menuHeight > window.innerHeight) {
                this.menuTop = window.innerHeight - menuHeight;
            }
        },

        // 处理菜单操作
        handleMenuAction(action) {
            console.log(`执行操作: ${action}`);
            switch(action){
                case 'upload':
                    this.uploadFile()
                    break;
            }
            // 这里可以添加具体的业务逻辑
            this.hideMenu(); // 执行完操作后隐藏菜单
        },
        // 提交表单
        submitForm(){
            // checkbox选中的数值
            let chkbox = document.getElementsByClassName('sfchkbox')
            
            for(let i=0;i<chkbox.length;i++){
                if(chkbox[i].checked){
                    // 加上当前的路径
                    let rv = chkbox[i].value
                    this.selectedFiles.push(rv)
                }
            }
            // build to string
            // let srt = this.selectedFiles.join(',')
    
            // 当前路径
            let curpath = this.fspath

            // 提交post请求
            let data = {
                sfiles: this.selectedFiles,
                serverip: this.$refs.fsip.value,
                curpath: curpath,
                remoteaddr: this.$refs.ssip.value,
                remotepath: this.sspath,
            }
            // build to schema
            const pdata = new URLSearchParams(data)
            //
            SendZipFile(pdata).then(res=>{ 
                console.log(res,"res")
                // alert(res.status)
                if(res.status == "200"){
                    // 显示对话框
                    this.dialogShow = true
                    // 3s后隐藏
                    setTimeout(() => {
                        this.dialogShow = false
                    }, 3000);
                    
                    // 第二台服务器列表更新
                    this.getSflist()
                }

                // alert(res.data.reply)
                // 清空数组
                this.selectedFiles = []
                // 清空pdata
                pdata.forEach((value, key) => {
                    pdata.delete(key)
                })
            })
            return
        },

        // 更新文件
        uploadFile(e){
            // 
            console.log(e,"upload")

            // itname.checked = true
            // let chkbox =document.getElementsByName('ssbox'+index)
        }

    }
}
</script>

<style scoped>
    @import url('@/assets/sfilecompare.css');
</style>