/**
 * TOTP API helpers (M4-T08).
 *
 * All calls go through the typed apiClient (openapi-fetch + generated schema).
 * CSRF tokens are injected automatically by the client middleware for write
 * endpoints; GET /api/auth/totp needs no CSRF (read-only).
 *
 * Security notes:
 * - The TotpSetupResponse contains secret + recovery_codes in plaintext.
 *   These are kept only in component state; callers must NOT write them to
 *   localStorage, sessionStorage, or log them.
 * - After the setup phase is over the data leaves memory when the component
 *   re-renders (one-time display only).
 */

import apiClient, { ApiError } from '../api/client'
import type { components } from '../api/schema.d.ts'

export type TotpSetupResponse = components['schemas']['TotpSetupResponse']
export type TotpStatusResponse = components['schemas']['TotpStatusResponse']

// ---------------------------------------------------------------------------
// getTotpStatus — GET /api/auth/totp
// ---------------------------------------------------------------------------

/** Return the current TOTP enabled state for the authenticated user. */
export async function getTotpStatus(): Promise<TotpStatusResponse> {
  const res = await apiClient.GET('/api/auth/totp')
  if (!res.data) {
    throw new ApiError(res.response.status, null)
  }
  return res.data
}

// ---------------------------------------------------------------------------
// setupTotp — POST /api/auth/totp/setup
// ---------------------------------------------------------------------------

/**
 * Generate a new pending TOTP secret + recovery codes.
 * Returns the one-time plaintext values; caller is responsible for displaying
 * them exactly once and never persisting them outside component state.
 */
export async function setupTotp(): Promise<TotpSetupResponse> {
  const res = await apiClient.POST('/api/auth/totp/setup')
  if (!res.data) {
    throw new ApiError(res.response.status, null)
  }
  return res.data
}

// ---------------------------------------------------------------------------
// enableTotp — POST /api/auth/totp/enable
// ---------------------------------------------------------------------------

/** Confirm TOTP setup with the current 6-digit code from the authenticator app. */
export async function enableTotp(code: string): Promise<void> {
  // The endpoint returns 204 on success; openapi-fetch yields { data: undefined }.
  await apiClient.POST('/api/auth/totp/enable', { body: { code } })
}

// ---------------------------------------------------------------------------
// disableTotp — POST /api/auth/totp/disable
// ---------------------------------------------------------------------------

/**
 * Disable TOTP.  Exactly one of password or code must be provided.
 * On success the backend clears the secret and all recovery codes.
 */
export async function disableTotp(opts: {
  password?: string | null
  code?: string | null
}): Promise<void> {
  await apiClient.POST('/api/auth/totp/disable', {
    body: { password: opts.password ?? null, code: opts.code ?? null },
  })
}
