"use client";
import { useCallback, useMemo, useRef, useState } from "react";
import { create } from "@bufbuild/protobuf";
import { UpdateEnvironmentVariablesRequestSchema, RemoveEnvironmentVariablesRequestSchema, } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/io_pb";
import { EnvironmentValueSchema } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/spec_pb";
import { useStigmer } from "../hooks";
import { generateSlugSuffix } from "../internal/slug";
import { toError } from "../internal/toError";
import { useEnvironmentList } from "./useEnvironmentList";
const PERSONAL_LABELS = {
    "stigmer.ai/personal": "true",
};
/**
 * Layer 2 orchestration hook that manages the caller's personal
 * {@link Environment} for a given organization.
 *
 * Encapsulates the "personal environment" convention: label
 * (`stigmer.ai/personal: "true"`), unique slug per user, and
 * the get-or-create lifecycle. Composes {@link useEnvironmentList}
 * for declarative reading and the SDK client directly for mutations.
 *
 * Pass `null` as `org` to skip all operations (stable no-op).
 *
 * This is a Layer 2 **Environment Flow** hook. It provides the managed
 * "personal environment" experience used by the Stigmer Console and
 * any app that wants automatic credential storage. Callers who manage
 * environments programmatically should use the Layer 1 building-block
 * hooks instead:
 * - {@link useCreateEnvironment} — create any environment
 * - {@link useUpdateEnvironmentVariables} — incremental variable merge
 * - {@link useRemoveEnvironmentVariables} — remove variables by key
 *
 * @example
 * ```tsx
 * // Basic usage — read the personal environment
 * const { environment, isLoading } = usePersonalEnvironment("acme");
 *
 * // Get-or-create with initial data on first use
 * const { getOrCreate, addVariables, isMutating } =
 *   usePersonalEnvironment("acme");
 *
 * const env = await getOrCreate({
 *   GITHUB_TOKEN: { value: "ghp_...", isSecret: true },
 * });
 *
 * // Add variables to an existing personal environment
 * await addVariables({
 *   SLACK_TOKEN: { value: "xoxb-...", isSecret: true },
 * });
 * ```
 */
export function usePersonalEnvironment(org) {
    const stigmer = useStigmer();
    const { environments, isLoading, error: listError, refetch } = useEnvironmentList(org, PERSONAL_LABELS);
    const environment = useMemo(() => environments[0] ?? null, [environments]);
    const [isMutating, setIsMutating] = useState(false);
    const [mutationError, setMutationError] = useState(null);
    const environmentRef = useRef(environment);
    environmentRef.current = environment;
    const isLoadingRef = useRef(isLoading);
    isLoadingRef.current = isLoading;
    const error = mutationError ?? listError;
    const getOrCreate = useCallback(async (initialData) => {
        if (environmentRef.current)
            return environmentRef.current;
        if (!org) {
            throw new Error("usePersonalEnvironment: cannot call getOrCreate when org is null.");
        }
        if (isLoadingRef.current) {
            throw new Error("usePersonalEnvironment: cannot call getOrCreate while the " +
                "environment list is loading. Wait for isLoading to become " +
                "false before calling getOrCreate().");
        }
        setIsMutating(true);
        setMutationError(null);
        try {
            let data;
            if (initialData && Object.keys(initialData).length > 0) {
                data = initialData;
            }
            const created = await stigmer.environment.create({
                name: "Personal Environment",
                slug: `env-personal-${generateSlugSuffix()}`,
                org,
                labels: PERSONAL_LABELS,
                data,
            });
            refetch();
            return created;
        }
        catch (err) {
            setMutationError(toError(err));
            throw err;
        }
        finally {
            setIsMutating(false);
        }
    }, [org, stigmer, refetch]);
    const addVariables = useCallback(async (variables) => {
        const env = environmentRef.current;
        if (!env) {
            throw new Error("usePersonalEnvironment: personal environment does not exist. " +
                "Call getOrCreate() before addVariables().");
        }
        setIsMutating(true);
        setMutationError(null);
        try {
            const protoVars = Object.fromEntries(Object.entries(variables).map(([k, v]) => [
                k,
                create(EnvironmentValueSchema, {
                    value: v.value,
                    isSecret: v.isSecret,
                    description: v.description,
                }),
            ]));
            const request = create(UpdateEnvironmentVariablesRequestSchema, {
                environmentId: env.metadata.id,
                variables: protoVars,
            });
            const updated = await stigmer.environment.updateVariables(request);
            refetch();
            return updated;
        }
        catch (err) {
            setMutationError(toError(err));
            throw err;
        }
        finally {
            setIsMutating(false);
        }
    }, [stigmer, refetch]);
    const removeVariables = useCallback(async (keys) => {
        const env = environmentRef.current;
        if (!env) {
            throw new Error("usePersonalEnvironment: personal environment does not exist. " +
                "Call getOrCreate() before removeVariables().");
        }
        setIsMutating(true);
        setMutationError(null);
        try {
            const request = create(RemoveEnvironmentVariablesRequestSchema, {
                environmentId: env.metadata.id,
                keys,
            });
            const updated = await stigmer.environment.removeVariables(request);
            refetch();
            return updated;
        }
        catch (err) {
            setMutationError(toError(err));
            throw err;
        }
        finally {
            setIsMutating(false);
        }
    }, [stigmer, refetch]);
    return {
        environment,
        isLoading,
        error,
        refetch,
        getOrCreate,
        addVariables,
        removeVariables,
        isMutating,
    };
}
//# sourceMappingURL=usePersonalEnvironment.js.map