let video_list = {};    //element_id -- socket
let run_list = {};      //element_id -- runtag(替换berror)
var channel_list = null;
const fourViewButton = document.getElementById('fourView');
const nineViewButton = document.getElementById('nineView');

//页面即将卸载时执行
window.addEventListener('beforeunload', function (event) {
    // 关闭所有 WebSocket 连接或执行其他清理操作
    for(let key in video_list){
        delete run_list[key];
        video_list[key].close();
        delete video_list[key];
    }
});

//页面加载时执行
document.addEventListener('DOMContentLoaded', async function() {
    console.log('DOM fully loaded and parsed');
    // 发送请求获取额外数据 --- 这个接口功能有点大了---暂时只是更新通道树2024-7-29
    try {
            let response = await fetch('/api/channel/list');
            if (!response.ok) {
                throw new Error('Network response was not ok');
            }
            channel_list = await response.json();
            // 遍历输出每个元素的信息
            let area_name = ""
            let html = '<ul class="list-group">';
            channel_list.forEach(channel => {
//                   console.log(`Area Name: ${channel.area_name}`);
//                   console.log(`ID: ${channel.ID}`);
//                   console.log(`Channel Name: ${channel.channel_name}`);
//                   console.log(`URL: ${channel.url}`);
//                   console.log(`Type: ${channel.type}`);
//                   console.log(`Status: ${channel.status}`);
//                   console.log(`Element ID: ${channel.element_id}`);
                if(area_name !== `${channel.area_name}`){
                    if(area_name !== ""){
                        html += '</ul>';
                        html += '</li>';
                    }
                    area_name = `${channel.area_name}`;
                    html += `<li class="list-group-item"><strong>${area_name}</strong>`;
                    html += '<ul class="list-group">';
                }
                //html += `<li class="list-group-item">${channel.channel_name}</li>`;
                html += `<li class="list-group-item" draggable="true" ondragstart="drag(event)"
                data-node-id="${channel.ID}"  data-node-name="${area_name}--${channel.channel_name}">
                            <svg class="bi" width="16" height="16"><use xlink:href="#view"/></svg>
                            ${channel.channel_name}
                         </li>`;
            });
            if(area_name !== ""){
                html += '</ul>';
                html += '</li>';
            }
            html += '</ul>';
            const treeView = document.getElementById('treeView');
            treeView.innerHTML = html
            generateVideoNodes(4);
        } catch (error) {
            console.error('Failed to fetch data:', error);
        }
      });



//视频窗口
document.getElementById('fourView').addEventListener('click', function() {
    if (fourViewButton.classList.contains('btn-primary')) {
        return; // 如果按钮已经是选中状态,直接返回
    }
    const videoGrid = document.getElementById('videoGrid');
    videoGrid.classList.remove('nine');
    videoGrid.classList.add('four');
    generateVideoNodes(4);
    //更新按钮点击状态
    fourViewButton.classList.remove('btn-secondary');
    fourViewButton.classList.add('btn-primary');
    nineViewButton.classList.remove('btn-primary');
    nineViewButton.classList.add('btn-secondary');
});

document.getElementById('nineView').addEventListener('click', function() {
    if (nineViewButton.classList.contains('btn-primary')) {
        return; // 如果按钮已经是选中状态,直接返回
    }
    const videoGrid = document.getElementById('videoGrid');
    videoGrid.classList.remove('four');
    videoGrid.classList.add('nine');
    generateVideoNodes(9);
    //更新按钮点击状态
    fourViewButton.classList.remove('btn-primary');
    fourViewButton.classList.add('btn-secondary');
    nineViewButton.classList.remove('btn-secondary');
    nineViewButton.classList.add('btn-primary');
});

