import {eq, inArray, sql} from 'drizzle-orm'
import {HTTPException} from 'hono/http-exception'

import {db, schema} from '../db/client'
import {publicImageUrl} from '../lib/source-image'
import {countInt} from '../lib/sql'

// target-existence guard shared by user-directed writes (friend request,
// trail invite, dm open): a missing target 404s before any relation check
export const requireUserExists = async (
  userId: string,
): Promise<void> => {
  const [row] = await db
    .select({id: schema.users.id})
    .from(schema.users)
    .where(eq(schema.users.id, userId))
    .limit(1)
  if (!row) throw new HTTPException(404, {message: 'not_found'})
}

// count + newest item name in one pass, shared by crumb and trail stats
export const authorStats = async (
  table: typeof schema.crumbs | typeof schema.trails,
  authorId: string,
) => {
  const [row] = await db
    .select({
      count: countInt(),
      preview: sql<
        string | null
      >`(array_agg(${table.name} order by ${table.createdAt} desc))[1]`,
    })
    .from(table)
    .where(eq(table.authorId, authorId))
  return {count: row?.count ?? 0, preview: row?.preview ?? null}
}

export type UserSummary = {
  id: string
  handle: string
  avatarUrl: string | null
}

// minimal display identity (id, handle, avatar) keyed by id, for author
// and peer hydration
export const loadUserSummaries = async (
  ids: string[],
): Promise<Map<string, UserSummary>> => {
  if (!ids.length) return new Map()
  const rows = await db
    .select({
      id: schema.users.id,
      handle: schema.users.handle,
      avatarRef: schema.users.avatarRef,
    })
    .from(schema.users)
    .where(inArray(schema.users.id, ids))
  return new Map(
    rows.map((r) => [
      r.id,
      {
        id: r.id,
        handle: r.handle,
        avatarUrl: publicImageUrl(r.avatarRef),
      },
    ]),
  )
}
