/**
 * `useEmbedder` — view-model hook for the memory/embedder settings (L14 / C2).
 *
 * Owns the configured embedder profiles and the available engines (with the
 * build-time feature flags). Consumes {@link EmbedderGateway} exclusively; never
 * touches `invoke()` or `@tauri-apps/api`, keeping the component layer testable
 * with mock gateways (ARCHITECTURE §1.3).
 *
 * Note: the embedder change takes effect at the *next app start* — this hook
 * just persists the choice; it does not hot-swap the live recall tier.
 */

import { useCallback, useEffect, useState } from "react";

import type { EmbedderEngines, EmbedderProfile, GatewayError } from "@/domain";
import { useGateways } from "@/app/di";

/** What the embedder settings UI needs from this hook. */
export interface EmbedderViewModel {
  /** The configured embedder profiles. */
  profiles: EmbedderProfile[];
  /** The available engines + build feature flags, or `null` until loaded. */
  engines: EmbedderEngines | null;
  /** The single active profile (first configured), or `null` (naïve/None). */
  active: EmbedderProfile | null;
  /** Last error message, or `null`. */
  error: string | null;
  /** Whether a request is in flight. */
  busy: boolean;
  /** Reloads profiles + engines. */
  refresh: () => Promise<void>;
  /** Persists a profile (create/replace by id) and refreshes. */
  saveProfile: (profile: EmbedderProfile) => Promise<void>;
  /** Deletes a profile by id and refreshes. */
  deleteProfile: (embedderId: string) => Promise<void>;
}

function describe(e: unknown): string {
  if (e && typeof e === "object" && "message" in e) {
    return String((e as GatewayError).message);
  }
  return String(e);
}

export function useEmbedder(): EmbedderViewModel {
  const { embedder } = useGateways();

  const [profiles, setProfiles] = useState<EmbedderProfile[]>([]);
  const [engines, setEngines] = useState<EmbedderEngines | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [busy, setBusy] = useState(false);

  const refresh = useCallback(async () => {
    setBusy(true);
    setError(null);
    try {
      const [list, eng] = await Promise.all([
        embedder.listEmbedderProfiles(),
        embedder.describeEmbedderEngines(),
      ]);
      setProfiles(list);
      setEngines(eng);
    } catch (e) {
      setError(describe(e));
    } finally {
      setBusy(false);
    }
  }, [embedder]);

  useEffect(() => {
    void refresh();
  }, [refresh]);

  const saveProfile = useCallback(
    async (profile: EmbedderProfile) => {
      setBusy(true);
      setError(null);
      try {
        await embedder.saveEmbedderProfile(profile);
        await refresh();
      } catch (e) {
        setError(describe(e));
        setBusy(false);
      }
    },
    [embedder, refresh],
  );

  const deleteProfile = useCallback(
    async (embedderId: string) => {
      setBusy(true);
      setError(null);
      try {
        await embedder.deleteEmbedderProfile(embedderId);
        await refresh();
      } catch (e) {
        setError(describe(e));
        setBusy(false);
      }
    },
    [embedder, refresh],
  );

  // The active embedder is the first configured profile (the backend keeps a
  // single active embedder); `null` ⇒ naïve recall (None).
  const active = profiles.find((p) => p.strategy !== "none") ?? null;

  return {
    profiles,
    engines,
    active,
    error,
    busy,
    refresh,
    saveProfile,
    deleteProfile,
  };
}
