import { onScopeDispose, shallowReadonly, shallowRef } from "vue";
import type { EngineEvent, IEngine, JsonValue, RunResult } from "@newvexa/workify";
import { createOrderEngine } from "../vanilla";

/** À appeler une fois dans setup() ou dans un effectScope actif. */
export function useWorkflow(engine: IEngine = createOrderEngine()) {
  const state = shallowRef(engine.getSnapshot());
  const lastEvent = shallowRef<EngineEvent | null>(null);
  const busy = shallowRef(false);
  let active: AbortController | null = null;

  const stopState = engine.subscribe(() => {
    state.value = engine.getSnapshot();
  });
  const stopEvents = engine.onEvent((event) => {
    lastEvent.value = event;
  });

  onScopeDispose(() => {
    stopState();
    stopEvents();
    active?.abort();
  });

  async function run(input: JsonValue): Promise<RunResult> {
    if (active) throw new Error("Une exécution est déjà active dans cette vue.");
    const controller = new AbortController();
    active = controller;
    busy.value = true;
    try {
      return await engine.run(input, { signal: controller.signal });
    } finally {
      // L'annulation ne libère l'instance qu'après drainage des tâches en vol.
      active = null;
      busy.value = false;
    }
  }

  return {
    state: shallowReadonly(state),
    lastEvent: shallowReadonly(lastEvent),
    busy: shallowReadonly(busy),
    run,
    cancel: () => active?.abort(),
    getHistory: () => engine.getHistory(),
  };
}

// Dans setup() :
// const { state, busy, run, cancel } = useWorkflow();
// await run({ orderId: "VUE-001", total: 1500 }); // sur une action explicite
// Le template déballera les refs : state.status, busy.
