import { Request, Router } from "express";
import RequestError, { HttpStatusCode } from "../../helper/request_error.js";
import promiseMiddleware from "../../helper/promiseMiddleware.js";
import Permission from "../../models/permissions.js";
import verify, { Types } from "../middlewares/verify.js";
import Client from "../../models/client.js";
import { ObjectId } from "bson";

const PermissionRoute: Router = Router();
PermissionRoute.route("/")
   /**
    * @api {get} /admin/permission
    * @apiName AdminGetPermissions
    *
    * @apiParam client Optionally filter by client _id
    *
    * @apiGroup admin_permission
    * @apiPermission admin
    *
    * @apiSuccess {Object[]} permissions
    * @apiSuccess {String} permissions._id The ID
    * @apiSuccess {String} permissions.name Permission name
    * @apiSuccess {String} permissions.description A description, that makes it clear to the user, what this Permission allows to do
    * @apiSuccess {String} permissions.client The ID of the owning client
    */
   .get(
      promiseMiddleware(async (req, res) => {
         let query = {};
         if (req.query.client) {
            query = { client: new ObjectId(req.query.client as string) };
         }
         let permissions = await Permission.find(query);
         res.json(permissions);
      })
   )
   /**
    * @api {post} /admin/permission
    * @apiName AdminAddPermission
    *
    * @apiParam client The ID of the owning client
    * @apiParam name Permission name
    * @apiParam description A description, that makes it clear to the user, what this Permission allows to do
    *
    * @apiGroup admin_permission
    * @apiPermission admin
    *
    * @apiSuccess {Object[]} permissions
    * @apiSuccess {String} permissions._id The ID
    * @apiSuccess {String} permissions.name Permission name
    * @apiSuccess {String} permissions.description A description, that makes it clear to the user, what this Permission allows to do
    * @apiSuccess {String} permissions.client The ID of the owning client
    * @apiSuccess {String} permissions.grant_type The type of the permission. "user" | "client" granted
    */
   .post(
      verify(
         {
            client: {
               type: Types.STRING,
            },
            name: {
               type: Types.STRING,
            },
            description: {
               type: Types.STRING,
            },
            type: {
               type: Types.ENUM,
               values: ["user", "client"],
            },
         },
         true
      ),
      promiseMiddleware(async (req, res) => {
         let client = await Client.findById(req.body.client);
         if (!client) {
            throw new RequestError(
               "Client not found",
               HttpStatusCode.BAD_REQUEST
            );
         }
         let permission = Permission.new({
            description: req.body.description,
            name: req.body.name,
            client: client._id,
            grant_type: req.body.type,
         });
         await Permission.save(permission);
         res.json(permission);
      })
   )
   /**
    * @api {delete} /admin/permission
    * @apiName AdminDeletePermission
    *
    * @apiParam id The permission ID
    *
    * @apiGroup admin_permission
    * @apiPermission admin
    *
    * @apiSuccess {Boolean} success
    */
   .delete(
      promiseMiddleware(async (req, res) => {
         let { id } = req.query as { [key: string]: string };
         await Permission.delete(id);
         res.json({ success: true });
      })
   );

export default PermissionRoute;
