import express from 'express';
import passport from 'passport';
import { MongoUser } from '../shared/models/user';
import { DB_NAME } from '../db-utils';
import { getDatabaseClient } from '../db-utils';
import { ObjectId } from 'bson';
import { MongoCategory } from '..//shared/models/category';

export const categoryRoutes = express.Router();

export const jwtAuthentication = passport.authenticate('jwt', { session: false });

// Get Category Details
categoryRoutes.get('/details/', jwtAuthentication, async (request, response) => {
    const categoryCollection = getDatabaseClient().db(DB_NAME).collection<MongoCategory>('categories');


    if (!request.query._id) {
        response.status(400);
        response.send("Missing category _id");
        return;
    }

    const currentCategory = await categoryCollection.findOne({
        _id: new ObjectId(request.query._id.toString()),
    });

    if (currentCategory) {
        response.status(200);
        response.json(currentCategory);
    } else {
        response.status(400);
        response.send("Category ID did not match");
    }

    return;
});


// Add category
categoryRoutes.post('/add/', jwtAuthentication, async (request, response) => {
    const user: MongoUser = (request.user as any);

    const categoryCollection = getDatabaseClient().db(DB_NAME).collection<MongoCategory>('categories');
    const userCollection = getDatabaseClient().db(DB_NAME).collection<MongoUser>('users');

    if (!request.body.name) {
        response.status(400);
        response.send("Category Name missing");
        return;
    }
    
    try {
        const newCategory = await categoryCollection.insertOne({
            name: request.body.name,
            icon: request.body.icon ? request.body.icon : "",
            isArchived: false,
        });

        if (!user.categories) {
            user.categories = [];
        }

        user.categories.push(newCategory.insertedId.toHexString());

        await userCollection.updateOne({
            _id: user._id
        }, {
            $set: {
                categories: user.categories
            }
        });
        
        response.status(200);
        response.send(newCategory.insertedId.toHexString());
    } catch(e) {
        response.sendStatus(500);
        return;
    }

    return;
});


// Update category
categoryRoutes.put('/update/', jwtAuthentication, async (request, response) => {
    const categoryCollection = getDatabaseClient().db(DB_NAME).collection('categories');

    const currentCategory = await categoryCollection.findOne({
        _id: new ObjectId(request.body._id)
    });

    if (!currentCategory) {
        response.status(400);
        response.send("Category ID did not match");
        return;
    }

    if (request.body.isArchived) {
        if (typeof request.body.isArchived !== "boolean") {
            response.status(400);
            response.send("Archived should be a boolean flag");
            return;
        }
    }

    try {
        await categoryCollection.updateOne({
            _id: new ObjectId(request.body._id),
        }, {
            $set: {
                name: request.body.name ? request.body.name : currentCategory.name,
                icon: request.body.icon ? request.body.icon : currentCategory.icon,
                isArchived: request.body.isArchived !== undefined ? request.body.isArchived : currentCategory.isArchived
            }
        });

        response.sendStatus(200);

    } catch (e) {
        response.status(400);
        response.send(e.toString());
    }

    return;
});
