let express = require('express')
let router = express.Router()
const auth = require('../lib/auth')

const Errors = require('../lib/errors')
let pagination = require('../lib/pagination')
let { Ban, Item, Transaction, Inventory, ItemCategory, User, Ip, sequelize, Sequelize } = require('../models')


router.get('/', async(req, res) => {
    try {
        let categories = await ItemCategory.findAll()

        res.json(categories)
    } catch (e) {
        res.status(500)
        res.json({
            errors: [Errors.unknown]
        })
    }

})

router.get('/:category', async(req, res, next) => {
    try {
        let threads, threadsLatestPost, resThreads, user
        let { from, limit } = pagination.getPaginationProps(req.query, true)

        if(req.query.username) {
            user = await User.findOne({ where: { username: req.query.username }})
        }

        function threadInclude(order) {
            let options = {
                model: Item,
                order: [['id', 'DESC']],
                limit,
                where: {},
                include: [
                    ItemCategory,
                    { model: User, attributes: ['username', 'createdAt', 'id', 'color', 'picture', 'locked', 'admin', 'booster', 'executive', 'bot'] },
                ]
            }

            if(user) {
                options.where.userId = user.id
            }

            if(from !== null) {
                options.where.id = { $lte: from }
            }

            return [options]
        }

        if(req.params.category === 'ALL') {
            threads = await Thread.findAll( threadInclude('ASC')[0] )
            threadsLatestPost = await Thread.findAll( threadInclude('DESC')[0] )
        } else {
            threads = await ItemCategory.findOne({
                where: { id: req.params.category },
                include: threadInclude('ASC')
            })

            threadsLatestPost = await ItemCategory.findOne({
                where: { id: req.params.category },
                include: threadInclude('DESC')
            })
        }
        if(!threads) throw Errors.invalidParameter('ID','Category doesn\'t exist')
        if(Array.isArray(threads)) {
            resThreads = {
                name: 'All',
                value: 'ALL',
                Threads: threads,
                meta: {}
            }

            threadsLatestPost = { Threads: threadsLatestPost }
        } else {
            resThreads = threads.toJSON()
            resThreads.meta = {}
        }

        res.json(resThreads)

    } catch (e) { next(e) }
})

router.get('/view/:id', async(req, res, next) => {
    try {
        let queryObj = {
            where: {id: req.params.id},
            include: { model: User, attributes: ['username', 'createdAt', 'id', 'color', 'picture', 'locked', 'admin', 'booster', 'executive', 'bot'] }
        }
        let marketplace = await Item.findOne(queryObj)
        if (!marketplace) throw Errors.invalidItem
        if(marketplace.deleted) {
            let queryObj = {
                where: {id: req.params.id},
                attributes: ['name', 'deleted', 'createdAt', 'id', 'updatedAt', 'price'],
                include: { model: User, attributes: ['username', 'createdAt', 'id', 'color', 'picture', 'locked', 'admin', 'booster', 'executive', 'bot'] }
            }
            let marketplace = await Item.findOne(queryObj)
            res.json(marketplace.toJSON())
        }
        if(!marketplace.deleted) {
            res.json(marketplace.toJSON())
        }


    } catch (err) { next(err) }
})

router.get('/purchase/:id', auth, async(req, res, next) => {
    await Ban.ReadOnlyMode(req.userData.UserId)
    try {
        let queryObj = {
            where: {id: req.params.id},
        }
        let queryObj2 = {
            where: {username: req.userData.username},
        }
        let queryObj3 = {
            where: {UserId: req.userData.UserId, ItemId: req.params.id},
        }
        let marketplace = await Item.findOne(queryObj)
        let user = await User.findOne(queryObj2)
        let inventory = await Inventory.findOne(queryObj3)
        if (!marketplace) throw Errors.invalidItem
        if (user.koins < marketplace.price && !marketplace.saleEnabled) {
            throw Errors.insufficientKoins
        }
        if (user.koins < marketplace.salePrice && marketplace.saleEnabled) {
            throw Errors.insufficientKoins
        }
        if (marketplace.offSale) {
            throw Errors.offSale
        }
        if(marketplace.deleted) {
            throw Errors.itemUnavailable
        }
        if(!marketplace.approved) {
            throw Errors.itemUnavailable
        }
        if(inventory && !marketplace.limited) {
            throw Errors.itemOwned
        }
        if(inventory && marketplace.limited) {
            throw Errors.itemOwnedLimited
        }
        if(marketplace.saleEnabled) {
            const UserId = user.id
            const priceTotal = marketplace.salePrice
            await user.removeKoins(priceTotal)
            await Transaction.create({UserId: UserId, priceOfPurchase: priceTotal, text: user.username + ' purchased ' + marketplace.name + ' (' + marketplace.id + ') from the Marketplace for ' + priceTotal + ' koins', itemId: marketplace.id, limited: marketplace.limited, ipId: Ip.createIfNotExists(req.ip, user)})
            await Inventory.create({UserId: UserId, purchasePrice: priceTotal, isReselling: false, isResellingPrice: 0, ItemId: marketplace.id, boughtFrom: marketplace.UserId, resellType: 0, auctionId: 0})
            res.status(200)
            res.json({success: true})
        } else {
            const UserId = user.id
            const priceTotal = marketplace.price
            await user.removeKoins(priceTotal)
            await Transaction.create({UserId: UserId, priceOfPurchase: priceTotal, text: user.username + ' purchased ' + marketplace.name + ' (' + marketplace.id + ') from the Marketplace for ' + priceTotal + ' koins', itemId: marketplace.id, limited: marketplace.limited, ipId: Ip.createIfNotExists(req.ip, user)})
            await Inventory.create({UserId: UserId, purchasePrice: priceTotal, isReselling: false, isResellingPrice: 0, ItemId: marketplace.id, boughtFrom: marketplace.UserId, resellType: 0, auctionId: 0})
            res.status(200)
            res.json({success: true})
        }

    } catch (err) { next(err) }
})

router.get('/check/:id', auth, async(req, res, next) => {
try {
    let queryObj = {
        where: {id: req.params.id},
    }
    let queryObj3 = {
        where: {UserId: req.userData.UserId, ItemId: req.params.id},
    }
    let inventory = await Inventory.findOne(queryObj3)
    let marketplace = await Item.findOne(queryObj)
    if(marketplace) {
        if (inventory) {
            res.status(200)
            res.json({purchased: true})
        } else {
            res.status(200)
            res.json({purchased: false})
        }
    } else {
        throw Errors.invalidItem
    }
} catch (err) { next(err) }
})

module.exports = router
