const { Service } = require('flitter-di')

class ActivityService extends Service {
    static get services() { return ['models', 'jobs'] }

    model() {
        return this.models.get('Activity')
    }

    async login(req) {
        const activity = this.from_req(req)
        activity.action = 'login'
        activity.metadata = {
            ip: req.ip
        }

        // If this is a new IP login, send an e-mail alert
        const foreign_ip = await this.foreign_login_ip(req.session.auth.user_id, req.ip)
        if ( foreign_ip ) {
            await this.jobs.queue('notifications').add('ForeignIPLoginAlert', {
                ip: req.ip,
                user_id: req.session.auth.user_id,
            })
        }

        await activity.save()
    }

    async api_access_denial({ req, reason, check, oauth_client_id = null }) {
        const activity = this.from_req(req)
        activity.action = 'api-access-denial'
        activity.metadata = {
            scope: check,
            reason,
            oauth_client_id,
        }

        await activity.save()
        return activity
    }

    async mfa_enable({ req }) {
        const activity = this.from_req(req)
        activity.action = 'mfa-enable'
        await activity.save()
    }

    async mfa_disable({ req }) {
        const activity = this.from_req(req)
        activity.action = 'mfa-disable'
        await activity.save()
    }

    async mfa_recovery_created({ req }) {
        const activity = this.from_req(req)
        activity.action = 'mfa-recovery-created'
        await activity.save()
    }

    async app_password_created({ req, name }) {
        const activity = this.from_req(req)
        activity.action = 'app-password-created'
        activity.metadata = { name }
        await activity.save()
    }

    async password_reset({ req, ip }) {
        const activity = this.from_req(req)
        activity.action = 'password-reset'
        activity.metadata = { ip }
        await activity.save()

        // Send an alert to the user
        await this.jobs.queue('notifications').add('PasswordResetAlert', {
            ip, user_id: req.session.auth.user_id,
        })
    }

    async api_token_created({ req, oauth_client_id }) {
        const activity = this.from_req(req)
        activity.action = 'api-token-created'
        activity.metadata = {
            ip: req.ip,
            oauth_client_id,
        }
    }

    async foreign_login_ip(user_id, ip) {
        const Activity = this.model()
        const existing_ip = await Activity.findOne({
            user_id,
            action: 'login',
            'metadata.ip': ip,
        })

        return !existing_ip
    }

    from_req(req) {
        const Activity = this.model()
        return new Activity({
            user_id: req.session.auth.user_id,
            session_id: req.session.id,
        })
    }
}

module.exports = exports = ActivityService
