export class ProductValidationError extends Error {
  override readonly name = 'ProductValidationError'
  readonly code = 'PRODUCT_VALIDATION' as const

  constructor(
    readonly field: string,
    readonly detail?: string,
  ) {
    super(detail ? `product validation failed: ${field} — ${detail}` : `product validation failed: ${field}`)
  }
}

export class NoPriceForCurrencyError extends Error {
  override readonly name = 'NoPriceForCurrencyError'
  readonly code = 'NO_PRICE_FOR_CURRENCY' as const

  constructor(readonly currency: string) {
    super(`no price for currency: ${currency}`)
  }
}

/**
 * Fields frozen at create time on a catalog product. Typed union (not bare `string`)
 * so the DTS names exactly which fields are immutable. Family-canonical: every commerce
 * sibling declares its own `ImmutableField` union for its create-time-frozen FKs.
 */
export type ImmutableField = 'kind' | 'vendorId'

/**
 * Family-canonical discriminated immutable-field error (commerce-conventions C5).
 * REPLACES the bespoke per-field `KindImmutableError`. Every commerce sibling reuses
 * this exact shape + the single `isImmutableFieldError` guard for its own immutable FKs.
 */
export class ImmutableFieldError extends Error {
  override readonly name = 'ImmutableFieldError'
  readonly code = 'IMMUTABLE_FIELD' as const

  constructor(readonly field: ImmutableField) {
    super(`field cannot be changed after create: ${field}`)
  }
}

export function isProductValidationError(e: unknown): e is ProductValidationError {
  return (
    typeof e === 'object' &&
    e !== null &&
    (e as { name?: unknown }).name === 'ProductValidationError' &&
    (e as { code?: unknown }).code === 'PRODUCT_VALIDATION'
  )
}

export function isNoPriceForCurrencyError(e: unknown): e is NoPriceForCurrencyError {
  return (
    typeof e === 'object' &&
    e !== null &&
    (e as { name?: unknown }).name === 'NoPriceForCurrencyError' &&
    (e as { code?: unknown }).code === 'NO_PRICE_FOR_CURRENCY'
  )
}

export function isImmutableFieldError(e: unknown): e is ImmutableFieldError {
  return (
    typeof e === 'object' &&
    e !== null &&
    (e as { name?: unknown }).name === 'ImmutableFieldError' &&
    (e as { code?: unknown }).code === 'IMMUTABLE_FIELD'
  )
}
