"use client";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useCallback, useState } from "react";
import { cn } from "@stigmer/theme";
import { getUserMessage, isRetryableError } from "@stigmer/sdk";
import { OAuthConnectionHealth } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/io_pb";
import { EnvVarForm, } from "../environment/EnvVarForm";
import { McpToolSelector } from "./McpToolSelector";
/**
 * Per-server configuration panel composing a credentials form
 * ({@link EnvVarForm}) and a tool selector ({@link McpToolSelector}).
 *
 * Designed to render inside the same popover container as
 * {@link McpServerPicker}: the picker list transitions to this panel
 * when the user drills into a specific server's configuration.
 *
 * The panel's content is driven by the `credentials` prop:
 * - **Present** (server needs setup) — the credentials form is shown
 *   above the tool selector. The tool selector renders disabled as a
 *   preview of what tools the server provides.
 * - **Absent** (server is ready) — only the tool selector is shown,
 *   fully interactive for customizing which tools to enable.
 *
 * This is a **pure presentational component** with no knowledge of
 * the setup hook, personal environments, or session creation. All
 * state is controlled via props — platform builders can use it with
 * any state management approach.
 *
 * All visual properties flow through `--stgm-*` design tokens.
 *
 * @example
 * ```tsx
 * // Server that needs credentials:
 * <McpServerConfigPanel
 *   mcpServer={server}
 *   credentials={{
 *     variables: missingVars,
 *     onSubmit: (values, opts) => submitEnvVars(ref, values, opts),
 *   }}
 *   discoveredTools={tools}
 *   toolApprovals={approvals}
 *   enabledTools={defaultEnabledTools}
 *   onEnabledToolsChange={(t) => setEnabledTools(ref, t)}
 *   onBack={() => setView("list")}
 * />
 *
 * // Server that is ready (tool customization only):
 * <McpServerConfigPanel
 *   mcpServer={server}
 *   discoveredTools={tools}
 *   toolApprovals={approvals}
 *   enabledTools={entry.enabledTools}
 *   onEnabledToolsChange={(t) => setEnabledTools(ref, t)}
 *   onBack={() => setView("list")}
 * />
 * ```
 */
