/**
 * Tauri adapter for {@link SystemGateway}. This is the *only* place (together
 * with the sibling adapters) that touches `@tauri-apps/api`. Components reach it
 * exclusively through the port — never `invoke()` directly.
 */

import { invoke } from "@tauri-apps/api/core";
import { listen } from "@tauri-apps/api/event";
import { open } from "@tauri-apps/plugin-dialog";

import type { AppExitWorkGuardState, DomainEvent, HealthReport, Unsubscribe } from "@/domain";
import type { SystemGateway } from "@/ports";

/** Tauri event name carrying relayed domain events (mirror of `DOMAIN_EVENT`). */
const DOMAIN_EVENT = "domain://event";

/** Tauri event name carrying the app-exit work guard state (ticket #83). */
const APP_EXIT_WORK_GUARD = "app-exit-work-guard";

export class TauriSystemGateway implements SystemGateway {
  async health(note?: string): Promise<HealthReport> {
    // The backend command takes an optional `request: { note }` (camelCase).
    return invoke<HealthReport>("health", {
      request: note === undefined ? null : { note },
    });
  }

  async onDomainEvent(
    handler: (event: DomainEvent) => void,
  ): Promise<Unsubscribe> {
    const unlisten = await listen<DomainEvent>(DOMAIN_EVENT, (e) => {
      handler(e.payload);
    });
    return unlisten;
  }

  async pickFolder(): Promise<string | null> {
    const result = await open({ directory: true, multiple: false });
    if (result === null || result === undefined) return null;
    // `open` with `multiple: false` returns a string when a path is chosen.
    return typeof result === "string" ? result : null;
  }

  async onAppExitWorkGuard(
    handler: (state: AppExitWorkGuardState) => void,
  ): Promise<Unsubscribe> {
    const unlisten = await listen<AppExitWorkGuardState>(APP_EXIT_WORK_GUARD, (e) => {
      handler(e.payload);
    });
    return unlisten;
  }

  async confirmAppExit(): Promise<void> {
    await invoke("confirm_app_exit");
  }
}
