import { Mintblue } from '../mintblue.js';
import { Writer, Action } from './types.js';
import { LogClass } from './utils.js';

/**
 * An implementation of the Writer interface that integrates with the mintBlue SDK.
 * This writer sends transactional data to the mintBlue platform.
 *
 * @category Machine
 */
@LogClass()
export class MintblueWriter implements Writer {
  private mintblue: Mintblue;
  private project_id: string;

  /**
   * Factory method to create an instance of the MintblueWriter.
   * Initializes the mintBlue SDK and returns a new writer instance.
   *
   * @param sdkToken - The SDK token for authentication with mintBlue.
   * @param project_id - The project identifier in mintBlue where the data will be written.
   * @returns A promise that resolves to a new MintblueWriter instance.
   */
  static async create(sdkToken: string, project_id: string): Promise<MintblueWriter> {
    const mintblue = await Mintblue.create({ token: sdkToken });
    return new MintblueWriter(mintblue, project_id);
  }

  /**
   * Constructor for MintblueWriter.
   *
   * @param mintblue - An instance of the mintBlue SDK.
   * @param project_id - The project identifier in mintBlue where the data will be written.
   */
  constructor(mintblue: Mintblue, project_id: string) {
    this.mintblue = mintblue;
    this.project_id = project_id;
  }

  /**
   * Writes the given action as a transaction to the mintBlue platform.
   *
   * @param action - The action to write.
   * @throws Will throw an error if the mintBlue SDK has not been initialized.
   * @returns A promise that resolves when the write operation completes or rejects on error.
   */
  async write(action: Action): Promise<void> {
    if (!this.mintblue) {
      throw new Error('mintBlue SDK not initialized yet');
    }

    try {
      await this.mintblue.createTransaction({
        project_id: this.project_id,
        outputs: [{ type: 'data', value: { f: action.f, args: action.args } as any, encrypt: true, sign: true }],
      });
    } catch (e) {
      this.handleError(e);
    }
  }

  /**
   * Handles and logs errors from the write operations.
   *
   * @param error - The error to handle and log.
   */
  handleError(error: any): void {
    console.log('MintblueWriter Error ' + error);
  }
}
