import { createHmac, timingSafeEqual } from 'node:crypto'

const TOKEN_COOKIE = 'admin_token'
const TOKEN_MAX_AGE = 60 * 60 * 24 // 24h

export function signToken(payload: string, secret: string): string {
  const hmac = createHmac('sha256', secret)
  hmac.update(payload)
  return payload + '.' + hmac.digest('hex')
}

export function verifyToken(token: string, secret: string): string | null {
  const dotIndex = token.lastIndexOf('.')
  if (dotIndex === -1) return null

  const payload = token.slice(0, dotIndex)
  const expected = signToken(payload, secret)

  const a = Buffer.from(token)
  const b = Buffer.from(expected)

  if (a.length !== b.length) return null
  if (!timingSafeEqual(a, b)) return null

  // Check expiry
  try {
    const data = JSON.parse(payload)
    if (data.exp && data.exp < Math.floor(Date.now() / 1000)) return null
    return payload
  }
  catch {
    return null
  }
}

export function setAdminCookie(event: any, secret: string): void {
  const exp = Math.floor(Date.now() / 1000) + TOKEN_MAX_AGE
  const payload = JSON.stringify({ role: 'admin', exp })
  const token = signToken(payload, secret)

  setCookie(event, TOKEN_COOKIE, token, {
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    sameSite: 'lax',
    maxAge: TOKEN_MAX_AGE,
    path: '/',
  })
}

export function clearAdminCookie(event: any): void {
  deleteCookie(event, TOKEN_COOKIE, { path: '/' })
}

export function getAdminToken(event: any): string | null {
  return getCookie(event, TOKEN_COOKIE) ?? null
}
