/*
 * 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 {parseSocketEventMessage, SocketEventMessage} from "../../../../modules/socket/event/message";
import {createSocketErrorResponse, createSocketResponse} from "../../../../helpers";
import {AuthContact} from "@chamesu/common/domains/auth/contact";
import {SocketInterface} from "../../../../modules/socket";


async function accessContact(socket: SocketInterface, eventMessage: SocketEventMessage, authContext: AuthSocketAppContext) : Promise<AuthContact> {
    const meta: Record<string, any> = eventMessage.meta;
    if(typeof meta.contactId === 'undefined') {
        throw new Error('Es muss eine Kontakt-ID angegeben werden.');
    }

    const contact : AuthContact | undefined = await authContext.contactHandler.getContact(meta.contactId);
    if(typeof contact === 'undefined') {
        throw new Error('Der anegebene Kontakt ist ungültig.');
    }

    if(contact.user_one_id !== socket.userId && contact.user_two_id !== socket.userId) {
        throw new Error('Du bist kein Teil von diesem Kontakt...');
    }

    return contact;
}

export function handleAuthSocketContactJoinEvent(socket: SocketInterface, ctx: AppContext, authCtx: AuthSocketAppContext) {
    return function (data: unknown, cb: CallableFunction) {
        return parseSocketEventMessage(data)
            .then(async (socketEvent: SocketEventMessage) => {
                try {
                    if(typeof socketEvent.id === 'undefined') {
                        return createSocketErrorResponse(cb, 'Es muss eine Kontakt-ID angegeben werden.');
                    }

                    return authCtx.contactHandler.join(socket, <string> socketEvent.id)
                        .then(() => {
                            return createSocketResponse(cb);
                        })
                        .catch((e) => {
                            return createSocketErrorResponse(cb, e.message);
                        })
                } catch (e) {
                    return createSocketErrorResponse(cb, e.message);
                }
            });
    }
}

export function handleAuthSocketContactLeaveEvent(socket: SocketInterface, ctx: AppContext, authCtx: AuthSocketAppContext) {
    return function (data: unknown, cb: CallableFunction) {
        return parseSocketEventMessage(data)
            .then(async (socketEvent: SocketEventMessage) => {
                try {
                    if (typeof socketEvent.id === 'undefined') {
                        return createSocketErrorResponse(cb, 'Es muss eine Kontakt-ID angegeben werden.');
                    }

                    return authCtx.contactHandler.leave(socket, <string> socketEvent.id)
                        .then(() => {
                            return createSocketResponse(cb);
                        })
                        .catch((e) => {
                            return createSocketErrorResponse(cb, e.message);
                        })
                } catch (e) {
                    return createSocketErrorResponse(cb, e.message);
                }
            });
    }
}
