// Auth-provider config store. Thin logic layer over authProviders.db, mirroring
// the users model split. Owns encryption of the client secret at the boundary so
// the DB layer only ever sees ciphertext and callers only ever see the decrypted
// secret when they explicitly ask (getWithSecret) — the plain list/get paths
// never surface it.

const db = require('./authProviders.db')
const secretBox = require('../../utils/secretBox')

// All configured provider rows (secret column left as ciphertext; callers that
// need the secret use getWithSecret).
async function list() {
  return db.list()
}

async function get(id) {
  return db.get(id)
}

// Provider row with the client secret decrypted (server-side only — used by the
// registry at token-exchange time). Returns null if the provider does not exist.
async function getWithSecret(id) {
  const row = await db.get(id)
  if (!row) return null
  return { ...row, client_secret: row.client_secret_enc ? secretBox.decrypt(row.client_secret_enc) : null }
}

// Create/update a provider. `secret` (raw) is encrypted here; pass secret ===
// undefined to leave an existing secret untouched, or '' to keep it unchanged as
// well (blank means "no change" from the admin UI). Returns the stored row.
async function save(id, { kind, name, enabled, clientId, secret, authorizeUrl, tokenUrl, userinfoUrl, scopes, priority }) {
  const fields = {}
  if (kind !== undefined) fields.kind = kind
  if (name !== undefined) fields.name = name
  if (enabled !== undefined) fields.enabled = enabled ? 1 : 0
  if (clientId !== undefined) fields.client_id = clientId
  if (secret) fields.client_secret_enc = secretBox.encrypt(secret) // only when a new secret is given
  if (authorizeUrl !== undefined) fields.authorize_url = authorizeUrl
  if (tokenUrl !== undefined) fields.token_url = tokenUrl
  if (userinfoUrl !== undefined) fields.userinfo_url = userinfoUrl
  if (scopes !== undefined) fields.scopes = scopes
  if (priority !== undefined) fields.priority = priority
  return db.upsert(id, fields)
}

async function remove(id) {
  return db.remove(id)
}

module.exports = { list, get, getWithSecret, save, remove }
