import { and, eq } from "drizzle-orm"
import { db } from "../../../db/index.js"
import { appUsers, userInterfaceBindings } from "../../../db/schema.js"

export type AppUserRow = typeof appUsers.$inferSelect
export type BindingRow = typeof userInterfaceBindings.$inferSelect

export function listUserRows(): AppUserRow[] {
  return db.select().from(appUsers).all()
}

export function getUserRowById(id: string): AppUserRow | undefined {
  return db.select().from(appUsers).where(eq(appUsers.id, id)).limit(1).all()[0]
}

export function getUserRowByLogin(login: string): AppUserRow | undefined {
  return db.select().from(appUsers).where(eq(appUsers.login, login)).limit(1).all()[0]
}

export function createUserRow(values: typeof appUsers.$inferInsert): AppUserRow {
  const [inserted] = db.insert(appUsers).values(values).returning().all()
  return inserted
}

export function updateUserRowById(
  id: string,
  values: Partial<AppUserRow>,
): AppUserRow {
  const [updated] = db.update(appUsers).set(values).where(eq(appUsers.id, id)).returning().all()
  return updated
}

export function deleteUserRowById(id: string): void {
  db.delete(appUsers).where(eq(appUsers.id, id)).run()
}

export function listBindingRows(): BindingRow[] {
  return db.select().from(userInterfaceBindings).all()
}

export function listBindingRowsByUser(userId: string): BindingRow[] {
  return db.select().from(userInterfaceBindings).where(eq(userInterfaceBindings.userId, userId)).all()
}

export function getBindingRowById(id: string): BindingRow | undefined {
  return db.select().from(userInterfaceBindings).where(eq(userInterfaceBindings.id, id)).limit(1).all()[0]
}

export function getBindingByServerIfacePeer(
  serverId: number,
  interfaceName: string,
  peerPublicKey = "",
): BindingRow | undefined {
  return db
    .select()
    .from(userInterfaceBindings)
    .where(and(
      eq(userInterfaceBindings.serverId, serverId),
      eq(userInterfaceBindings.interfaceName, interfaceName),
      eq(userInterfaceBindings.peerPublicKey, peerPublicKey),
    ))
    .limit(1)
    .all()[0]
}

export function createBindingRow(values: typeof userInterfaceBindings.$inferInsert): BindingRow {
  const [inserted] = db.insert(userInterfaceBindings).values(values).returning().all()
  return inserted
}

export function deleteBindingRowById(id: string): void {
  db.delete(userInterfaceBindings).where(eq(userInterfaceBindings.id, id)).run()
}

export function countUserRows(): number {
  return db.select().from(appUsers).all().length
}
