const Controller = require('libflitter/controller/Controller')
const Page = require('../../../models/api/Page.model')
const Node = require('../../../models/api/Node.model')
const FileGroup = require('../../../models/api/FileGroup.model')
const { ObjectId } = require('mongodb')

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

    async create_config(req, res) {
        const PageId = req.params.PageId

        let page = await Page.findOne({UUID: PageId})
        if ( !page ) return res.status(404).message('Page not found with that ID.').api({})
        if ( !(await page.is_accessible_by(req.user, 'update')) ) return req.security.deny()

        const NodeId = req.params.NodeId

        let node = await Node.findOne({UUID: NodeId})
        if ( !node ) return res.status(404).message('Node not found with that ID.').api({})

        const group = new FileGroup({
            NodeId: node.UUID,
            PageId: page.UUID,
            FileIds: [],
        })

        if ( req.body.UUID ) {
            const existingUUID = await FileGroup.findOne({ UUID: req.body.UUID })
            if ( !existingUUID ) {
                group.UUID = req.body.UUID
            }
        }

        await group.version_save(`Added to page "${page.Name}"`, req.user.id)
        req.user.allow(`files:${group.UUID}`)
        await req.user.save()

        return res.api(group)
    }

    async get_config(req, res) {
        const PageId = req.params.PageId

        let page = await Page.findOne({UUID: PageId})
        if ( !page ) return res.status(404).message('Page not found with that ID.').api({})
        if ( !(await page.is_accessible_by(req.user)) ) return req.security.deny()

        const NodeId = req.params.NodeId

        let node = await Node.findOne({UUID: NodeId})
        if ( !node ) return res.status(404).message('Node not found with that ID.').api({})

        const group = await FileGroup.findOne({UUID: req.params.FilesId})
        if ( !group ) return res.status(404).message('Invalid file group.').api({})
        // if ( !group.accessible_by(req.user) ) return req.security.deny()

        const File = this.models.get('upload::File')
        const files = await File.find({_id: {$in: group.FileIds.map(x => ObjectId(x))}})
        group.files = files

        return res.api(group)
    }

    async save_upload(req, res) {
        const PageId = req.params.PageId

        let page = await Page.findOne({UUID: PageId})
        if ( !page ) return res.status(404).message('Page not found with that ID.').api({})
        if ( !(await page.is_accessible_by(req.user, 'update')) ) return req.security.deny()

        const NodeId = req.params.NodeId

        let node = await Node.findOne({UUID: NodeId})
        if ( !node ) return res.status(404).message('Node not found with that ID.').api({})

        const group = await FileGroup.findOne({UUID: req.params.FilesId})
        if ( !group ) return res.status(404).message('Invalid file group.').api({})
        // if ( !group.accessible_by(req.user) ) return req.security.deny()

        let file_name = ''
        if ( req.uploads.uploaded_file ) {
            group.FileIds.push(req.uploads.uploaded_file.id)
        }

        await group.version_save(`Added file${file_name ? ' "'+file_name+'"' : ''}`, req.user.id)
        return res.redirect(req.body.redirectTo ? req.body.redirectTo : '/')
    }

    async download(req, res) {
        const PageId = req.params.PageId

        let page = await Page.findOne({UUID: PageId})
        if ( !page ) return res.status(404).message('Page not found with that ID.').api({})
        if ( !(await page.is_accessible_by(req.user)) ) return req.security.deny()

        const NodeId = req.params.NodeId

        let node = await Node.findOne({UUID: NodeId})
        if ( !node ) return res.status(404).message('Node not found with that ID.').api({})

        const group = await FileGroup.findOne({UUID: req.params.FilesId})
        if ( !group ) return res.status(404).message('Invalid file group.').api({})
        // if ( !group.accessible_by(req.user) ) return req.security.deny()

        if ( !group.FileIds.includes(req.params.FileId) ) {
            return req.security.deny()
        }

        const File = this.models.get('upload::File')
        const file = await File.findOne({_id: ObjectId(req.params.FileId)})
        if ( !file ) return res.status(404).api({})

        return file.send(res)
    }

    async delete_group(req, res) {
        const PageId = req.params.PageId

        let page = await Page.findOne({UUID: PageId})
        if ( !page ) return res.status(404).message('Page not found with that ID.').api({})
        if ( !(await page.is_accessible_by(req.user, 'update')) ) return req.security.deny()

        const NodeId = req.params.NodeId

        let node = await Node.findOne({UUID: NodeId})
        if ( !node ) return res.status(404).message('Node not found with that ID.').api({})

        const group = await FileGroup.findOne({UUID: req.params.FilesId})
        if ( !group ) return res.status(404).message('Invalid file group.').api({})
        // if ( !group.accessible_by(req.user) ) return req.security.deny()

        await group.delete()
        return res.api({})
    }
}

module.exports = exports = File
