/*
 * Copyright (c) 2022.
 * Author Peter Placzek (tada5hi)
 * For the full copyright and license information,
 * view the LICENSE file that was distributed with this source code.
 */

import {createSocketErrorResponse, createSocketResponse} from "../../../../helpers";
import {SocketInterface} from "../../../../modules/socket";
import {parseSocketEventMessage, SocketEventMessage} from "../../../../modules/socket/event/message";
import {useChatRoomEvent} from "../room/event";
import {useChatRoom} from "../room";
import {useChatRoomStatus} from "../room/user-status";

//--------------------------------------------------------------------

export function createChatRoomSocketEventHandler(socket: SocketInterface) {
    socket.on("ping", (cb) => {
        if (typeof cb === "function")
            cb();
    });

    socket.on('join', (options: any, cb: CallableFunction) => {
        if(typeof cb !== 'function') return;

        parseSocketEventMessage(options).then((chatRoomEvent: SocketEventMessage) => {
            try {
                useChatRoom().join(socket, <string> chatRoomEvent.id).then(() => {
                    socket.chatRooms.push(<string> chatRoomEvent.id);
                    return createSocketResponse(cb);
                }).catch((e: any) => {
                    console.log(e);
                    return createSocketErrorResponse(cb, e.message);
                })
            } catch (e) {
                console.log(e);
                return createSocketErrorResponse(cb, e.message);
            }
        }).catch(() => {
            return createSocketErrorResponse(cb, 'Socket Event Message malformed');
        });
    });

    socket.on('leave', (options: any, cb: CallableFunction) => {
        if(typeof cb !== 'function') return;

        parseSocketEventMessage(options).then((chatRoomEvent: SocketEventMessage) => {
            try {
                if(socket.chatRooms.indexOf(<string> chatRoomEvent.id) === -1) {
                    return createSocketResponse(cb);
                }

                useChatRoom().leave(socket, <string> chatRoomEvent.id).then(() => {
                    socket.chatRooms = socket.chatRooms.filter(room => room !== <string> chatRoomEvent.id);
                    return createSocketResponse(cb);
                }).catch((e: any) => {
                    return createSocketErrorResponse(cb, e.message);
                })
            } catch (e) {
                return createSocketErrorResponse(cb, e.message);
            }
        }).catch(() => {
            return createSocketErrorResponse(cb, 'Socket Event Message malformed');
        });
    });

    socket.on('subscribe', (options: any, cb: CallableFunction) => {
        if(typeof cb !== 'function') return;

        parseSocketEventMessage(options).then((chatRoomEvent: SocketEventMessage) => {
            if(typeof chatRoomEvent.meta.roomEvent === 'undefined') {
                return createSocketErrorResponse(cb, 'An Room Event mus be specified.');
            }

            if(socket.chatRooms.indexOf(<string> chatRoomEvent.id) === -1) {
                return createSocketErrorResponse(cb, 'You haven\'t joined the room.');
            }

            useChatRoomEvent().subscribeAsSocket(socket, <string> chatRoomEvent.id, chatRoomEvent.meta.roomEvent);

            return createSocketResponse(cb);
        }).catch(() => {
            return createSocketErrorResponse(cb, 'Socket Event Message malformed');
        });
    });

    socket.on('unsubscribe', (options: any, cb: CallableFunction) => {
        if(typeof cb !== 'function') return;

        parseSocketEventMessage(options).then((chatRoomEvent: SocketEventMessage) => {
            if(typeof chatRoomEvent.meta.roomEvent === 'undefined') {
                return createSocketErrorResponse(cb, 'An Room Event mus be specified.');
            }

            if(socket.chatRooms.indexOf(<string> chatRoomEvent.id) === -1) {
                return createSocketErrorResponse(cb, 'You haven\'t joined the room.');
            }

            useChatRoomEvent().unsubscribeAsSocket(socket, <string> chatRoomEvent.id, chatRoomEvent.meta.roomEvent);

            return createSocketResponse(cb);
        }).catch(() => {
            return createSocketErrorResponse(cb, 'Socket Event Message malformed');
        });
    });

    socket.on('messageTyping', (options: any) => {
        parseSocketEventMessage(options).then((chatRoomEvent: SocketEventMessage) => {
            if(typeof socket.userId === 'undefined' || socket.chatRooms.indexOf(<string> chatRoomEvent.id) === -1) {
                return;
            }

            useChatRoomEvent().emitUserMessageTyping(<string> chatRoomEvent.id, socket.userId).then(r => r);
        }).catch(() => {

        });
    });

    socket.on('onlineUsers', (options: any, cb: CallableFunction) => {
        if(typeof cb !== 'function') return;

        parseSocketEventMessage(options).then((chatRoomEvent: SocketEventMessage) => {
            useChatRoomStatus().getOnline(<string> chatRoomEvent.id).then((items: any) => {
                createSocketResponse(cb, items);
            }).catch((error: any) => {
                return createSocketErrorResponse(cb, error.message);
            })
        });
    });

    socket.on('disconnect', () => {
        if(!!socket.user)  {
            if(socket.chatRooms.length > 0) {
                for(let i=0; i< socket.chatRooms.length; i++) {
                    useChatRoom().leave(socket, socket.chatRooms[i]).then(r => r);
                }
            }
        }
    });
}
