import { DestroyRef, Injectable, inject, signal } from "@angular/core";
import type { EngineEvent, IEngine, JsonValue, RunResult } from "@newvexa/workify";
import { createOrderEngine } from "../vanilla";

@Injectable()
export class WorkflowService {
  private readonly engine: IEngine = createOrderEngine();
  private readonly state = signal(this.engine.getSnapshot());
  private readonly event = signal<EngineEvent | null>(null);
  private readonly running = signal(false);
  private active: AbortController | null = null;

  readonly snapshot = this.state.asReadonly();
  readonly lastEvent = this.event.asReadonly();
  readonly busy = this.running.asReadonly();

  constructor() {
    const stopState = this.engine.subscribe(() => {
      this.state.set(this.engine.getSnapshot());
    });
    const stopEvents = this.engine.onEvent((event) => {
      this.event.set(event);
    });
    inject(DestroyRef).onDestroy(() => {
      stopState();
      stopEvents();
      this.active?.abort();
    });
  }

  async run(input: JsonValue): Promise<RunResult> {
    if (this.active) throw new Error("Une exécution est déjà active dans cette vue.");
    const controller = new AbortController();
    this.active = controller;
    this.running.set(true);
    try {
      return await this.engine.run(input, { signal: controller.signal });
    } finally {
      this.active = null;
      this.running.set(false);
    }
  }

  cancel(): void {
    this.active?.abort();
  }

  getHistory() {
    return this.engine.getHistory();
  }
}
