import { Router, Request, Response, NextFunction } from "express";
import { TagHandler } from "../../handlers/TagHandler.js";
import { TagDto } from "../dtos/TagDto.js";
import {HttpStatusCode} from "../apiHelpers/HttpStatusCodes.js";
import {requireAdmin} from "../../middleware/authorizationMiddleware.js";

/**
 * REST resource for tags.
 *
 * Routes:
 *   GET    /tags                    — list all tags (authenticated users)
 *   POST   /tags/create-or-update   — create or update a tag (authenticated users)
 *   DELETE /tags/:id                — delete a tag (administrators only)
 *
 * Authentication / authorisation is assumed to be enforced by middleware
 * applied upstream (e.g. a global JWT guard). The adminOnly middleware below
 * adds the role check that restricts DELETE to administrators.
 */
export const tagBasicRoute = "/tag";
const router = Router();
const tagHandler = new TagHandler();


/**
 * GET /tags
 * Returns all available tags.
 */
router.get("/all", async (_req: Request, res: Response, next: NextFunction) => {
    try {
        const tags = await tagHandler.getAll();
        res.json(tags);
    } catch (err) {
        next(err);
    }
});

/**
 * POST /tags/create-or-update
 * Creates a new tag or updates an existing one.
 * If a tag with the given descriprion already exists in the database, that tag is returned instead of creating
 * a duplicate.
 * Body: TagDto
 */
router.post(
    "/create-or-update",
    async (req: Request, res: Response, next: NextFunction) => {
        try {
            const dto: TagDto = req.body;
            const result = await tagHandler.createOrUpdate(dto);
            res.status(HttpStatusCode.CREATED).json(result);
        } catch (err) {
            next(err);
        }
    }
);

/**
 * DELETE /tags/:id
 * Deletes a tag by ID. Restricted to administrators.
 * The database cascade removes all entries in the recipe_tag mapping table.
 */
router.delete(
    "/:id",
    requireAdmin,
    async (req: Request, res: Response, next: NextFunction) => {
        try {
            await tagHandler.delete(req.params.id);
            res.status(HttpStatusCode.NO_CONTENT).send();
        } catch (err) {
            next(err);
        }
    }
);

export default router;