/**
 * Tauri adapter for {@link FocusedProjectGateway} (ticket #47). Bridges the
 * main-window ⇄ detached-panel focused-project channel to the backend commands
 * and event. Like the sibling adapters, this is the only layer allowed to touch
 * `@tauri-apps/api`; components reach it exclusively through the port.
 *
 * Command/event names and payloads mirror the backend contract owned by
 * DevBackend: `set_focused_project` / `get_focused_project` and the
 * `focused-project://changed` event whose payload is `{ project: FocusedProject
 * | null }`.
 */

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

import type { Unsubscribe } from "@/domain";
import type { FocusedProject, FocusedProjectGateway } from "@/ports";

/** The Tauri event carrying focused-project transitions. */
const FOCUSED_PROJECT_CHANGED = "focused-project://changed";

/** Backend payload for `focused-project://changed`. */
interface FocusedProjectChanged {
  project: FocusedProject | null;
}

export class TauriFocusedProjectGateway implements FocusedProjectGateway {
  async setFocusedProject(project: FocusedProject | null): Promise<void> {
    // The backend command takes `project: Option<FocusedProjectDto>`; `null`
    // clears the focus (no project open).
    await invoke("set_focused_project", { project });
  }

  async getFocusedProject(): Promise<FocusedProject | null> {
    const project = await invoke<FocusedProject | null>("get_focused_project");
    return project ?? null;
  }

  async onFocusedProjectChanged(
    handler: (project: FocusedProject | null) => void,
  ): Promise<Unsubscribe> {
    const unlisten = await listen<FocusedProjectChanged>(
      FOCUSED_PROJECT_CHANGED,
      (e) => handler(e.payload.project ?? null),
    );
    return unlisten;
  }
}
