/* ----------------------------------------------------------------------------

 Question Server
 GitLab: <https://gitlab.com/MrFry/mrfrys-node-server>

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program. If not, see <https://www.gnu.org/licenses/>.

 ------------------------------------------------------------------------- */

import logger from '../../../utils/logger'
import utils from '../../../utils/utils'
import { Request, SubmoduleData, User } from '../../../types/basicTypes'

interface Subjects {
    [key: string]: number
}

interface IdStat {
    count: number
    newQuestions: number
    allQuestions: number
    subjs: Subjects
}

interface IdStats {
    [key: string]: IdStat
}

interface IdStatWithUID extends IdStat {
    userId: number
}

const idStatFile = 'stats/idstats'
const idvStatFile = 'stats/idvstats'

function mergeObjSum(a: Subjects, b: Subjects) {
    const res = { ...b }
    Object.keys(a).forEach((key) => {
        if (res[key]) {
            res[key] += a[key]
        } else {
            res[key] = a[key]
        }
    })

    return res
}

function setup(data: SubmoduleData): void {
    const { app /* userDB, url, publicdirs, moduleSpecificData */ } = data

    app.get('/ranklist', (req: Request, res) => {
        logger.LogReq(req)
        let result: IdStats
        const querySince: string = req.query.since
        const user: User = req.session.user

        if (!querySince) {
            result = utils.ReadJSON(idStatFile)
        } else {
            try {
                const since = new Date(querySince)
                if (!(since instanceof Date) || isNaN(since.getTime())) {
                    throw new Error('Not a date')
                }
                const data = utils.ReadJSON(idvStatFile)
                result = {}

                Object.keys(data).forEach((key) => {
                    const dailyStat = data[key]

                    if (new Date(key) > since) {
                        Object.keys(dailyStat).forEach((userId) => {
                            const userStat = dailyStat[userId]
                            const uidRes = result[userId]

                            if (!uidRes) {
                                result[userId] = userStat
                            } else {
                                result[userId] = {
                                    count: uidRes.count + userStat.count,
                                    newQuestions:
                                        uidRes.newQuestions +
                                        userStat.newQuestions,
                                    allQuestions:
                                        uidRes.allQuestions +
                                        userStat.allQuestions,
                                    subjs: mergeObjSum(
                                        uidRes.subjs,
                                        userStat.subjs
                                    ),
                                }
                            }
                        })
                    }
                })
            } catch (err) {
                res.json({
                    msg: 'invalid date format, or other error occured',
                })
            }
        }

        const list: Array<IdStatWithUID> = []
        const sum = {
            count: 0,
            newQuestions: 0,
            allQuestions: 0,
        }
        Object.keys(result).forEach((key) => {
            list.push({
                userId: parseInt(key),
                ...result[key],
            })

            sum.count = sum.count + result[key].count
            sum.newQuestions = sum.newQuestions + result[key].newQuestions
            sum.allQuestions = sum.allQuestions + result[key].allQuestions
        })

        if (list.length === 0) {
            res.json({
                msg: 'There are no users in the stats db :c',
            })
            return
        }

        res.json({
            since: querySince,
            sum: sum,
            list: list,
            selfuserId: user.id,
        })
    })
}

export default {
    setup: setup,
}
