import { eq, and } from "drizzle-orm";
import { database } from "~/database/context";
import * as schema from "~/database/schema";
import { isUserAdminByClerkId } from "~/models/user";

export type Commissioner = typeof schema.commissioners.$inferSelect;
export type NewCommissioner = typeof schema.commissioners.$inferInsert;

export async function createCommissioner(
  data: NewCommissioner
): Promise<Commissioner> {
  const db = database();
  const [commissioner] = await db
    .insert(schema.commissioners)
    .values(data)
    .returning();
  return commissioner;
}

export async function findCommissionersByLeagueId(
  leagueId: string
): Promise<Commissioner[]> {
  const db = database();
  return await db.query.commissioners.findMany({
    where: eq(schema.commissioners.leagueId, leagueId),
    orderBy: (commissioners, { asc }) => [asc(commissioners.createdAt)],
  });
}

export async function findCommissionersByUserId(
  userId: string
): Promise<Commissioner[]> {
  const db = database();
  return await db.query.commissioners.findMany({
    where: eq(schema.commissioners.userId, userId),
    orderBy: (commissioners, { desc }) => [desc(commissioners.createdAt)],
  });
}

export async function hasCommissionerRecord(
  leagueId: string,
  userId: string
): Promise<boolean> {
  const db = database();
  const commissioner = await db.query.commissioners.findFirst({
    where: and(
      eq(schema.commissioners.leagueId, leagueId),
      eq(schema.commissioners.userId, userId)
    ),
  });
  return !!commissioner;
}

export async function isCommissioner(
  leagueId: string,
  userId: string
): Promise<boolean> {
  const db = database();
  const [isAdmin, commissioner] = await Promise.all([
    isUserAdminByClerkId(userId),
    db.query.commissioners.findFirst({
      where: and(
        eq(schema.commissioners.leagueId, leagueId),
        eq(schema.commissioners.userId, userId)
      ),
    }),
  ]);
  return isAdmin || !!commissioner;
}

export async function countCommissionersByLeagueId(
  leagueId: string
): Promise<number> {
  const db = database();
  const commissioners = await db.query.commissioners.findMany({
    where: eq(schema.commissioners.leagueId, leagueId),
  });
  return commissioners.length;
}

export async function deleteCommissioner(id: string): Promise<void> {
  const db = database();
  await db.delete(schema.commissioners).where(eq(schema.commissioners.id, id));
}

export async function removeCommissionerByLeagueAndUser(
  leagueId: string,
  userId: string
): Promise<void> {
  const db = database();
  await db
    .delete(schema.commissioners)
    .where(
      and(
        eq(schema.commissioners.leagueId, leagueId),
        eq(schema.commissioners.userId, userId)
      )
    );
}
