const User = require('./User.model')
const uuid = require('uuid/v4')

class PublicUserModel extends User {
    static get services() {
        return [...super.services, 'models']
    }

    static get schema() {
        return {
            ...super.schema,
            RequestData: {
                hostname: String,
                ips: [String],
                ip: String,
                date: String,
                requests: [{
                    method: String,
                    original_url: String,
                    xhr: Boolean,
                    user_id: String,
                    date: { type: Date, default: () => new Date },
                }],
            },
        }
    }

    static today() {
        const date = new Date()
        return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`
    }

    static async get_for_request(request) {
        let user = await this.findOne({
            'RequestData.hostname': request.hostname,
            'RequestData.ip': request.headers['x-forwarded-for'] || request.connection.remoteAddress,
            'RequestData.date': this.today(),
        })

        if ( !user ) user = await this.create_for_request(request)

        await user.record_request(request)
        await user.save()
        return user
    }

    static async create_for_request(request) {
        const data = {
            hostname: request.hostname,
            ips: request.ips,
            ip: request.headers['x-forwarded-for'] || request.connection.remoteAddress,
            date: this.today(),
            requests: [],
        }

        const user = new this({
            uid: `public-user-${uuid()}`,
            RequestData: data,
        })
        await user.save()
        return user
    }

    async record_request(request) {
        if ( !this.RequestData.requests ) {
            this.RequestData.requests = [];
        }

        this.RequestData.requests.push({
            method: request.method,
            original_url: request.originalUrl,
            xhr: request.xhr,
            user_id: request.user ? request.user.id : '',
        })
    }

    async get_root_page() {
        const Page = this.models.get('api:Page')
        let page = await Page.findOne({OrgUserId: this._id, ParentId: '0'})

        if ( !page ) {
            page = new Page({
                Name: 'Public Root Page',
                OrgUserId: this._id,
                ParentId: '0',
                NodeIds: [],
                ChildPageIds: [],
                noDelete: true,
                virtual: true,
            })

            await page.save()
        }

        return page
    }

    async can(permission) {
        const PublicUserPermission = this.models.get('auth:PublicUserPermission')
        return PublicUserPermission.can(permission)
    }

    is_public_user() {
        return true
    }
}

module.exports = exports = PublicUserModel
