export class NotPurchasedError extends Error {
  override readonly name = 'NotPurchasedError'
  readonly code = 'NOT_PURCHASED' as const
  readonly httpStatus = 403 as const

  constructor(
    readonly userId: string,
    readonly productId: string,
  ) {
    super(`not purchased: user ${userId} product ${productId}`)
  }
}

export class ReviewNotFoundError extends Error {
  override readonly name = 'ReviewNotFoundError'
  readonly code = 'REVIEW_NOT_FOUND' as const
  readonly httpStatus = 404 as const

  constructor(readonly reviewId: string) {
    super('review not found')
  }
}

export class ReviewValidationError extends Error {
  override readonly name = 'ReviewValidationError'
  readonly code = 'REVIEW_VALIDATION' as const
  readonly httpStatus = 400 as const

  constructor(readonly field: string) {
    super(`review validation failed: ${field}`)
  }
}

export type ImmutableField = 'userId' | 'productId' | 'purchaseId' | 'vendorId'

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 class ReviewsConfigError extends Error {
  override readonly name = 'ReviewsConfigError'
  readonly code = 'REVIEWS_CONFIG' as const

  constructor(readonly detail: string) {
    super(`reviews config: ${detail}`)
  }
}

export class ReviewsMigrateError extends Error {
  override readonly name = 'ReviewsMigrateError'
  readonly code = 'REVIEWS_MIGRATE' as const

  constructor(readonly detail: string) {
    super(`reviews migrate: ${detail}`)
  }
}

export function isNotPurchasedError(e: unknown): e is NotPurchasedError {
  return (
    typeof e === 'object' &&
    e !== null &&
    (e as { name?: unknown }).name === 'NotPurchasedError' &&
    (e as { code?: unknown }).code === 'NOT_PURCHASED'
  )
}

export function isReviewNotFoundError(e: unknown): e is ReviewNotFoundError {
  return (
    typeof e === 'object' &&
    e !== null &&
    (e as { name?: unknown }).name === 'ReviewNotFoundError' &&
    (e as { code?: unknown }).code === 'REVIEW_NOT_FOUND'
  )
}

export function isReviewValidationError(e: unknown): e is ReviewValidationError {
  return (
    typeof e === 'object' &&
    e !== null &&
    (e as { name?: unknown }).name === 'ReviewValidationError' &&
    (e as { code?: unknown }).code === 'REVIEW_VALIDATION'
  )
}

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'
  )
}

export function isReviewsConfigError(e: unknown): e is ReviewsConfigError {
  return (
    typeof e === 'object' &&
    e !== null &&
    (e as { name?: unknown }).name === 'ReviewsConfigError' &&
    (e as { code?: unknown }).code === 'REVIEWS_CONFIG'
  )
}

export function isReviewsMigrateError(e: unknown): e is ReviewsMigrateError {
  return (
    typeof e === 'object' &&
    e !== null &&
    (e as { name?: unknown }).name === 'ReviewsMigrateError' &&
    (e as { code?: unknown }).code === 'REVIEWS_MIGRATE'
  )
}
