import { Router } from 'express'

class JamiRestApi {
    constructor(jami) {
        this.jami = jami
    }

    getRouter() {
        const router = Router({mergeParams: true})
        //router.use(express.json());

        // Accounts
        router.get(['/accounts'], (req, res, next) => {
            console.log("Get account list")
            let accounts = this.jami.getAccountList()
            if (req.user.accountFilter)
                accounts = accounts.filter(account => req.user.accountFilter(account.getId()))
            res.json(accounts.map(account => account.getSummary()))
        })

        const checkAccount = (req, res, next) => {
            console.log(`checkAccount ${req.params.accountId} for ${req.user.id}`)
            if (req.user && (!req.user.accountFilter || req.user.accountFilter(req.params.accountId))) {
                return next();
            }
            res.status(403).end()
        }

        const accountRouter = Router({mergeParams: true})
        router.use('/accounts/:accountId', checkAccount, accountRouter)

        accountRouter.get(['/'], (req, res, next) => {
            console.log(`Get account ${req.params.accountId}`)
            const account = this.jami.getAccount(req.params.accountId)
            if (account)
                res.json(account.getObject())
            else
                res.status(404).end()
        })

        // Contacts
        accountRouter.get(['/contacts'], (req, res, next) => {
            console.log(`Get account ${req.params.accountId}`)
            const account = this.jami.getAccount(req.params.accountId)
            if (account)
                res.json(account.getContacts())
            else
                res.status(404).end()
        })

        // Conversations
        accountRouter.get('/conversations', (req, res, next) => {
            console.log(`Get conversations for account ${req.params.accountId}`)
            const account = this.jami.getAccount(req.params.accountId)
            if (!account)
                return res.sendStatus(404)
            const conversations = account.getConversations()
            res.json(Object.keys(conversations).map(conversationId => conversations[conversationId].getObject({
                memberFilter: member => member.contact.getUri() !== account.getUri()
            })))
            //res.json(account.getConversations())
        })

        accountRouter.post('/conversations', (req, res, next) => {
            console.log(`Create conversations for account, contact ${req.params.accountId}`)
            console.log(req.body)
            const account = this.jami.getAccount(req.params.accountId)
            if (!account)
                return res.sendStatus(404)
            if (req.body.members.length === 1) {
                const details = this.jami.addContact(req.params.accountId, req.body.members[0])
                res.json(details)
            } else
                res.status(400).end()
        })

        accountRouter.get('/conversations/:conversationId', (req, res, next) => {
            console.log(`Get conversation ${req.params.conversationId} for account ${req.params.accountId}`)
            const account = this.jami.getAccount(req.params.accountId)
            if (!account)
                return res.sendStatus(404)
            const conversation = account.getConversation(req.params.conversationId)
            if (!conversation)
                res.status(404).end()
            else {
                res.json(conversation.getObject({
                    memberFilter: member => member.contact.getUri() !== account.getUri()
                }))
            }
        })

        // Nameserver
        const nsRouter = Router({mergeParams: true})
        accountRouter.use('/ns', nsRouter)

        nsRouter.get(['/name/:nameQuery'], (req, res, next) => {
            console.log(`Name lookup ${req.params.nameQuery}`)
            this.jami.lookupName(req.params.accountId, req.params.nameQuery)
                .then(result => {
                    if (result.state == 0)
                        res.json(result)
                    else if (result.state == 1)
                        res.sendStatus(400)
                    else
                        res.sendStatus(404)
                }).catch(e => {
                    res.sendStatus(404)
                })
        })
        nsRouter.get(['/addr/:addrQuery'], (req, res, next) => {
            console.log(`Address lookup ${req.params.addrQuery}`)
            this.jami.lookupAddress(req.params.accountId, req.params.addrQuery)
                .then(result => {
                    if (result.state == 0)
                        res.json(result)
                    else if (result.state == 1)
                        res.sendStatus(400)
                    else
                        res.sendStatus(404)
                }).catch(e => {
                    res.sendStatus(404)
                })
        })

        return router
    }
}

export default JamiRestApi