function generateVideoNodes(count) { //在这里显示视频-初始化
    //结束在播放的socket
    for(let key in video_list){
        delete run_list[key];
        video_list[key].close();
        delete video_list[key];
    }
    //切换窗口布局
    const videoGrid = document.getElementById('videoGrid');
    let html = '';
    for (let i = 0; i < count; i++) {
        let frameWidth = count === 4 ? 'calc(50% - 10px)' : 'calc(33.33% - 10px)';
        html += `
        <div class="video-frame" data-frame-id="${i}" style="width: ${frameWidth};"
        ondrop="drop(event)" ondragover="allowDrop(event)">
            <div class="video-header">
                <div class="video-title">Video Stream ${i+1}</div>
                <div class="video-buttons">
                    <button onclick="toggleFullScreen(${i})">🔲</button>
                    <button onclick="closeVideo(${i})">❌</button>
                </div>
            </div>
            <div class="video-area"><img id="video-${i}" alt="Video Stream" /></div>
        </div>`;
    }
    videoGrid.innerHTML = html;
    //获取视频接口
    const url = `/api/viewlist?count=${count}`;
    fetch(url)
    .then(response => response.json())
    .then(data => {
        console.log('Success:', data);
        clist = data.clist;
        elist = data.elist;
        nlist = data.nlist;
        for(let i=0;i<clist.length;i++){
            if(parseInt(elist[i]) < count){
                connectToStream(elist[i],clist[i],nlist[i])
            }
        }
    })
    .catch(error => {
        console.error('Error:', error);
    });
}

function toggleFullScreen(id) {
    console.log('toggleFullScreen');
    const videoFrame = document.querySelector(`[data-frame-id="${id}"]`);
    if (!document.fullscreenElement) {
        videoFrame.requestFullscreen().catch(err => {
            alert(`Error attempting to enable full-screen mode: ${err.message} (${err.name})`);
        });
    } else {
        document.exitFullscreen();
    };
}

function closeVideo(id) {
    const titleElement = document.querySelector(`[data-frame-id="${id}"] .video-title`);
    if (titleElement.textContent === `Video Stream ${Number(id)+1}`) {
        showModal('当前视频窗口未播放视频。');
        return;
    };
    console.log('closeVideo');
    //发送视频链接接口
    const url = '/api/close_stream';
    const data = {"element_id":id};
    // 发送 POST 请求
    fetch(url, {
        method: 'POST', // 指定请求方法为 POST
        headers: {
            'Content-Type': 'application/json' // 设置请求头,告诉服务器请求体的数据类型为 JSON
        },
        body: JSON.stringify(data) // 将 JavaScript 对象转换为 JSON 字符串
    })
    .then(response => response.json()) // 将响应解析为 JSON
    .then(data => {
        console.log('Success:', data);
        const istatus = data.status;
        if(istatus === 0){
            showModal(data.msg); // 使用 Modal 显示消息
            return;
        }
        else{
            const videoFrame = document.querySelector(`[data-frame-id="${id}"] .video-area img`);
            const titleElement = document.querySelector(`[data-frame-id="${id}"] .video-title`);
            run_list[id] = false;
            video_list[id].close();

            videoFrame.src = ''; // 清空画面
            videoFrame.style.display = 'none'; // 停止播放时隐藏 img 元素

            titleElement.textContent = `Video Stream ${id+1}`;
            removeErrorMessage(videoFrame)
        }
    })
    .catch((error) => {
        showModal(`Error: ${error.message}`); // 使用 Modal 显示错误信息
        return;
    });
}

function allowDrop(event) {
    event.preventDefault();
}

function drag(event) {
    event.dataTransfer.setData("text", event.target.dataset.nodeId);
    event.dataTransfer.setData("name", event.target.dataset.nodeName);
}

