import { PrimariaApi } from "../../api/api";
import { TYPES } from "../../infrastructure/ioc/types";
import { inject } from "inversify";
import { ExitShell } from "./request";
import { disposeShell, raiseCloseEvent, raiseCustomCloseEvent } from "../../disposer";
import { disposePlugins } from "../../handle-plugins";
import { translate } from "../../locales";

export class ExitShellHandler {
  constructor(@inject(TYPES.primaryApi) private api: PrimariaApi) {}
  async handle(exitEvent: ExitShell): Promise<void> {
    const evt = exitEvent && exitEvent.ecapEvent !== undefined ? exitEvent : undefined;

    try {
      const canExit = await this.api.exitGuardManager.canExit();
      if (!canExit) return;

      // Per si un plugin tarda molt en fer dispose, màxim deixarem 5 segons, per no interrompre el tancar infinitament
      await Promise.race([
        disposePlugins(), // S'intenta executar un dispose normal
        this.timeout(10000), // Si passen 5s, es segueix amb l'execució
      ]);
      disposeShell();
      this.emitClose(evt);
    } catch (error) {
      this.api.notificationService.error(translate("errors.exit"));
      this.emitClose(evt);
    }
  }

  private timeout(ms: number) {
    return new Promise<void>((resolve) => setTimeout(resolve, ms));
  }

  private emitClose(exitEvent?: ExitShell): void {
    if (exitEvent) {
      raiseCustomCloseEvent(exitEvent);
    } else {
      raiseCloseEvent();
    }
  }
}
