import { Router } from "express";
import { z } from "zod";
import { ContactMessage, User } from "@/db/models";
import { asyncHandler } from "@/lib/errors";
import { requireAuth, requireRoles } from "@/middleware/auth";
import { notifyUser } from "@/services/notifications";
import { toPlain } from "@/lib/serialize";
import { isContactMysql } from "@/db/activeDatabase";
import {
  contactToApi,
  createContactMysql,
  listAdminUserIdsMysql,
  listContactMysql,
} from "@/db/mysql/contact";

export const contactRouter = Router();

contactRouter.post(
  "/",
  asyncHandler(async (req, res) => {
    const body = z
      .object({
        name: z.string().min(2),
        email: z.string().email(),
        subject: z.string().min(3),
        message: z.string().min(10),
        userId: z.string().optional(),
      })
      .parse(req.body);

    if (isContactMysql()) {
      const msg = await createContactMysql(body);
      // Notify admins: prefer MySQL admin ids; notifications service may still use Mongo
      // until notifications module is migrated — skip notify failures silently if Mongo-only.
      try {
        const adminIds = await listAdminUserIdsMysql();
        await Promise.all(
          adminIds.map((userId) =>
            notifyUser({
              userId,
              titleAr: "رسالة تواصل جديدة",
              titleEn: "New contact message",
              messageAr: body.subject,
              messageEn: body.subject,
              link: "/admin/messages",
            }).catch(() => undefined),
          ),
        );
      } catch {
        /* notifications may still be mongo-backed */
      }
      res.status(201).json({ message: contactToApi(msg), _db: "mysql" });
      return;
    }

    const msg = await ContactMessage.create({
      name: body.name,
      email: body.email,
      subject: body.subject,
      message: body.message,
      userId: body.userId ?? undefined,
    });

    const admins = await User.find({ role: "ADMIN", deletedAt: null }).select("_id").lean();
    await Promise.all(
      admins.map((admin) =>
        notifyUser({
          userId: admin._id,
          titleAr: "رسالة تواصل جديدة",
          titleEn: "New contact message",
          messageAr: body.subject,
          messageEn: body.subject,
          link: "/admin/messages",
        }),
      ),
    );

    res.status(201).json({ message: toPlain(msg.toObject()), _db: "mongodb" });
  }),
);

contactRouter.get(
  "/",
  requireAuth,
  requireRoles("ADMIN"),
  asyncHandler(async (_req, res) => {
    if (isContactMysql()) {
      const messages = await listContactMysql(100);
      res.json({ messages: messages.map(contactToApi), _db: "mysql" });
      return;
    }

    const messages = await ContactMessage.find().sort({ createdAt: -1 }).limit(100).lean();
    res.json({ messages: messages.map(toPlain), _db: "mongodb" });
  }),
);
