/**
 * socket入口脚本文件
 *
 * @author caiaolin
 * @date 2017-05-12
 * @version
 */
import socket from "socket.io";
const moment = require('moment');
const { PageTarget } = require('./public/common_constants');

const socketIO = socket(5500);

const userCache = {};

function getEditingUsers(projectID) {
    const users = userCache[projectID];
    if (!users) {
        return [];
    }
    const rst = [];
    const existMap = {};
    for (const user of users) {
        if (existMap[user._id]) {
            continue;
        }
        existMap[user._id] = true;
        rst.push(user);
    }
    return rst;
}

// socket.io相关操作
socketIO.on('connection', function(socket) {
    let roomInfo = {};
    let curUser;
    let curProjectID;
    console.log("new connection");
    // 加入房间
    socket.on('join', function(data) {
        const { roomData, payload } = data;
        if (payload && payload.user) {
            curUser = payload.user;
        }
        if (roomData) {
            if (roomData.projectID) {
                curProjectID = roomData.projectID;
                if (!userCache[roomData.projectID]) {
                    userCache[roomData.projectID] = [];
                }
                // 由于用户可以重复打开项目，因此不做唯一性处理
                userCache[roomData.projectID].push(curUser);
            }
            for(let key in roomData){
                roomInfo[key] = roomData[key];
                socket.join(roomData[key], () => {
                    if (key === 'projectID') {
                        const editingUsers = getEditingUsers(curProjectID);
                        if (editingUsers.length > 1) { // 只有一个用户数据，说明只有用户自己打开项目，不需要推送数据，减少触发。
                            socket.broadcast.to(roomInfo.projectID).emit('handleAvatarList', {editingUsers});
                            socket.emit('handleAvatarList', {editingUsers});
                        }
                    }
                });
            }
        }
    });
    // 数据更改通知
    socket.on('unitFileChangeNotify', function(data) {
        socket.broadcast.to(roomInfo['unitFile']).emit('unitFileChange', data);
        if(data.userID) socket.broadcast.to(data.userID).emit('fileDataChange', data);
    });
    socket.on('feeRateChangeNotify', function(data) {
        socket.broadcast.to(roomInfo['feeRate']).emit('feeRateChange', data);
        if(data.userID) socket.broadcast.to(data.userID).emit('fileDataChange', data);
    });
    socket.on('changeNewRoom', function(data) {
        if(data.projectID){//如果有项目ID，则通知同一个项目在其它地方被打开的页面
            socket.broadcast.to(data.oldRoom).emit('changeFileNotify', data);
            if(data.userID) socket.broadcast.to(data.userID).emit('fileDataChange', data);

        }
        socket.leave(data.oldRoom);
        socket.join(data.newRoom);
        roomInfo[data.name]=data.newRoom;
    });
    socket.on('removeProjectMark', function(data) {
        if(data.projectID && data.userID){
            socket.broadcast.to(data.userID).emit('refreshProjectIcon', data);
        }
    });
    socket.on('multiFileChangeNotify', function(data) {
        console.log(data);
        let projectID = data.projects[0].projectID;
        let userID = data.user_id;
        if(projectID && userID){//通知项目管理页面
            socket.broadcast.to(userID).emit('fileDataChange', {projectID:projectID});
        }
        for(let fileID of data.oldFileIDs){//通知已打开的项目页面
            let messageTitle = data.from == "feeRateFile"?"feeRateChange":"unitFileChange";
            socket.broadcast.to(fileID).emit(messageTitle, data);
        }
    });

    // 分享权限变更
    socket.on('sharePermissionChange', async function ({ permissionType, userID, compilationID, projectID, emitTenders, payload }) {
        const emitPayload = { projectID };
        if (payload) {
            if (payload.prop) {
                payload.prop.updateDate = moment(Date.now()).format('YYYY-MM-DD HH:mm:ss');
            }
            Object.assign(emitPayload, payload);
        }
        // 推送给项目管理页面
        socket.broadcast.to(`${userID}@${compilationID}`).emit('sharePermissionChange', { permissionType, target: PageTarget.PM, payload: emitPayload });
        // 推送给主页面
        for (const tender of emitTenders) {
            const emitPayload = {};
            if (typeof tender.allowCooperate !== 'undefined') {
                emitPayload.allowCooperate = tender.allowCooperate;
            }
            socket.broadcast.to(`${userID}@${tender.ID}`).emit('sharePermissionChange', { permissionType, target: PageTarget.MAIN, payload: emitPayload });
        }
    });

    // 项目管理树结构变化
    socket.on('pmTreeChange', function ({ userID, compilationID, expandState, selection }) {
        socket.broadcast.to(`${userID}@${compilationID}`).emit('pmTreeChange', { expandState, selection });
    });

    socket.on('disconnect', function () {
        // 由于用户可以重复打开项目，因此不做唯一性处理，只删除一个数据，不删除所有的同用户数据
        if (curProjectID && userCache[curProjectID]) {
            const index = userCache[curProjectID].findIndex(user => user._id === curUser._id);
            if (index >= 0) {
                userCache[curProjectID].splice(index, 1);
                if (!userCache[curProjectID].length) {
                    delete userCache[curProjectID];
                }
                const editingUsers = getEditingUsers(curProjectID);
                socket.broadcast.to(roomInfo.projectID).emit('handleAvatarList', {editingUsers});
                socket.emit('handleAvatarList', {editingUsers});
            }
        }
        console.log("client disconnect =========="+JSON.stringify(roomInfo));
    });
});