/**
 * Typed boundary error when the host worker rejects an upload (validation/quota/size/auth).
 * Carries a STRUCTURAL `isUploadRejectedError: true` tag so cross-package callers (the host, the
 * useUpload hook) identify it WITHOUT `instanceof` — two deduped copies of this class break
 * instanceof, and a `name`-only check is spoofable by a plain `{ name: 'UploadRejectedError' }`.
 * Mirrors the same-wave `@platform-modules/uploads/storage` `isStorageError === true` convention
 * (CLAUDE.md §6: cross-package error identity must use a structural type-guard, never instanceof).
 */
export class UploadRejectedError extends Error {
  override readonly name = 'UploadRejectedError'
  readonly isUploadRejectedError = true as const
  constructor(
    readonly reason: string,
    readonly status: number,
  ) {
    super(`upload rejected (${status}): ${reason}`)
  }
}

export function isUploadRejectedError(e: unknown): e is UploadRejectedError {
  return typeof e === 'object' && e !== null && (e as { isUploadRejectedError?: unknown }).isUploadRejectedError === true
}

/**
 * Typed boundary error when `useUpload.upload` is called re-entrantly — a SECOND upload while one
 * is already in flight. The hook tracks a single upload's state, so the second call cannot be
 * coalesced (each must return its own MediaItem) and is rejected. DISTINCT from UploadRejectedError
 * (a HOST-side rejection carrying reason+status) — a client-side re-entrancy conflict has neither,
 * so it gets its own discriminant, never a synthetic-status reuse. Carries a STRUCTURAL
 * `isUploadInFlightError: true` tag so callers identify it WITHOUT `instanceof` (CLAUDE.md §6).
 */
export class UploadInFlightError extends Error {
  override readonly name = 'UploadInFlightError'
  readonly isUploadInFlightError = true as const
  constructor() {
    super('an upload is already in progress')
  }
}

export function isUploadInFlightError(e: unknown): e is UploadInFlightError {
  return typeof e === 'object' && e !== null && (e as { isUploadInFlightError?: unknown }).isUploadInFlightError === true
}
