"use client";
import { useCallback, useMemo, useState } from "react";
import { OAuthAppSource } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/status_pb";
import { VendorApprovalStatus } from "@stigmer/protos/ai/stigmer/iam/oauthapp/v1/spec_pb";
import { usePersonalEnvironment } from "../environment/usePersonalEnvironment";
import { diffEnv } from "../environment/diffEnv";
import { SYSTEM_ENV_VAR_KEYS } from "../environment/systemEnvVars";
import { useOAuthGrantStatus } from "./useOAuthGrantStatus";
/**
 * Checks the user's personal environment against an MCP server's
 * `env` declarations and provides a mechanism to save missing credentials.
 *
 * Designed for the discovery flow on the MCP server detail page:
 * before triggering discovery, the UI needs to ensure all required
 * environment variables (API keys, tokens) are present. This hook
 * computes the missing set and exposes `saveCredentials` to persist
 * them.
 *
 * **Auth-mode-aware**: when `spec.auth` is configured, the hook
 * composes {@link useOAuthGrantStatus} to determine whether the
 * OAuth-managed variable (`target_env_var`) is connected via an
 * active grant. The OAuth variable is excluded from `missingVariables`
 * — it is acquired via {@link useMcpServerOAuthConnect}, not a manual
 * form. Additional non-OAuth vars still appear in `missingVariables`
 * (mixed mode).
 *
 * Unlike {@link useMcpServerSetup} which manages multi-server setup
 * for session creation, this hook is scoped to a single server and
 * always persists to the personal environment (no one-time option).
 *
 * Pass `null` for `mcpServer` while loading.
 *
 * @example
 * ```tsx
 * const creds = useMcpServerCredentials("acme", mcpServer);
 *
 * // OAuth server — sign-in button + manual override escape hatch
 * if (creds.authMode === "oauth" && !creds.isOAuthConnected) {
 *   if (creds.manualOverride) {
 *     // User opted to enter the token manually
 *     return (
 *       <>
 *         <EnvVarForm
 *           variables={creds.missingVariables}
 *           onSubmit={(values) => creds.saveCredentials(values)}
 *           isSubmitting={creds.isSaving}
 *         />
 *         <button onClick={() => creds.setManualOverride(false)}>
 *           Sign in with OAuth instead
 *         </button>
 *       </>
 *     );
 *   }
 *   return (
 *     <>
 *       <button onClick={startOAuth}>Sign in</button>
 *       <button onClick={() => creds.setManualOverride(true)}>
 *         Enter token manually
 *       </button>
 *     </>
 *   );
 * }
 *
 * // Manual vars still needed (mixed mode or manual-only)
 * if (creds.missingVariables.length > 0) {
 *   return (
 *     <EnvVarForm
 *       variables={creds.missingVariables}
 *       onSubmit={(values) => creds.saveCredentials(values)}
 *       isSubmitting={creds.isSaving}
 *       hideSaveToggle
 *     />
 *   );
 * }
 * ```
 */
export function useMcpServerCredentials(org, mcpServer) {
    const personalEnv = usePersonalEnvironment(org);
    const [manualOverride, setManualOverride] = useState(false);
    const auth = mcpServer?.spec?.auth;
    const authMode = auth ? "oauth" : "manual";
    const oauthTargetEnvVar = auth?.targetEnvVar || null;
    const tokenLifetimeHint = auth?.tokenLifetimeHint || null;
    const oauthStatus = mcpServer?.status?.oauthStatus;
    const isVendorApprovalPending = authMode === "oauth" &&
        oauthStatus?.vendorApprovalStatus === VendorApprovalStatus.PENDING;
    const isVendorApprovalBlocked = authMode === "oauth" &&
        (oauthStatus?.vendorApprovalStatus === VendorApprovalStatus.PENDING ||
            oauthStatus?.vendorApprovalStatus === VendorApprovalStatus.REJECTED);
    const vendorApprovalDocsUrl = oauthStatus?.vendorApprovalDocsUrl || null;
    const effectiveOAuthSource = oauthStatus?.effectiveOauthSource ??
        OAuthAppSource.OAUTH_APP_SOURCE_UNSPECIFIED;
    const isOrgOAuthApp = effectiveOAuthSource === OAuthAppSource.OAUTH_APP_SOURCE_ORG_OVERRIDE;
    const hasOAuthAppRef = Boolean(auth?.oauthAppRef?.slug);
    const canBringOwnApp = authMode === "oauth" && hasOAuthAppRef && !isOrgOAuthApp;
    const grantStatus = useOAuthGrantStatus(authMode === "oauth" ? (mcpServer?.metadata?.id ?? null) : null, authMode === "oauth" ? org : null);
    const isOAuthConnected = authMode === "oauth" && grantStatus.connected;
    const existingKeys = useMemo(() => new Set(Object.keys(personalEnv.environment?.spec?.data ?? {})), [personalEnv.environment]);
    const allMissingVariables = useMemo(() => {
        if (!mcpServer)
            return [];
        const envDeclarations = mcpServer.spec?.env;
        if (!envDeclarations || Object.keys(envDeclarations).length === 0)
            return [];
        return diffEnv(envDeclarations, existingKeys).filter((v) => !SYSTEM_ENV_VAR_KEYS.has(v.key));
    }, [mcpServer, existingKeys]);
    const requiredMissing = useMemo(() => allMissingVariables.filter((v) => !v.optional), [allMissingVariables]);
    const missingVariables = useMemo(() => {
        if (!oauthTargetEnvVar || manualOverride)
            return requiredMissing;
        return requiredMissing.filter((v) => v.key !== oauthTargetEnvVar);
    }, [requiredMissing, oauthTargetEnvVar, manualOverride]);
    const isReady = !personalEnv.isLoading &&
        !grantStatus.isLoading &&
        missingVariables.length === 0 &&
        (authMode === "manual" || manualOverride || isOAuthConnected);
    const saveCredentials = useCallback(async (values) => {
        await personalEnv.getOrCreate();
        await personalEnv.addVariables(values);
    }, [personalEnv]);
    const refetch = useCallback(() => {
        personalEnv.refetch();
        grantStatus.refetch();
    }, [personalEnv, grantStatus]);
    return {
        authMode,
        oauthTargetEnvVar,
        isOAuthConnected,
        connectionHealth: grantStatus.connectionHealth,
        canDisconnect: isOAuthConnected,
        accessTokenExpiresAt: grantStatus.accessTokenExpiresAt,
        tokenLifetimeHint,
        isVendorApprovalPending,
        isVendorApprovalBlocked,
        vendorApprovalDocsUrl,
        effectiveOAuthSource,
        isOrgOAuthApp,
        canBringOwnApp,
        missingVariables,
        isReady,
        isLoading: personalEnv.isLoading || grantStatus.isLoading,
        error: personalEnv.error ?? grantStatus.error,
        saveCredentials,
        isSaving: personalEnv.isMutating,
        refetch,
        manualOverride,
        setManualOverride,
    };
}
//# sourceMappingURL=useMcpServerCredentials.js.map