import { db } from "@minmon/db";
import { note, server, service } from "@minmon/db";
import { count, desc, eq } from "drizzle-orm";

import { permissionedProcedure, router } from "../index";
import { byIdSchema, serverCreateSchema, serverUpdateSchema } from "./schemas";
import { createEntityId, requireServer, stripUndefined } from "./utils";

export const serversRouter = router({
  list: permissionedProcedure("servers.read").query(async () => {
    return db.select().from(server).orderBy(desc(server.createdAt), desc(server.id));
  }),

  byId: permissionedProcedure("servers.read").input(byIdSchema).query(async ({ input }) => {
    const item = await requireServer(input.id);

    const [serviceCount, noteCount] = await Promise.all([
      db.select({ count: count() }).from(service).where(eq(service.serverId, input.id)),
      db.select({ count: count() }).from(note).where(eq(note.serverId, input.id)),
    ]);

    return {
      ...item,
      summary: {
        services: serviceCount[0]?.count ?? 0,
        notes: noteCount[0]?.count ?? 0,
      },
    };
  }),

  create: permissionedProcedure("servers.create").input(serverCreateSchema).mutation(async ({ input }) => {
    const [created] = await db
      .insert(server)
      .values({
        id: createEntityId(),
        ...input,
      })
      .returning();

    return created;
  }),

  update: permissionedProcedure("servers.update").input(serverUpdateSchema).mutation(async ({ input }) => {
    const { id, ...changes } = input;
    await requireServer(id);

    const [updated] = await db
      .update(server)
      .set(stripUndefined(changes))
      .where(eq(server.id, id))
      .returning();

    return updated;
  }),

  delete: permissionedProcedure("servers.delete").input(byIdSchema).mutation(async ({ input }) => {
    await requireServer(input.id);
    await db.delete(server).where(eq(server.id, input.id));
    return { id: input.id };
  }),
});
