# JSDoc: Source: schemas/channel/media/playlistSchema.js

# Source: schemas/channel/media/playlistSchema.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 playlistMediaSchema = require('./playlistMediaSchema');

    /**
     * DB Schema for Documents representing playlists full of media
     */
    const playlistSchema = new mongoose.Schema({
        name: {
            type: mongoose.SchemaTypes.String,
            required: true,
        },
        media: [playlistMediaSchema],
        defaultTitles:[{
            type: mongoose.SchemaTypes.String,
            required: false,
            default: []
        }]
    });

    //methods
    /**
     * Dehydrate to minified flat network-friendly object
     * @returns {Object} Network-Friendly Browser-Digestable object representing media from a playlist
     */
    playlistSchema.methods.dehydrate = function(){
        //Create empty array to hold media
        const mediaArray = [];

        //Fill media array
        for(let media of this.media){
            mediaArray.push(media.dehydrate());
        }

        //return dehydrated playlist
        return {
            name: this.name,
            media: mediaArray,
            defaultTitles: this.defaultTitles
        }
    }

    /**
     * Add media to the given playlist Document
     * @param {Array} mediaList - Array of media Objects to add to playlist
     */
    playlistSchema.methods.addMedia = function(mediaList){
        //For every piece of media in the list
        for(let media of mediaList){
            //Set media status schema discriminator
            media.status = 'saved';

            //Add the media to the playlist
            this.media.push(media);
        }
    }

    /**
     * Gets Media from a playlist by UUID
     * @param {String} uuid - UUID of media to pull
     * @returns {media} media with matching UUID
     */
    playlistSchema.methods.findMediaByUUID = function(uuid){
        //For every piece of media in the current playlist
        for(let media of this.media){
            //If we found our match
            if(media.uuid.toString() == uuid){
                //return it
                return media;
            }
        }
    }

    /**
     * Deletes media from a given playlist
     * @param {String} uuid - UUID of media to delete
     */
    playlistSchema.methods.deleteMedia = function(uuid){
        //Create new array to hold list of media to be kept
        const keptMedia = [];

        //For every piece of media in the current playlist
        for(let media of this.media){
            //It isn't the media to be deleted
            if(media.uuid.toString() != uuid){
                //Add it to the list to be kept
                keptMedia.push(media);
            }
        }

        //Set playlist media from keptMedia
        this.media = keptMedia;
    }

    /**
     * Pick title based on default title's list and media's given title
     * @param {String} title - Title to use if there are no default titles.
     * @returns {String} Chosen title based on result of function
     */
    playlistSchema.methods.pickDefaultTitle = function(title){
        //If we don't have default titles in this playlist
        if(this.defaultTitles.length <= 0){
            //If we wheren't handed an original title
            if(title == null || title == ''){
                return 'Unnamed Media'
            }else{
                return title;
            }
        }else{
            //Grab a random default title and return it
            return this.defaultTitles[Math.floor(Math.random() * this.defaultTitles.length)];
        }
    }

    module.exports = playlistSchema;