export function McpServerConfigPanel({ mcpServer, credentials, oauthSignIn, discoveredTools, toolApprovals, enabledTools, onEnabledToolsChange, onBack, onSwitchToManual, onSwitchToOAuth, error, disabled, className, }) {
    const serverName = mcpServer.metadata?.name ?? mcpServer.metadata?.slug ?? "MCP Server";
    const iconUrl = mcpServer.spec?.iconUrl;
    const description = mcpServer.spec?.description;
    const isDisabled = disabled || credentials?.isSubmitting;
    const isOAuthBusy = oauthSignIn
        ? oauthSignIn.phase === "initiating" ||
            oauthSignIn.phase === "awaiting-callback" ||
            oauthSignIn.phase === "completing" ||
            oauthSignIn.phase === "connecting"
        : false;
    const handleCredentialSubmit = useCallback((values, options) => {
        credentials?.onSubmit(values, options);
    }, [credentials]);
    return (_jsxs("div", { className: cn("space-y-3", className), role: "region", "aria-label": `Configure ${serverName}`, children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx("button", { type: "button", onClick: onBack, disabled: credentials?.isSubmitting || isOAuthBusy, className: cn("mt-0.5 shrink-0 rounded p-0.5", "text-muted-foreground hover:text-foreground hover:bg-accent-hover", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", "disabled:pointer-events-none disabled:opacity-50"), "aria-label": "Back to MCP server list", children: _jsx(BackArrowIcon, {}) }), _jsxs("div", { className: "flex min-w-0 flex-1 items-start gap-2", children: [iconUrl && (_jsx("img", { src: iconUrl, alt: "", width: 16, height: 16, className: "mt-0.5 size-4 shrink-0 rounded-sm object-contain" })), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("h3", { className: "truncate text-xs font-medium text-foreground", children: serverName }), description && (_jsx("p", { className: "line-clamp-2 text-[0.65rem] leading-relaxed text-muted-foreground", children: description }))] })] })] }), oauthSignIn && (_jsx(InlineOAuthSignIn, { serverName: serverName, isConnected: oauthSignIn.isConnected, connectionHealth: oauthSignIn.connectionHealth, phase: oauthSignIn.phase, onSignIn: oauthSignIn.onSignIn, onDisconnect: oauthSignIn.onDisconnect, isDisconnecting: oauthSignIn.isDisconnecting, disconnectError: oauthSignIn.disconnectError, onClearDisconnectError: oauthSignIn.onClearDisconnectError, error: oauthSignIn.error, onClearError: oauthSignIn.onClearError, isVendorApprovalPending: oauthSignIn.isVendorApprovalPending, isVendorApprovalBlocked: oauthSignIn.isVendorApprovalBlocked, vendorApprovalDocsUrl: oauthSignIn.vendorApprovalDocsUrl, canBringOwnApp: oauthSignIn.canBringOwnApp, isOrgOAuthApp: oauthSignIn.isOrgOAuthApp, onBringOwnApp: oauthSignIn.onBringOwnApp, onRemoveOrgApp: oauthSignIn.onRemoveOrgApp, isRemovingOrgApp: oauthSignIn.isRemovingOrgApp, onSwitchToManual: onSwitchToManual })), !oauthSignIn && onSwitchToOAuth && (_jsx("button", { type: "button", onClick: onSwitchToOAuth, className: "text-[0.65rem] text-muted-foreground underline decoration-muted-foreground/40 underline-offset-2 hover:text-foreground hover:decoration-foreground", children: "Sign in with OAuth instead" })), credentials && (_jsx(EnvVarForm, { variables: credentials.variables, onSubmit: handleCredentialSubmit, isSubmitting: credentials.isSubmitting, disabled: disabled || isOAuthBusy, title: "Credentials required", defaultSaveForFuture: credentials.defaultSaveForFuture, hideSaveToggle: credentials.hideSaveToggle, poolValues: credentials.poolValues, className: "w-full" })), error && (_jsx("div", { role: "alert", className: "rounded-md border border-destructive/30 bg-destructive-subtle px-2.5 py-2 text-xs text-destructive", children: getUserMessage(error) })), _jsx(McpToolSelector, { tools: discoveredTools, toolApprovals: toolApprovals, enabledTools: enabledTools, onChange: onEnabledToolsChange, disabled: !!isDisabled || !!credentials || isOAuthBusy })] }));
}
// ---------------------------------------------------------------------------
// Inline OAuth sign-in (compact, for config panel context)
// ---------------------------------------------------------------------------
/** Maps OAuthConnectionHealth to compact status dot + label for InlineOAuthSignIn. */
function inlineHealthProps(health, isConnected, isVendorApprovalPending) {
    if (isVendorApprovalPending && !isConnected) {
        return {
            textClass: "text-amber-600 dark:text-amber-400",
            dotClass: "bg-amber-500",
            label: "Pending approval",
        };
    }
    switch (health) {
        case OAuthConnectionHealth.OAUTH_CONNECTION_HEALTH_HEALTHY:
            return {
                textClass: "text-success",
                dotClass: "bg-success",
                label: "Signed in",
            };
        case OAuthConnectionHealth.OAUTH_CONNECTION_HEALTH_TOKEN_EXPIRED_REFRESHABLE:
            return {
                textClass: "text-amber-600 dark:text-amber-400",
                dotClass: "bg-amber-500",
                label: "Token expired",
            };
        case OAuthConnectionHealth.OAUTH_CONNECTION_HEALTH_TOKEN_EXPIRED:
            return {
                textClass: "text-destructive",
                dotClass: "bg-destructive",
                label: "Re-auth needed",
            };
        default:
            return {
                textClass: "text-muted-foreground",
                dotClass: "bg-muted-foreground",
                label: "Sign-in required",
            };
    }
}
function InlineOAuthSignIn({ serverName, isConnected, connectionHealth, phase, onSignIn, onDisconnect, isDisconnecting, disconnectError, onClearDisconnectError, error, onClearError, isVendorApprovalPending, isVendorApprovalBlocked, vendorApprovalDocsUrl, canBringOwnApp, isOrgOAuthApp, onBringOwnApp, onRemoveOrgApp, isRemovingOrgApp, onSwitchToManual, }) {
    const [disconnectPhase, setDisconnectPhase] = useState("idle");
    const [removeOrgAppPhase, setRemoveOrgAppPhase] = useState("idle");
    const blocked = isVendorApprovalBlocked ?? isVendorApprovalPending;
    const isBusy = phase === "initiating" ||
        phase === "awaiting-callback" ||
        phase === "completing" ||
        phase === "connecting";
    const signInDisabled = isBusy || (!!blocked && !isOrgOAuthApp);
    const anyBusy = isBusy || !!isDisconnecting || !!isRemovingOrgApp;
    const needsReAuth = connectionHealth === OAuthConnectionHealth.OAUTH_CONNECTION_HEALTH_TOKEN_EXPIRED;
    const status = inlineHealthProps(connectionHealth, isConnected, !!isVendorApprovalPending && !isOrgOAuthApp);
    const showDisconnectLink = isConnected && onDisconnect && !anyBusy && disconnectPhase === "idle";
    const showRemoveOrgAppLink = isOrgOAuthApp && onRemoveOrgApp && !anyBusy && removeOrgAppPhase === "idle";
    // Inline disconnect confirmation
    if (disconnectPhase === "confirming" || disconnectPhase === "disconnecting") {
        return (_jsxs("div", { className: "space-y-1.5", children: [_jsx("p", { className: "text-[0.65rem] text-foreground", children: "Remove credentials? You can reconnect at any time." }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsxs("button", { type: "button", disabled: !!isDisconnecting, onClick: async () => {
                                if (!onDisconnect)
                                    return;
                                setDisconnectPhase("disconnecting");
                                try {
                                    await onDisconnect();
                                    setDisconnectPhase("idle");
                                }
                                catch {
                                    setDisconnectPhase("confirming");
                                }
                            }, className: cn("inline-flex items-center gap-1 rounded px-2 py-0.5 text-[0.65rem] font-medium", "bg-destructive text-destructive-foreground hover:bg-destructive-hover", "disabled:pointer-events-none disabled:opacity-50"), children: [isDisconnecting && _jsx(InlineSpinner, {}), "Disconnect"] }), _jsx("button", { type: "button", disabled: !!isDisconnecting, onClick: () => {
                                setDisconnectPhase("idle");
                                onClearDisconnectError?.();
                            }, className: cn("inline-flex items-center rounded px-2 py-0.5 text-[0.65rem] font-medium", "text-muted-foreground hover:text-foreground hover:bg-accent-hover", "disabled:pointer-events-none disabled:opacity-50"), children: "Cancel" })] }), disconnectError && (_jsxs("div", { className: "flex items-start gap-1.5 text-[0.65rem] text-destructive", role: "alert", children: [_jsx("span", { className: "flex-1", children: getUserMessage(disconnectError) }), _jsx("button", { type: "button", onClick: () => onClearDisconnectError?.(), className: "shrink-0 underline underline-offset-2 hover:no-underline", children: "Dismiss" })] }))] }));
    }
    // Inline "remove custom app" confirmation
    if (removeOrgAppPhase === "confirming" || removeOrgAppPhase === "removing") {
        return (_jsxs("div", { className: "space-y-1.5", children: [_jsx("p", { className: "text-[0.65rem] text-foreground", children: "Remove your custom OAuth app? The server will revert to the platform's app." }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsxs("button", { type: "button", disabled: !!isRemovingOrgApp, onClick: async () => {
                                if (!onRemoveOrgApp)
                                    return;
                                setRemoveOrgAppPhase("removing");
                                try {
                                    await onRemoveOrgApp();
                                    setRemoveOrgAppPhase("idle");
                                }
                                catch {
                                    setRemoveOrgAppPhase("confirming");
                                }
                            }, className: cn("inline-flex items-center gap-1 rounded px-2 py-0.5 text-[0.65rem] font-medium", "bg-destructive text-destructive-foreground hover:bg-destructive-hover", "disabled:pointer-events-none disabled:opacity-50"), children: [isRemovingOrgApp && _jsx(InlineSpinner, {}), "Remove"] }), _jsx("button", { type: "button", disabled: !!isRemovingOrgApp, onClick: () => setRemoveOrgAppPhase("idle"), className: cn("inline-flex items-center rounded px-2 py-0.5 text-[0.65rem] font-medium", "text-muted-foreground hover:text-foreground hover:bg-accent-hover", "disabled:pointer-events-none disabled:opacity-50"), children: "Cancel" })] })] }));
    }
    return (_jsxs("div", { className: "space-y-1.5", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsxs("span", { className: cn("inline-flex items-center gap-1 text-[0.65rem] font-medium", status.textClass), children: [_jsx("span", { className: cn("size-1.5 rounded-full", status.dotClass), "aria-hidden": "true" }), status.label] }), isOrgOAuthApp && isConnected && (_jsx("span", { className: "text-[0.6rem] text-muted-foreground", children: "Your app" })), showDisconnectLink && (_jsx("button", { type: "button", onClick: () => setDisconnectPhase("confirming"), className: "text-[0.65rem] text-muted-foreground underline decoration-muted-foreground/40 underline-offset-2 hover:text-foreground hover:decoration-foreground", children: "Disconnect" })), showRemoveOrgAppLink && (_jsx("button", { type: "button", onClick: () => setRemoveOrgAppPhase("confirming"), className: "text-[0.65rem] text-muted-foreground underline decoration-muted-foreground/40 underline-offset-2 hover:text-foreground hover:decoration-foreground", children: "Remove custom app" }))] }), _jsx("button", { type: "button", onClick: onSignIn, disabled: signInDisabled, className: cn("inline-flex items-center gap-1 rounded px-2 py-0.5 text-[0.65rem] font-medium", isConnected && !needsReAuth
                            ? "text-muted-foreground hover:text-foreground hover:bg-accent-hover"
                            : "bg-primary text-primary-foreground hover:bg-primary-hover", "disabled:pointer-events-none disabled:opacity-50"), children: isBusy ? (_jsx(InlineSpinner, {})) : isOrgOAuthApp && !isConnected ? ("Sign in with your app") : isConnected && !needsReAuth ? ("Re-authenticate") : needsReAuth ? ("Sign in to reconnect") : (`Sign in with ${serverName}`) })] }), blocked && !isConnected && !isOrgOAuthApp && (_jsxs("div", { className: "text-[0.65rem] text-amber-700 dark:text-amber-300", children: [_jsxs("p", { children: ["OAuth sign-in is pending vendor approval.", canBringOwnApp && onBringOwnApp
                                ? " You can use your own OAuth app or enter a token manually."
                                : ""] }), canBringOwnApp && onBringOwnApp && (_jsx("button", { type: "button", onClick: onBringOwnApp, className: "mt-1 inline-flex items-center gap-1 rounded bg-amber-600 px-2 py-0.5 text-[0.6rem] font-medium text-white hover:bg-amber-700 dark:bg-amber-500 dark:text-amber-950 dark:hover:bg-amber-400", children: "Use your own OAuth app" })), vendorApprovalDocsUrl && !canBringOwnApp && (_jsx("a", { href: vendorApprovalDocsUrl, target: "_blank", rel: "noopener noreferrer", className: "underline decoration-amber-600/40 underline-offset-2 hover:decoration-amber-600 dark:decoration-amber-400/40 dark:hover:decoration-amber-400", children: "Learn how to bring your own token" }))] })), isOrgOAuthApp && !isConnected && (_jsx("span", { className: "text-[0.6rem] text-muted-foreground", children: "Using your OAuth app" })), error && (_jsxs("div", { className: "flex items-start gap-1.5 text-[0.65rem] text-destructive", role: "alert", children: [_jsx("span", { className: "flex-1", children: getUserMessage(error) }), _jsxs("div", { className: "flex shrink-0 items-center gap-1.5", children: [isRetryableError(error) && (_jsx("button", { type: "button", onClick: () => {
                                    onClearError();
                                    onSignIn();
                                }, className: "font-medium underline underline-offset-2 hover:no-underline", children: "Try again" })), _jsx("button", { type: "button", onClick: onClearError, className: "underline underline-offset-2 hover:no-underline", children: "Dismiss" })] })] })), !isConnected && !isBusy && (_jsxs("div", { className: "flex items-center gap-2", children: [onSwitchToManual && (_jsx("button", { type: "button", onClick: onSwitchToManual, className: "text-[0.65rem] text-muted-foreground underline decoration-muted-foreground/40 underline-offset-2 hover:text-foreground hover:decoration-foreground", children: "Enter token manually" })), canBringOwnApp && onBringOwnApp && !blocked && (_jsx("button", { type: "button", onClick: onBringOwnApp, className: "text-[0.65rem] text-muted-foreground underline decoration-muted-foreground/40 underline-offset-2 hover:text-foreground hover:decoration-foreground", children: "Use your own OAuth app" }))] }))] }));
}
function InlineSpinner() {
    return (_jsx("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", className: "animate-spin", "aria-hidden": "true", children: _jsx("path", { d: "M8 2a6 6 0 1 0 6 6" }) }));
}
// ---------------------------------------------------------------------------
// Icons (internal to this module)
// ---------------------------------------------------------------------------
function BackArrowIcon() {
    return (_jsx("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: _jsx("path", { d: "M10 3L5 8l5 5" }) }));
}
//# sourceMappingURL=McpServerConfigPanel.js.map