/*
 * 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 {dropContactData, getAllContactData} from "~/domains/contact-data/api";
import {getters} from "~/modules/security/store";
import {
    createAndSaveContactSelfKeyPair,
    decodeContactMessage,
    saveContactRelatedKey,
} from "~/domains/contact/encryption";
import {
    createAndShareRoomKeyToContacts,
    saveChatRoomKey,
    shareChatRoomKey
} from "~/domains/chat-room/encryption";
import {getRoomMembers} from "~/domains/chat-room/api";

type ShareData = {
    id: string,
    content: any,
    encrypted: boolean,
    type: string,
    fromUserId: number,
    toUserId: number,
    contactId: string
}

export enum ContactDataSecretType {
    CONTACT = 'secretKey',
    ROOM = 'roomSecretKey',
    ROOM_REQUEST = 'requestRoomSecretKey'
}

export async function loadAndApplyContactData(userId: number) {
    const shareData : ShareData[] = await getAllContactData({
        filter: {
            toUserId: userId
        }
    });

    if(shareData.length === 0) {
        return;
    }

    for(let i=0; i<shareData.length; i++) {
        await applyContactData(shareData[i], userId);
    }
}

export async function applyContactData(shareData: ShareData, userId: number) {
    if(shareData.toUserId !== userId) return;

    switch (shareData.type) {
        case ContactDataSecretType.CONTACT:
            await saveContactRelatedKey(
                shareData.contactId,
                shareData.content
            );

            const selfKeyPair = getters.contactSelfKeyPair(shareData.contactId);
            if(typeof selfKeyPair === 'undefined') {
                await createAndSaveContactSelfKeyPair(shareData.contactId);
            }
            break;
        case ContactDataSecretType.ROOM:
            await applyRoomSecretKey(shareData, userId);
            break;
        case ContactDataSecretType.ROOM_REQUEST:
            await applyRequestRoomSecretKey(shareData, userId);
            break;
    }

    await dropContactData(shareData.id);
}

async function applySecretKey(shareData: ShareData, userid: number) {

}

async function applyRoomSecretKey(shareData: ShareData, userid: number) {
    let message : any = shareData.content;

    if(shareData.encrypted) {
        message = decodeContactMessage(
            message,
            shareData.contactId
        );

        message = JSON.parse(message);
    }

    const prototype = Object.prototype.toString.call(message);
    if(prototype === '[object Object]') {
        const {roomId, key} = message;

        if(typeof roomId !== 'undefined' && typeof key !== 'undefined') {
            await saveChatRoomKey(roomId, key);
        }
    }
}

async function applyRequestRoomSecretKey(shareData: ShareData, userId: number) {
    let requestMessage : any = shareData.content;

    const requestPrototype = Object.prototype.toString.call(requestMessage);
    if(requestPrototype === '[object Object]') {
        const {roomId} = requestMessage;

        if(typeof roomId !== 'undefined') {
            const roomKey = getters.roomKey(roomId);
            if(typeof roomKey !== 'undefined') {
                await shareChatRoomKey(shareData.contactId, roomId, roomKey);
            } else {
                const response = await getRoomMembers(roomId, {
                    filter: {
                        userId
                    }
                });

                if(response.data.length === 1 && response.data[0].creator) {
                    await createAndShareRoomKeyToContacts(roomId);
                }
            }
        }
    }
}
