/**
 * Error base para todas las capas con soporte de `code`, `cause` y serialización segura.
 * Mantiene instanceof correcto y añade un discriminador de capa.
 */

export abstract class BaseError<
  L extends "domain" | "application" | "infrastructure",
> extends Error {
  public abstract readonly layer: L;
  public readonly code: string;
  public readonly metadata?: Record<string, unknown>;

  constructor(
    name: string,
    message: string,
    code: string,
    options?: ErrorOptions & { metadata?: Record<string, unknown> }
  ) {
    super(message, options);
    this.name = name;
    this.code = code;
    this.metadata = options?.metadata;
    Object.setPrototypeOf(this, new.target.prototype); // mantener instanceof
  }

  /** Serialización segura para logs/observabilidad */
  toJSON() {
    const cause = (this as any).cause as unknown | undefined;
    return {
      name: this.name,
      message: this.message,
      code: this.code,
      layer: this.layer,
      metadata: this.metadata,
      cause: cause instanceof Error ? { name: cause.name, message: cause.message } : undefined,
    };
  }
}
