const { Injectable } = require('flitter-di')
const FakeResponse = require('./FakeResponse')

class FakeRequest extends Injectable {
    static get services() {
        return [...super.services, 'models', 'app', 'configs']
    }

    response = new FakeResponse()

    body = {}
    session = {}
    sessionID = undefined
    user = undefined
    is_auth = false
    ip = undefined
    headers = {}
    connection = {
        remoteAddress: undefined,
    }
    method = 'get'
    originalUrl = undefined
    path = undefined
    params = {}
    query = {}
    xhr = false

    async deflate() {
        return {
            body: {...this.body},
            session_id: this.sessionID,
            user_id: this.user?.id,
            is_auth: this.is_auth,
            ip: this.ip,
            headers: {...this.headers},
            remote_addr: this.connection?.remoteAddress,
            method: this.method,
            original_url: this.originalUrl,
            path: this.path,
            params: {...this.params},
            query: {...this.query},
            xhr: this.xhr,
        }
    }

    static serialize_request(req) {
        return {
            body: {...req.body},
            session_id: req.sessionID,
            user_id: req.user?.id,
            is_auth: req.is_auth,
            ip: req.ip,
            headers: {...req.headers},
            remote_addr: req.connection?.remoteAddress,
            method: req.method,
            original_url: req.originalUrl,
            path: req.path,
            params: {...req.params},
            query: {...req.query},
            xhr: req.xhr,
        }
    }

    async inflate(data) {
        const User = this.models.get('auth:User')
        const Session = require('./models/Session')
        this.app.di().inject(Session)

        this.body = data.body

        this.sessionID = data.session_id || data.sessionID
        if ( this.sessionID ) {
            const session = await Session.findOne({ _id: this.sessionID })
            if ( session ) {
                this._session_instance = session
                this.session = session.session
            }
        }

        this.user_id = data.user_id || data.user?.id
        if ( this.user_id ) {
            const user = await User.findById(this.user_id)
            if ( user ) {
                this.user = user
            }
        }

        this.is_auth = data.is_auth
        this.ip = data.ip
        this.headers = {...(data.headers || {})}
        this.connection = {
            remoteAddress: data.remote_addr || data.connection?.remoteAddress,
        }
        this.method = data.method
        this.originalUrl = data.original_url || data.originalUrl
        this.path = data.path
        this.params = {...(data.params || {})}
        this.query = {...(data.query || {})}
        this.xhr = data.xhr
    }
}

module.exports = exports = FakeRequest
