import { WaitlistMessage } from "@/models/WaitlistMessage";
import { Client } from "@/models/Client";
import { Department } from "@/models/Department";
import { Position } from "@/models/Position";
import type { OrderChatMessage } from "@/components/orders/OrderChat";

const OBJECT_ID_RE = /^[0-9a-f]{24}$/i;

export async function getWaitlistChatMessagesByEntryId(entryIds: string[]): Promise<Map<string, OrderChatMessage[]>> {
  const messages = await WaitlistMessage.find({ waitlistEntryId: { $in: entryIds } })
    .sort({ createdAt: 1 })
    .lean();

  const senderIds = [...new Set(messages.map((m) => String(m.senderId)))].filter((id) => OBJECT_ID_RE.test(id));
  const senders = await Client.find({ _id: { $in: senderIds } }).lean();
  const senderById = new Map(senders.map((s) => [String(s._id), s]));

  const [departments, positions] = await Promise.all([Department.find({}).lean(), Position.find({}).lean()]);
  const departmentById = new Map(departments.map((d) => [String(d._id), d]));
  const positionById = new Map(positions.map((p) => [String(p._id), p]));

  const byEntryId = new Map<string, OrderChatMessage[]>();
  for (const m of messages) {
    const sender = senderById.get(String(m.senderId));
    let senderTitle = "";
    if (sender?.role === "staff") {
      const position = sender.positionId ? positionById.get(String(sender.positionId)) : undefined;
      const department = sender.departmentId ? departmentById.get(String(sender.departmentId)) : undefined;
      senderTitle = [position?.name, department?.name].filter(Boolean).join(" · ");
    }
    const chatMessage: OrderChatMessage = {
      id: String(m._id),
      senderId: String(m.senderId),
      text: m.text,
      createdAt: new Date(m.createdAt).toISOString(),
      senderName: sender?.nickname || sender?.firstName || sender?.name || "?",
      senderAvatarPath: sender?.avatarPath || "",
      senderTitle,
    };
    const key = String(m.waitlistEntryId);
    byEntryId.set(key, [...(byEntryId.get(key) ?? []), chatMessage]);
  }
  return byEntryId;
}
