/**
 * Tauri adapter for {@link ProfileGateway} (L5). Like the sibling adapters this
 * is one of the *only* places that calls `invoke()`; components reach it
 * exclusively through the port.
 *
 * Commands and payload keys are camelCase, matching the backend DTO convention.
 */

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

import type {
  AgentProfile,
  FirstRunState,
  OpenCodeProviderCatalogEntry,
  ProfileModelCatalog,
  ProfileAvailability,
} from "@/domain";
import type {
  CloneProfileFromSeedInput,
  CloneOpenCodeProfileFromSeedInput,
  ProfileGateway,
  SaveOpenCodeProviderProfileInput,
} from "@/ports";
import { normalizeProfileModelCatalog } from "./profileCatalog";

export class TauriProfileGateway implements ProfileGateway {
  firstRunState(): Promise<FirstRunState> {
    return invoke<FirstRunState>("first_run_state");
  }

  referenceProfiles(): Promise<AgentProfile[]> {
    return invoke<AgentProfile[]>("reference_profiles");
  }

  detectProfiles(candidates: AgentProfile[]): Promise<ProfileAvailability[]> {
    return invoke<ProfileAvailability[]>("detect_profiles", {
      request: { candidates },
    });
  }

  listProfiles(): Promise<AgentProfile[]> {
    return invoke<AgentProfile[]>("list_profiles");
  }

  saveProfile(profile: AgentProfile): Promise<AgentProfile> {
    return invoke<AgentProfile>("save_profile", { request: { profile } });
  }

  async deleteProfile(profileId: string): Promise<void> {
    await invoke("delete_profile", { profileId });
  }

  cloneProfileFromSeed(input: CloneProfileFromSeedInput): Promise<AgentProfile> {
    return invoke<AgentProfile>("clone_profile_from_seed", {
      request: {
        seedProfileId: input.seedProfileId,
        name: input.name,
        model: input.model,
      },
    });
  }

  async listClaudeModels(): Promise<ProfileModelCatalog> {
    return normalizeProfileModelCatalog(await invoke<unknown>("list_claude_models"));
  }

  async listCodexModels(): Promise<ProfileModelCatalog> {
    return normalizeProfileModelCatalog(await invoke<unknown>("list_codex_models"));
  }

  configureProfiles(profiles: AgentProfile[]): Promise<AgentProfile[]> {
    return invoke<AgentProfile[]>("configure_profiles", {
      request: { profiles },
    });
  }

  cloneOpenCodeProfileFromSeed(
    input: CloneOpenCodeProfileFromSeedInput = {},
  ): Promise<AgentProfile> {
    return invoke<AgentProfile>("clone_opencode_profile_from_seed", {
      request: { name: input.name, opencode: input.opencode },
    });
  }

  listOpenCodeProviders(): Promise<OpenCodeProviderCatalogEntry[]> {
    return invoke<OpenCodeProviderCatalogEntry[]>("list_opencode_providers");
  }

  saveOpenCodeProviderProfile(
    input: SaveOpenCodeProviderProfileInput,
  ): Promise<AgentProfile> {
    return invoke<AgentProfile>("save_opencode_provider_profile", {
      request: {
        profile: input.profile,
        providerId: input.providerId,
        model: input.model,
        apiKey: input.apiKey,
        custom: input.custom,
      },
    });
  }

}
