const Controller = require('libflitter/controller/Controller')

/*
 * DatabaseAPI Controller
 * -------------------------------------------------------------
 * Put some description here!
 */
class DatabaseAPI extends Controller {
    static get services() {
        return [...super.services, 'models', 'utility']
    }

    async databases(req, res, next) {
        const Database = this.models.get('api:db:Database')
        const dbs = await Database.visible_by_user(req.user)
        return res.api(dbs.map(x => x.to_api_object()))
    }

    async get_database(req, res, next) {
        return res.api(req.form.database.to_api_object())
    }

    async get_columns(req, res, next) {
        const db = req.form.database
        const cols = (await db.get_columns()).map(x => x.to_api_object())
        return res.api(cols)
    }

    async get_columns_order(req, res, next) {
        return res.api(req.form.database.ColumnIds)
    }

    async get_data(req, res, next) {
        const DBEntry = this.models.get('api:db:DBEntry')
        const db = req.form.database
        const cursor = await DBEntry.cursor({DatabaseId: db.UUID})

        if ( req.query.sort ) {
            if ( this.utility.is_json(req.query.sort) ) {
                const sort = JSON.parse(req.query.sort)
                if ( typeof sort !== 'object' ) return res.status(400).message('Invalid sort field. Should be JSON object.').api()
                const sort_obj = {}
                for ( const field in sort ) {
                    if ( !sort.hasOwnProperty(field) ) continue
                    sort_obj[`RowData.${field}`] = (Number(sort[field]) < 0 ? -1 : 1)
                }
                cursor.sort(sort_obj)
            } else if ( req.query.sort ) {
                const sort_obj = {}
                sort_obj[`RowData.${req.query.sort}`] = (req.query.reverse ? -1 : 1)
                cursor.sort(sort_obj)
            }
        }

        if ( req.query.limit ) {
            const limit = Number(req.query.limit)
            if ( !isNaN(limit) ) cursor.limit(limit)
        }

        if ( req.query.skip ) {
            const skip = Number(req.query.skip)
            if ( !isNaN(skip) ) cursor.skip(skip)
        }

        if ( req.query.where ) {
            if ( !this.utility.is_json(req.query.where) ) {
                return res.status(400).message('Invalid where field. Should be JSON object.').api()
            }

            const wheres = JSON.parse(req.query.where)

            if ( typeof wheres !== 'object' ) {
                return res.status(400).message('Invalid where field. Should be JSON object.').api()
            }

            const wheres_object = {}
            for ( const field in wheres ) {
                if ( !wheres.hasOwnProperty(field) ) continue
                const value = wheres[field]
                if ( typeof value !== 'object' ) {
                    wheres_object[`RowData.${field}`] = value
                } else {
                    const sub_where = {}
                }
            }
        }

        const data = (await DBEntry.from_cursor(cursor)).map(x => {
            x = x.to_api_object()
            if ( req.query.flatten ) {
                x = {
                    uuid: x.uuid,
                    database_id: x.database_id,
                    ...x.data,
                }
            }
            return x
        })
        return res.api(data)
    }

    async get_record(req, res, next) {
        const DBEntry = this.models.get('api:db:DBEntry')
        const db = req.form.database
        const record = await DBEntry.findOne({UUID: req.params.record_id, DatabaseId: db.UUID})
        if ( record ) {
            const api_obj = record.to_api_object()
            if ( req.query.flatten ) {
                return res.api({
                    uuid: api_obj.uuid,
                    database_id: api_obj.database_id,
                    ...api_obj.data,
                })
            }
            return res.api(api_obj)
        }
        else return res.status(404).message('Database record not found with that ID.').api()
    }
}

module.exports = exports = DatabaseAPI
