import { NextRequest, NextResponse } from "next/server";
import { isAdminSession, hasPermission } from "@/lib/adminAuth";
import { getSessionClientId } from "@/lib/auth";
import { connectDB } from "@/lib/db";
import { Order } from "@/models/Order";
import { Client } from "@/models/Client";
import { GeneratedDocument } from "@/models/GeneratedDocument";
import { IntranetArticle } from "@/models/IntranetArticle";
import { PortfolioItem } from "@/models/PortfolioItem";
import { BlogPost } from "@/models/BlogPost";
import { Todo } from "@/models/Todo";

function escapeRegex(s: string) {
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}

// Durchsucht Aufträge, Kunden, Dokumente und Intranet-Beiträge auf einmal —
// Aufträge/Kunden/Dokumente jeweils nur, wenn die passende Berechtigung
// vorliegt, damit die Suche nicht mehr zeigt als die einzelnen Admin-Seiten
// es auch täten. Intranet-Beiträge sind dagegen wie auf der Intranet-Seite
// selbst für jede:n durchsuchbar, nur nach Abteilung gefiltert (siehe dort).
export async function GET(req: NextRequest) {
  if (!(await isAdminSession())) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  const q = (req.nextUrl.searchParams.get("q") || "").trim();
  if (q.length < 2) {
    return NextResponse.json({ orders: [], clients: [], documents: [], intranet: [], portfolio: [], blog: [], todos: [] });
  }

  const rx = new RegExp(escapeRegex(q), "i");
  await connectDB();

  const [hasOrders, hasClients, hasDocuments, canEditIntranet, hasPortfolio, hasBlog, canViewAllTodos, viewerId] = await Promise.all([
    hasPermission("orders_view"),
    hasPermission("clients_view"),
    hasPermission("documents_view"),
    hasPermission("intranet_edit"),
    hasPermission("portfolio_view"),
    hasPermission("blog_view"),
    hasPermission("todos_view"),
    getSessionClientId(),
  ]);
  const viewer = viewerId ? await Client.findById(viewerId).select("departmentId").lean() : null;
  const viewerDepartmentId = viewer?.departmentId ? String(viewer.departmentId) : null;

  const [orders, clients, documents, intranetArticles, portfolioItems, blogPosts, todos] = await Promise.all([
    hasOrders
      ? Order.aggregate([
          { $lookup: { from: "clients", localField: "clientId", foreignField: "_id", as: "client" } },
          { $unwind: { path: "$client", preserveNullAndEmptyArrays: true } },
          { $match: { $or: [{ characterOrConcept: rx }, { "client.name": rx }, { "client.email": rx }] } },
          { $limit: 6 },
          { $project: { characterOrConcept: 1, clientName: "$client.name" } },
        ])
      : [],
    hasClients ? Client.find({ role: "client", $or: [{ name: rx }, { email: rx }] }).select("name email").limit(6).lean() : [],
    hasDocuments
      ? GeneratedDocument.find({ $or: [{ templateName: rx }, { clientName: rx }] }).select("templateName clientName").limit(6).lean()
      : [],
    IntranetArticle.find({
      $or: [{ title: rx }, { content: rx }, { category: rx }],
      ...(canEditIntranet
        ? {}
        : {
            visible: true,
            $and: [
              {
                $or: [
                  { visibleToDepartmentIds: { $size: 0 } },
                  ...(viewerDepartmentId ? [{ visibleToDepartmentIds: viewerDepartmentId }] : []),
                ],
              },
            ],
          }),
    })
      .select("title category")
      .limit(6)
      .lean(),
    hasPortfolio
      ? PortfolioItem.find({ $or: [{ title: rx }, { titleEn: rx }, { tags: rx }] }).select("title category").limit(6).lean()
      : [],
    hasBlog ? BlogPost.find({ $or: [{ title: rx }, { titleEn: rx }, { tags: rx } ] }).select("title tags").limit(6).lean() : [],
    Todo.find({
      $and: [
        { $or: [{ title: rx }, { "notes.text": rx }] },
        ...(canViewAllTodos ? [] : [{ $or: [{ assignedToId: viewerId }, { createdById: viewerId }] }]),
      ],
    })
      .select("title priority")
      .limit(6)
      .lean(),
  ]);

  return NextResponse.json({
    orders: orders.map((o) => ({ id: String(o._id), label: o.characterOrConcept, sub: o.clientName || "" })),
    clients: clients.map((c) => ({ id: String(c._id), label: c.name, sub: c.email })),
    documents: documents.map((d) => ({ id: String(d._id), label: d.templateName, sub: d.clientName || "" })),
    intranet: intranetArticles.map((a) => ({ id: String(a._id), label: a.title, sub: a.category })),
    portfolio: portfolioItems.map((p) => ({ id: String(p._id), label: p.title, sub: p.category || "" })),
    blog: blogPosts.map((b) => ({ id: String(b._id), label: b.title, sub: (b.tags || []).slice(0, 2).join(", ") })),
    todos: todos.map((t) => ({ id: String(t._id), label: t.title, sub: t.priority || "" })),
  });
}
