import {randomBytes} from 'node:crypto'

import {and, eq, gt} from 'drizzle-orm'

import {db, schema} from '../db/client'
import {sha256} from '../lib/hash'

const TTL_MS = 1000 * 60 * 60 * 24 * 30 // 30 days

export const createSession = async (
  userId: string,
): Promise<string> => {
  const raw = randomBytes(32).toString('base64url')
  const expiresAt = new Date(Date.now() + TTL_MS)
  await db.insert(schema.sessions).values({
    userId,
    tokenHash: sha256(raw),
    expiresAt,
  })
  return raw
}

export const resolveSession = async (raw: string) => {
  const hash = sha256(raw)
  const [row] = await db
    .select({
      session: schema.sessions,
      user: schema.users,
    })
    .from(schema.sessions)
    .innerJoin(
      schema.users,
      eq(schema.sessions.userId, schema.users.id),
    )
    .where(
      and(
        eq(schema.sessions.tokenHash, hash),
        gt(schema.sessions.expiresAt, new Date()),
      ),
    )
    .limit(1)
  return row ?? null
}

export const deleteSession = async (raw: string) => {
  await db
    .delete(schema.sessions)
    .where(eq(schema.sessions.tokenHash, sha256(raw)))
}