function drop(event) {
    event.preventDefault();
    const nodeId = event.dataTransfer.getData("text");
    const nodeName = event.dataTransfer.getData("name");
    const frameId = event.currentTarget.dataset.frameId;

    //需要判断下当前窗口是否已经在播放视频
    const imgElement = document.getElementById(`video-${frameId}`);
    const titleElement = document.querySelector(`[data-frame-id="${frameId}"] .video-title`);

    if (titleElement.textContent !== `Video Stream ${Number(frameId)+1}`) {
        showModal('请先关闭当前窗口视频,然后再播放新的视频。');
        return;
    };
    //发送视频链接接口
    const url = '/api/start_stream';
    const data = {"channel_id":nodeId,"element_id":frameId};
    // 发送 POST 请求
    fetch(url, {
        method: 'POST', // 指定请求方法为 POST
        headers: {
            'Content-Type': 'application/json' // 设置请求头,告诉服务器请求体的数据类型为 JSON
        },
        body: JSON.stringify(data) // 将 JavaScript 对象转换为 JSON 字符串
    })
    .then(response => response.json()) // 将响应解析为 JSON
    .then(data => {
        const istatus = data.status;
        if(istatus === 0){
            showModal(data.msg); // 使用 Modal 显示消息
            return;
        }
        else{
            //获取视频流
            connectToStream(frameId,nodeId,nodeName);
        }
    })
    .catch((error) => {
        showModal(`Error: ${error.message}`); // 使用 Modal 显示错误信息
        return;
    });
    //console.log('retrun 只是把fetch结束,这里的代码还是会执行');
}

function connectToStream(element_id,channel_id,channel_name) {
    console.log("开始连接视频",channel_id);
    // 设置视频区域的标题
    const titleElement = document.querySelector(`[data-frame-id="${element_id}"] .video-title`);
    titleElement.textContent = channel_name;
    //获取视频
    const imgElement = document.getElementById(`video-${element_id}`);
    imgElement.alt = `Stream ${channel_name}`;
    const streamUrl = `ws://${window.location.host}/api/ws/video_feed/${channel_id}`;
    let berror = false;

    function connect() {
        const socket = new WebSocket(streamUrl);
        video_list[element_id] = socket;
        run_list[element_id] = true;
        imgElement.style.display = 'block';
        berror_state = false;
         // 处理连接打开事件
        socket.onopen = () => {
            console.log('WebSocket connection established');
        };

        socket.onmessage = function(event) {
            const reader = new FileReader();
            reader.readAsArrayBuffer(event.data);

            reader.onload = () => {
                const arrayBuffer = reader.result;
                const decoder = new TextDecoder("utf-8");
                const decodedData = decoder.decode(arrayBuffer);

                if (decodedData === "video_error") {   //video_error
                    displayErrorMessage(imgElement, "该视频源未获取到画面,请检查,默认每隔2分钟将重新链接视频源。");
                    berror_state  = true;
                } else if(decodedData ===  "client_error"){  //client_error
                    run_list[element_id] = false;
                    displayErrorMessage(imgElement, "该通道节点数据存在问题,请重启或联系技术支持!");
                    socket.close();  // 停止连接
                    berror_state = true;
                }
                else {
                    if(berror_state){
                        removeErrorMessage(imgElement);
                        berror_state = false;
                    }
                    // 释放旧的对象URL
                    if (imgElement.src) {
                        URL.revokeObjectURL(imgElement.src);
                    }
                    //blob = new Blob([arrayBuffer], { type: 'image/jpeg' });
                    imgElement.src = URL.createObjectURL(event.data);
                }
            };

            //图片显示方案二
//            if (imgElement.src) {
//                URL.revokeObjectURL(imgElement.src);
//            }
//            imgElement.src = URL.createObjectURL(event.data);

        };

        socket.onclose = function() {
            if(run_list[element_id]){
                console.log(`尝试重新连接... Channel ID: ${channel_id}`);
                setTimeout(connect, 1000*10);  // 尝试在10秒后重新连接
            }
        };

        socket.onerror = function() {
            console.log(`WebSocket错误,Channel ID: ${channel_id}`);
            socket.close();
        };
    };
    connect();
}

function displayErrorMessage(imgElement, message) {
    removeErrorMessage(imgElement)
    imgElement.style.display = 'none';  // 隐藏图片
    const errorElement = document.createElement('div');
    errorElement.textContent = message;
    errorElement.classList.add('error-message');
    imgElement.parentNode.appendChild(errorElement);
}

function removeErrorMessage(imgElement) {
    const errorElement = imgElement.parentNode.querySelector('.error-message');
    if (errorElement) {
        imgElement.parentNode.removeChild(errorElement);
    }
}