/**
 * Tauri adapter for {@link PluginGateway} (ticket #43, F1).
 *
 * Commands use snake_case (Tauri convention); payload keys are camelCase,
 * consistent with the other adapters in this directory. Command names and
 * envelope match the carnet §5 exactly — no contract improvised here.
 *
 * NOTE: The Tauri commands wired here are defined in the backend `app-tauri`
 * crate (lots B1-B4, in progress in parallel on this branch). The mock gateway
 * covers tests and offline dev today.
 */

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

import type {
  PluginAdmin,
  PluginInstallResult,
  PluginReview,
  PluginRuntimeContributionCatalog,
  PluginUninstallResult,
} from "@/domain";
import type { PluginGateway, ReviewPluginPackageInput } from "@/ports";

type TauriPluginReviewDto = Omit<PluginReview, "issues" | "installable"> & {
  issues?: PluginReview["issues"];
  installable?: boolean;
};

function normalizeReview(review: TauriPluginReviewDto): PluginReview {
  return {
    ...review,
    issues: review.issues ?? [],
    installable: review.installable ?? true,
  };
}

export class TauriPluginGateway implements PluginGateway {
  listPlugins(): Promise<PluginAdmin[]> {
    return invoke<PluginAdmin[]>("plugin_list_plugins");
  }

  async reviewPackage(input: ReviewPluginPackageInput): Promise<PluginReview> {
    const review = await invoke<TauriPluginReviewDto>("plugin_review_package", {
      input: { sourceKind: input.sourceKind, path: input.path },
    });
    return normalizeReview(review);
  }

  installFromArchive(path: string): Promise<PluginInstallResult> {
    return invoke<PluginInstallResult>("plugin_install_from_archive", { path });
  }

  installFromDirectory(path: string): Promise<PluginInstallResult> {
    return invoke<PluginInstallResult>("plugin_install_from_directory", { path });
  }

  setEnabled(pluginId: string, enabled: boolean): Promise<PluginAdmin> {
    return invoke<PluginAdmin>("plugin_set_enabled", { pluginId, enabled });
  }

  uninstall(pluginId: string): Promise<PluginUninstallResult> {
    return invoke<PluginUninstallResult>("plugin_uninstall", { pluginId });
  }

  listRuntimeContributions(): Promise<PluginRuntimeContributionCatalog> {
    return invoke<PluginRuntimeContributionCatalog>("plugin_list_runtime_contributions");
  }

  async openPluginsFolder(pluginId?: string): Promise<void> {
    await invoke("plugin_open_plugins_folder", { pluginId: pluginId ?? null });
  }
}
