// src/services/db/errors.db.ts

/**
 * Base class for custom database errors to ensure they have a status property.
 */
export class DatabaseError extends Error {
  public status: number;

  constructor(message: string, status: number) {
    super(message);
    this.name = this.constructor.name;
    this.status = status;
    // This is necessary to make `instanceof` work correctly with transpiled TS classes
    Object.setPrototypeOf(this, new.target.prototype);
  }
}

/**
 * Thrown when a unique constraint is violated (e.g., trying to register an existing email).
 * Corresponds to PostgreSQL error code '23505'.
 */
export class UniqueConstraintError extends DatabaseError {
  constructor(message = 'The record already exists.') {
    super(message, 409); // 409 Conflict
  }
}

/**
 * Thrown when a foreign key constraint is violated (e.g., trying to reference a non-existent record).
 * Corresponds to PostgreSQL error code '23503'.
 */
export class ForeignKeyConstraintError extends DatabaseError {
  constructor(message = 'The referenced record does not exist.') {
    super(message, 400); // 400 Bad Request
  }
}

/**
 * Thrown when a specific record is not found in the database.
 */
export class NotFoundError extends DatabaseError {
  constructor(message = 'The requested resource was not found.') {
    super(message, 404); // 404 Not Found
  }
}

/**
 * Defines the structure for a single validation issue, often from a library like Zod.
 */
export interface ValidationIssue {
  path: (string | number)[];
  message: string;
  [key: string]: unknown; // Allow other properties that might exist on the error object
}

/**
 * Thrown when request validation fails (e.g., missing body fields or invalid params).
 */
export class ValidationError extends DatabaseError {
  public validationErrors: ValidationIssue[];

  constructor(errors: ValidationIssue[], message = 'The request data is invalid.') {
    super(message, 400); // 400 Bad Request
    this.name = 'ValidationError';
    this.validationErrors = errors;
  }
}


export class FileUploadError extends Error {
  public status = 400;
  constructor(message: string) {
    super(message);
    this.name = 'FileUploadError';
  }
}