import { ITransactionManager } from "./transaction-manager.interface";

export abstract class TransactionManager implements ITransactionManager {
  protected _transaction: any | null = null;

  /**
   * 🔹 Inicia una transacción si no hay una activa
   */
  async start(): Promise<void> {
    if (!this._transaction) {
      this._transaction = await this._startTransaction();
    }
  }

  /**
   * 🔹 Devuelve la transacción activa
   */
  getTransaction(): any {
    if (!this._transaction) {
      throw new Error("No active transaction. Call start() first.");
    }
    return this._transaction;
  }

  /**
   * 🔹 Ejecuta una función dentro de una transacción
   */
  async complete<T>(work: (transaction: any) => Promise<T>): Promise<T> {
    await this.start();
    try {
      const result = await work(this.getTransaction());
      await this.commit();
      return result;
    } catch (error) {
      await this.rollback();
      throw error;
    }
  }

  /**
   * 🔹 Métodos abstractos para manejar transacciones
   */
  protected abstract _startTransaction(): Promise<any>;
  protected abstract _commitTransaction(): Promise<void>;
  protected abstract _rollbackTransaction(): Promise<void>;

  async commit(): Promise<void> {
    if (this._transaction) {
      await this._commitTransaction();
      this._transaction = null;
    }
  }

  async rollback(): Promise<void> {
    if (this._transaction) {
      await this._rollbackTransaction();
      this._transaction = null;
    }
  }
}
