import { Router } from "express";
import { z } from "zod";
import { requireAuth } from "../../middleware/auth.js";
import { validateBody, validateQuery } from "../../middleware/validate.js";
import { hasPublishRight, createPost, listPosts, removePost, myNotifications, markNotificationsRead } from "./service.js";
import { forbidden } from "../../lib/errors.js";

export const socialRouter = Router();
// Reading the feed and notifications: any signed-in active user
socialRouter.use(requireAuth);

socialRouter.get(
  "/posts",
  validateQuery(z.object({ page: z.coerce.number().int().min(1).default(1) })),
  async (req, res, next) => {
    try {
      const { page } = res.locals.validatedQuery as { page: number };
      res.json(await listPosts(page));
    } catch (error) {
      next(error);
    }
  },
);

// Publishing requires the social.publish right (assigned by the central
// qualitative secretariat secretary through role management — owner decision)
socialRouter.post("/posts", requirePublishRight, validateBody(z.object({ body: z.string().min(3).max(4000) })), async (req, res, next) => {
  try {
    res.status(201).json(await createPost(req, (req.body as { body: string }).body));
  } catch (error) {
    next(error);
  }
});

socialRouter.post("/posts/:id/remove", validateBody(z.object({ reason: z.string().min(3).max(500) })), async (req, res, next) => {
  try {
    const id = z.coerce.number().int().positive().parse(req.params.id);
    const reason = (req.body as { reason: string }).reason;
    await removePost(req, id, reason);
    res.json({ ok: true });
  } catch (error) {
    next(error);
  }
});

socialRouter.get("/notifications", async (req, res, next) => {
  try {
    res.json(await myNotifications(req.user!.id));
  } catch (error) {
    next(error);
  }
});

socialRouter.post("/notifications/read-all", async (req, res, next) => {
  try {
    await markNotificationsRead(req.user!.id);
    res.json({ ok: true });
  } catch (error) {
    next(error);
  }
});

async function requirePublishRight(req: import("express").Request, _res: unknown, next: (err?: unknown) => void): Promise<void> {
  if (!(await hasPublishRight(req.user!.id))) {
    next(forbidden("النشر بأمر أمين الأمانة النوعية المركزية لمن يعيّنهم"));
    return;
  }
  next();
}
