/*
 * 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 {AppContext} from "../../../index";
import {AuthSocketAppContext} from "../index";
import {SocketInterface} from "../../../../modules/socket";
import {createSocketErrorResponse, createSocketResponse} from "../../../../helpers";
import {
    parseSocketEventMessage,
    SocketEventMessage
} from "../../../../modules/socket/event/message";
import {OnlineIdsResponse} from "../../../../modules/socket/status";
import {handleAuthSocketContactJoinEvent, handleAuthSocketContactLeaveEvent} from "./contact";

function createSocketEventHandler(ctx: AppContext, authCtx: AuthSocketAppContext) {
    return ctx.socketServer.on('connection',(socket: SocketInterface) => {
        if(!!socket.userId) {
            authCtx.contactHandler.joinAll(socket)
                .then(r => r)
                .catch(e => console.log(e));
        }

        socket.on('contactJoin', handleAuthSocketContactJoinEvent(socket, ctx, authCtx));
        socket.on('contactLeave', handleAuthSocketContactLeaveEvent(socket, ctx, authCtx));

        socket.on('contactsOnline', (data: unknown, cb: CallableFunction) => {
            return authCtx.contactHandler.ctx.status.getOnline(socket.userId)
                .then((onlineClients: OnlineIdsResponse) => {
                    return createSocketResponse(cb, onlineClients);
                }).catch((error: any) => {
                    return createSocketErrorResponse(cb, error.message);
                })
        })

        socket.on('guestsOnline', (data: unknown, cb: CallableFunction) => {
            return parseSocketEventMessage(data).then((socketEvent: SocketEventMessage) => {
                return authCtx.guestHandler.ctx.status.getOnlineClients()
                    .then((onlineClients: any) => {
                        return createSocketResponse(cb, onlineClients);
                    }).catch((error: any) => {
                        return createSocketErrorResponse(cb, error.message);
                    })
            });
        });

        socket.on('usersOnline', (options: any, cb: CallableFunction) => {
            return authCtx.userHandler.ctx.status.getOnline()
                .then((onlineClients: OnlineIdsResponse) => {
                    return createSocketResponse(cb, onlineClients);
                }).catch((error: any) => {
                    return createSocketErrorResponse(cb, error.message);
                })
        });

        socket.on('disconnect', () => {
            if(!!socket.userId)  {
                authCtx.userHandler.drop(socket).then(r => r);
                authCtx.contactHandler.leaveAll(socket).then(r => r);
            } else {
                authCtx.guestHandler.drop(socket).then(r => r);
            }
        });
    });
}

export default createSocketEventHandler;
