import { Request, Router } from "express";
import { GetUserMiddleware } from "../middlewares/user.js";
import { HttpStatusCode } from "../../helper/request_error.js";
import promiseMiddleware from "../../helper/promiseMiddleware.js";
import User from "../../models/user.js";
import Mail from "../../models/mail.js";
import RefreshToken from "../../models/refresh_token.js";
import LoginToken from "../../models/login_token.js";

const UserRoute: Router = Router();
UserRoute.use(GetUserMiddleware(true, true), (req: Request, res, next) => {
   if (!req.isAdmin) res.sendStatus(HttpStatusCode.FORBIDDEN);
   else next();
});

UserRoute.route("/")
   /**
    * @api {get} /admin/user
    * @apiName AdminGetUsers
    *
    * @apiGroup admin_user
    * @apiPermission admin
    * @apiSuccess {Object[]} user
    * @apiSuccess {String} user._id The internal id of the user
    * @apiSuccess {String} user.uid The public UID of the user
    * @apiSuccess {String} user.username The username
    * @apiSuccess {String} user.name The real name
    * @apiSuccess {Date} user.birthday The birthday
    * @apiSuccess {Number} user.gender 0 = none, 1 = male, 2 = female, 3 = other
    * @apiSuccess {Boolean} user.admin Is admin or not
    */
   .get(
      promiseMiddleware(async (req, res) => {
         let users = await User.find({});
         users.forEach(
            (e) => delete e.password && delete e.salt && delete e.encryption_key
         );
         res.json(users);
      })
   )
   /**
    * @api {delete} /admin/user
    * @apiName AdminDeleteUser
    *
    * @apiParam {String} id The User ID
    *
    * @apiGroup admin_user
    * @apiPermission admin
    *
    * @apiSuccess {Boolean} success
    */
   .delete(
      promiseMiddleware(async (req, res) => {
         let { id } = req.query as { [key: string]: string };
         let user = await User.findById(id);

         await Promise.all([
            user.mails.map((mail) => Mail.delete(mail)),
            [
               RefreshToken.deleteFilter({ user: user._id }),
               LoginToken.deleteFilter({ user: user._id }),
            ],
         ]);

         await User.delete(user);
         res.json({ success: true });
      })
   )
   /**
    * @api {put} /admin/user
    * @apiName AdminChangeUser
    *
    * @apiParam {String} id The User ID
    *
    * @apiGroup admin_user
    * @apiPermission admin
    *
    * @apiSuccess {Boolean} success
    *
    * @apiDescription Flipps the user role:
    * admin -> user
    * user -> admin
    */
   .put(
      promiseMiddleware(async (req, res) => {
         let { id } = req.query as { [key: string]: string };
         let user = await User.findById(id);
         user.admin = !user.admin;
         await User.save(user);
         res.json({ success: true });
      })
   );
export default UserRoute;
