import {and, eq, inArray, sql} from 'drizzle-orm';
import {reactions} from '@db/schema';
import {db} from '@db/instance';

import {InsertReaction} from '../interfaces';

export const insertReactions = async (values: InsertReaction[]) => {
  if (!values.length) {
    return;
  }

  return await db.instance
    .insert(reactions)
    .values(values)
    .onConflictDoNothing();
};

export const deleteReaction = async (
  messageId: string,
  userId: number,
  reaction: string,
) => {
  return await db.instance
    .delete(reactions)
    .where(
      and(
        eq(reactions.message_id, messageId),
        eq(reactions.user_id, userId),
        eq(reactions.name, reaction),
      ),
    );
};

export const getMessageReactionsRanked = async (messageId: string) => {
  return await db.instance
    .select({
      name: reactions.name,
      count: sql<number>`count(*)`.as('count'),
      first_ts: sql<string>`min(reactions.ts)`.as('first_ts'),
    })
    .from(reactions)
    .where(eq(reactions.message_id, messageId))
    .groupBy(reactions.name)
    .orderBy(sql`count(*) desc`, sql`first_ts asc`);
};

export const getUserReactions = async (messageId: string, userId: number) => {
  return await db.instance.query.reactions.findMany({
    where: and(
      eq(reactions.message_id, messageId),
      eq(reactions.user_id, userId),
    ),
  });
};

export const getMessageReactions = async (messageId: string) => {
  return await db.instance
    .select()
    .from(reactions)
    .where(eq(reactions.message_id, messageId));
};

export const deleteMessageReactions = async (messageId: string) => {
  return await db.instance
    .delete(reactions)
    .where(eq(reactions.message_id, messageId));
};

export const deleteMessageReactionsBatch = async (messageIds: string[]) => {
  return await db.instance
    .delete(reactions)
    .where(inArray(reactions.message_id, messageIds));
};
