# JSDoc: Source: schemas/emoteSchema.js

# Source: schemas/emoteSchema.js

    /*Canopy - The next generation of stoner streaming software
    Copyright (C) 2024-2025 Rainbownapkin and the TTN Community

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.*/

    //NPM Imports
    const {mongoose} = require('mongoose');

    //Local Imports
    const defaultEmote = require("../../defaultEmotes.json");
    const server = require('../server');

    /**
     * "Enum" for emote type property
     */
    const typeEnum = ["image", "video"];

    /**
     * DB Schema for documents represnting site-wide emotes
     */
    const emoteSchema = new mongoose.Schema({
        name:{
            type: mongoose.SchemaTypes.String,
            required: true,
            maxLength: 14,
        },
        link:{
            type: mongoose.SchemaTypes.String,
            required: true
        },
        type:{
            type: mongoose.SchemaTypes.String,
            required: true,
            enum: typeEnum,
            default: typeEnum[0]
        }
    });

    /**
     * Post-Save function, ensures all new emotes are broadcastes to actively connected clients
     */
    emoteSchema.post('save', async function (next){
        //broadcast updated emotes
        server.channelManager.broadcastSiteEmotes();
    });

    /**
     * Post-Delete function, ensures all deleted emotes are removed from actively connected clients
     */
    emoteSchema.post('deleteOne', {document: true}, async function (next){
        //broadcast updated emotes
        server.channelManager.broadcastSiteEmotes();
    });

    //statics
    /**
     * Loads un-loaded emotes from defaultEmotes.json
     */
    emoteSchema.statics.loadDefaults = async function(){
        //Make sure registerEmote function is happy
        const _this = this;

        //Ensure default comes first (.bind(this) doesn't seem to work here...)
        await registerEmote(defaultEmote.default);
        //For each entry in the defaultEmote.json file
        defaultEmote.array.forEach(registerEmote);

        async function registerEmote(emote){
            try{
                //Look for emote matching the one from our file
                const foundEmote = await _this.findOne({name: emote.name});

                //if the emote doesn't exist
                if(!foundEmote){
                    const emoteDB = await _this.create(emote);
                    console.log(`Loading default emote [${emote.name}] into DB from defaultEmote.json`);
                }

            }catch(err){
                if(emote != null){
                    console.log(`Error loading emote [${emote.name}]:`);
                }else{
                    console.log("Error, null emote:");
                }
            }
        }
    }

    /**
     * Generates a network-friendly browser-digestable list of emotes
     * @returns {Object} - network-friendly browser-digestable list of emotes
     */
    emoteSchema.statics.getEmotes = async function(){
        //Create an empty array to hold our emote list
        const emoteList = [];
        //Pull emotes from database
        const emoteDB = await this.find({});

        emoteDB.forEach((emote) => {
            emoteList.push({
                name: emote.name,
                link: emote.link,
                type: emote.type
            });
        });

        return emoteList;
    }

    emoteSchema.statics.typeEnum = typeEnum;

    module.exports = mongoose.model("emote", emoteSchema);