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

import { protectedProcedure, router } from "../index";
import { byIdSchema, noteCreateSchema, noteListSchema, noteUpdateSchema } from "./schemas";
import {
  createEntityId,
  requireNote,
  requireServer,
  stripUndefined,
} from "./utils";

export const notesRouter = router({
  list: protectedProcedure.input(noteListSchema).query(async ({ input }) => {
    if (!input?.serverId) {
      return db.select().from(note).orderBy(desc(note.createdAt), desc(note.id));
    }

    await requireServer(input.serverId);

    return db
      .select()
      .from(note)
      .where(eq(note.serverId, input.serverId))
      .orderBy(desc(note.createdAt), desc(note.id));
  }),

  byId: protectedProcedure.input(byIdSchema).query(async ({ input }) => {
    return requireNote(input.id);
  }),

  create: protectedProcedure.input(noteCreateSchema).mutation(async ({ input }) => {
    await requireServer(input.serverId);

    const [created] = await db
      .insert(note)
      .values({
        id: createEntityId(),
        ...input,
      })
      .returning();

    return created;
  }),

  update: protectedProcedure.input(noteUpdateSchema).mutation(async ({ input }) => {
    const { id, serverId, ...changes } = input;
    await requireNote(id);

    if (serverId) {
      await requireServer(serverId);
    }

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

    return updated;
  }),

  delete: protectedProcedure.input(byIdSchema).mutation(async ({ input }) => {
    await requireNote(input.id);
    await db.delete(note).where(eq(note.id, input.id));
    return { id: input.id };
  }),

  serverOptions: protectedProcedure.query(async () => {
    return db
      .select({
        id: server.id,
        name: server.name,
      })
      .from(server)
      .orderBy(desc(server.updatedAt));
  }),
});
