// Type-only import: keeps this module free of runtime deps so the
// `__tests__/mergeOptimisticCredentials.ts` net doesn't have to mock the
// whole `src/lib/api` graph just to assert merge behaviour.
import type { UpdateCredentialsInput } from 'src/lib/api/shared'

// Pure helper: maps an `UpdateCredentialsInput` patch onto a cached
// `Account` / `LoginUserResponse` blob. Lives outside the hook file so
// the test net can import it without dragging in the whole React Query
// + tamagui + lib/api dependency graph.

type Mergeable = Record<string, unknown>

export function mergeOptimisticCredentials<T extends Mergeable | undefined>(
  old: T,
  input: UpdateCredentialsInput
): T {
  if (!old) return old
  const next = { ...(old as Mergeable) }
  if (input.display_name !== undefined) next.display_name = input.display_name
  if (input.note !== undefined) {
    next.note = input.note
    // `LoginUserResponse` carries a `note_text` mirror of `note` with the
    // HTML stripped — keep them in lockstep for the optimistic paint.
    next.note_text = input.note
  }
  if (input.website !== undefined) next.website = input.website
  if (input.locked !== undefined) next.locked = input.locked
  if (input.discoverable !== undefined) next.discoverable = input.discoverable
  if (input.hide_collections !== undefined) next.hide_collections = input.hide_collections
  if (input.indexable !== undefined) next.indexable = input.indexable
  if (input.bot !== undefined) next.bot = input.bot
  if (input['source[privacy]'] !== undefined) {
    const source = (next.source ?? {}) as Mergeable
    next.source = { ...source, privacy: input['source[privacy]'] }
  }
  // Pixelfed `settings` blob — the privacy-settings page reads from here.
  const settingsKeys: (keyof UpdateCredentialsInput)[] = [
    'show_profile_follower_count',
    'show_profile_following_count',
    'is_suggestable',
    'public_dm',
    'crawlable',
    'disable_embeds',
    'show_atom',
  ]
  if (settingsKeys.some((k) => input[k] !== undefined)) {
    const settings = (next.settings ?? {}) as Mergeable
    const merged: Mergeable = { ...settings }
    for (const k of settingsKeys) {
      if (input[k] !== undefined) merged[k] = input[k] as boolean
    }
    next.settings = merged
  }
  return next as T
}
