const { Model } = require('flitter-orm')

class AnnouncementModel extends Model {
    static get services() {
        return [...super.services, 'models', 'jobs', 'configs']
    }

    static get schema() {
        return {
            title: String,
            message: String,
            user_ids: [String],
            group_ids: [String],
            type: String, // login | email | banner
        }
    }

    async to_api() {
        return {
            id: this.id,
            title: this.title,
            message: this.message,
            user_ids: this.user_ids,
            group_ids: this.group_ids,
            type: this.type,
        }
    }

    async groups() {
        const Group = this.models.get('auth:Group')
        return await Group.find({ _id: { $in: this.group_ids.map(x => this.constructor.to_object_id(x)) } })
    }

    async users() {
        const User = this.models.get('auth:User')
        return await User.find({ _id: { $in: this.user_ids.map(x => this.constructor.to_object_id(x)) } })
    }

    async all_users() {
        const users = await this.users()
        const groups = await this.groups()

        const all_users = users
        const all_user_ids = users.map(x => x.id)
        for ( const group of groups ) {
            const group_users = await group.users()
            for ( const user of group_users ) {
                if ( !all_user_ids.includes(user.id) ) {
                    all_user_ids.push(user.id)
                    all_users.push(user)
                }
            }
        }

        return all_users
    }

    async log_populate() {
        await this.jobs.queue('notifications').add('PopulateAnnouncement', {
            announcement_id: this.id,
        })
    }

    async populate() {
        if ( this.type === 'email' ) {
            await this.populate_emails()
        } else if ( this.type === 'banner' ) {
            await this.populate_banners()
        } else if ( this.type === 'login' ) {
            await this.populate_logins()
        }
    }

    async populate_emails() {
        const users = await this.all_users()
        for ( const user of users ) {
            await this.jobs.queue('mailer').add('EMail', {
                to: user.email,
                subject: 'Announcement | ' + this.configs.get('app.name'),
                email_params: {
                    header_text: this.title,
                    body_paragraphs: [
                        this.message,
                    ],
                },
            })
        }
    }

    async populate_banners() {
        const users = await this.all_users()
        const Message = this.models.get('Message')
        for ( const user of users ) {
            await Message.create(user, `${this.title} - ${this.message}`)
        }
    }

    async populate_logins() {
        const users = await this.all_users()
        const LoginMessage = this.models.get('LoginMessage')
        for ( const user of users ) {
            await LoginMessage.create(user, this.title, this.message)
        }
    }
}

module.exports = exports = AnnouncementModel
