/**
 * Copyright IBM Corp. 2020, 2026
 *
 * This source code is licensed under the Apache-2.0 license found in the
 * LICENSE file in the root directory of this source tree.
 */

const require_runtime = require("../../_virtual/_rolldown/runtime.js");
const require_index = require("../../node_modules/classnames/index.js");
const require_settings = require("../../settings.js");
const require_usePreviousValue = require("../../global/js/hooks/usePreviousValue.js");
const require_useFocus = require("../../global/js/hooks/useFocus.js");
const require_devtools = require("../../global/js/utils/devtools.js");
const require_usePortalTarget = require("../../global/js/hooks/usePortalTarget.js");
const require_uuidv4 = require("../../global/js/utils/uuidv4.js");
const require_APIKeyDownloader = require("./APIKeyDownloader.js");
let react = require("react");
react = require_runtime.__toESM(react);
let prop_types = require("prop-types");
prop_types = require_runtime.__toESM(prop_types);
let _carbon_react = require("@carbon/react");
let _carbon_react_icons = require("@carbon/react/icons");
//#region src/components/APIKeyModal/APIKeyModal.tsx
var import_classnames = /* @__PURE__ */ require_runtime.__toESM(require_index.default);
const componentName = "APIKeyModal";
const defaults = {
	apiKeyName: "",
	customSteps: []
};
const APIKeyModal = (0, react.forwardRef)(({ apiKey, apiKeyLabel, apiKeyName = defaults.apiKeyName, body, className, closeButtonText, copyButtonText, copyErrorText, copyIconDescription, customSteps = defaults.customSteps, downloadBodyText, downloadFileName, downloadFileType, downloadLinkText, downloadLinkLabel = downloadLinkText, editButtonText, editSuccess, editSuccessTitle, editSuccessMessage, editing, error, errorText, generateButtonText, generateSuccessBody, generateSuccessTitle, generateSuccessMessage, generateTitle, hasAPIKeyVisibilityToggle, hasDownloadLink, hideAPIKeyLabel, launcherButtonRef, loading, loadingText, modalLabel, nameHelperText, nameLabel, namePlaceholder, nameRequired, nextStepButtonText, onClose, onCopy, onRequestEdit, onRequestGenerate, open, portalTarget: portalTargetIn, previousStepButtonText, showAPIKeyLabel, helperText, ...rest }, ref) => {
	const [title, setTitle] = (0, react.useState)(null);
	const [successMessage, setSuccessMessage] = (0, react.useState)(null);
	const [copyError, setCopyError] = (0, react.useState)(false);
	const [name, setName] = (0, react.useState)(apiKeyName);
	const [currentStep, setCurrentStep] = (0, react.useState)(0);
	const copyRef = (0, react.useRef)(void 0);
	const apiKeyInputId = (0, react.useRef)(require_uuidv4.default());
	const nameInputId = (0, react.useRef)(require_uuidv4.default());
	const renderPortalUse = require_usePortalTarget.usePortalTarget(portalTargetIn);
	const hasSteps = Boolean(customSteps.length);
	const apiKeyLoaded = apiKey && !loading;
	const hasNextStep = hasSteps && currentStep < customSteps.length - 1;
	const hasPreviousStep = hasSteps && currentStep !== 0;
	const copyButtonProps = {
		renderIcon: (props) => /* @__PURE__ */ react.default.createElement(_carbon_react_icons.Copy, {
			size: 16,
			...props
		}),
		iconDescription: copyIconDescription,
		ref: copyRef
	};
	const blockClass = `${require_settings.pkg.prefix}--apikey-modal`;
	const localRef = (0, react.useRef)(void 0);
	const PasswordInputRef = (0, react.useRef)(null);
	const modalRef = ref || localRef;
	const { firstElement, keyDownListener, claimFocus } = require_useFocus.useFocus(modalRef);
	const prevOpen = require_usePreviousValue.usePreviousValue(open);
	(0, react.useEffect)(() => {
		if (copyRef.current && open && apiKeyLoaded) copyRef.current.focus();
		if (PasswordInputRef?.current) PasswordInputRef?.current.setAttribute("readOnly", "true");
	}, [open, apiKeyLoaded]);
	(0, react.useEffect)(() => {
		if (open) setTimeout(() => claimFocus(), 0);
	}, [
		modalRef,
		open,
		firstElement
	]);
	(0, react.useEffect)(() => {
		if (prevOpen && !open && launcherButtonRef) setTimeout(() => {
			launcherButtonRef.current.focus();
		}, 0);
	}, [
		launcherButtonRef,
		open,
		prevOpen
	]);
	const isPrimaryButtonDisabled = () => {
		if (loading) return true;
		if (hasSteps && "valid" in (customSteps?.[currentStep] || [])) return !customSteps[currentStep]?.valid;
		if (!hasSteps && nameRequired && !name) return true;
		return false;
	};
	const getPrimaryButtonText = () => {
		if (hasNextStep) return nextStepButtonText;
		if (apiKeyLoaded) return copyButtonText;
		if (editing) return editButtonText;
		return generateButtonText;
	};
	const getSecondaryButtonText = () => {
		if (hasPreviousStep && !apiKeyLoaded) return previousStepButtonText;
		return closeButtonText;
	};
	(0, react.useEffect)(() => {
		if (editing && editSuccess) {
			setTitle(generateTitle);
			setSuccessMessage(editSuccessMessage ?? editSuccessTitle);
		} else if (apiKeyLoaded) {
			setTitle(generateTitle);
			setSuccessMessage(generateSuccessMessage ?? generateSuccessTitle);
		} else if (hasSteps) setTitle(customSteps[currentStep]?.title);
		else setTitle(generateTitle);
	}, [
		apiKeyLoaded,
		loading,
		editing,
		editSuccess,
		editSuccessTitle,
		editSuccessMessage,
		hasSteps,
		generateSuccessTitle,
		generateSuccessMessage,
		generateTitle,
		currentStep,
		customSteps
	]);
	const setNameHandler = (evt) => {
		setName(evt.target.value);
	};
	const onCloseHandler = () => {
		setName("");
		setCurrentStep(0);
		onClose?.();
	};
	const submitHandler = async (e) => {
		e.preventDefault();
		if (hasNextStep) setCurrentStep(currentStep + 1);
		else if (apiKeyLoaded) if (onCopy) onCopy(apiKey);
		else try {
			await navigator.clipboard.writeText(apiKey);
		} catch (e) {
			console.error(e);
			setCopyError(true);
		}
		else if (editing) onRequestEdit?.(name);
		else onRequestGenerate?.(name);
	};
	const onBackHandler = () => {
		if (hasPreviousStep && !apiKeyLoaded) setCurrentStep(currentStep - 1);
		else onCloseHandler();
	};
	return renderPortalUse(/* @__PURE__ */ react.default.createElement(_carbon_react.unstable_FeatureFlags, { enableExperimentalFocusWrapWithoutSentinels: true }, /* @__PURE__ */ react.default.createElement(_carbon_react.ComposedModal, {
		...rest,
		open,
		...require_devtools.getDevtoolsProps(componentName),
		ref: modalRef,
		onKeyDown: keyDownListener,
		className: (0, import_classnames.default)(className, blockClass),
		onClose: onCloseHandler,
		size: "sm",
		"aria-label": modalLabel,
		preventCloseOnClickOutside: true
	}, /* @__PURE__ */ react.default.createElement(_carbon_react.ModalHeader, {
		className: `${blockClass}__header`,
		title,
		label: modalLabel
	}), /* @__PURE__ */ react.default.createElement(_carbon_react.ModalBody, { className: `${blockClass}__body-container` }, hasSteps && !apiKeyLoaded ? customSteps[currentStep]?.content : /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, body && /* @__PURE__ */ react.default.createElement("p", { className: `${blockClass}__body` }, body), !editing && apiKey && hasAPIKeyVisibilityToggle && /* @__PURE__ */ react.default.createElement(_carbon_react.PasswordInput, {
		value: apiKey,
		labelText: apiKeyLabel,
		id: apiKeyInputId.current,
		showPasswordLabel: showAPIKeyLabel,
		hidePasswordLabel: hideAPIKeyLabel,
		tooltipPosition: "left",
		helperText,
		ref: PasswordInputRef
	}), !editing && apiKey && !hasAPIKeyVisibilityToggle && /* @__PURE__ */ react.default.createElement(_carbon_react.TextInput, {
		value: apiKey,
		labelText: apiKeyLabel,
		id: apiKeyInputId.current
	}), (editing || !apiKeyLoaded && nameRequired) && /* @__PURE__ */ react.default.createElement(_carbon_react.Form, {
		onSubmit: submitHandler,
		"aria-label": title ?? void 0
	}, /* @__PURE__ */ react.default.createElement(_carbon_react.TextInput, {
		helperText: nameHelperText,
		placeholder: namePlaceholder,
		labelText: nameLabel,
		onChange: setNameHandler,
		value: name,
		id: nameInputId.current,
		disabled: loading,
		required: nameRequired,
		"data-modal-primary-focus": true
	})), loading && /* @__PURE__ */ react.default.createElement(_carbon_react.InlineLoading, {
		description: loadingText,
		className: `${blockClass}__loader`
	}), (copyError || error) && /* @__PURE__ */ react.default.createElement("div", { className: `${blockClass}__messaging` }, /* @__PURE__ */ react.default.createElement("div", { className: `${blockClass}__error-icon` }, /* @__PURE__ */ react.default.createElement(_carbon_react_icons.ErrorFilled, { size: 16 })), /* @__PURE__ */ react.default.createElement("p", {
		className: `${blockClass}__messaging-text`,
		role: "alert",
		"aria-live": "assertive"
	}, copyError ? copyErrorText : errorText)), apiKeyLoaded && /* @__PURE__ */ react.default.createElement("div", { className: `${blockClass}__messaging` }, /* @__PURE__ */ react.default.createElement(_carbon_react_icons.InformationFilled, { size: 16 }), hasDownloadLink ? /* @__PURE__ */ react.default.createElement(require_APIKeyDownloader.APIKeyDownloader, {
		apiKey,
		body: downloadBodyText,
		fileName: downloadFileName,
		linkText: downloadLinkText,
		fileType: downloadFileType,
		downloadLinkLabel
	}) : /* @__PURE__ */ react.default.createElement("div", {
		className: `${blockClass}__messaging-text`,
		role: "alert",
		"aria-live": "assertive"
	}, generateSuccessBody)), (editSuccess || apiKeyLoaded && successMessage) && /* @__PURE__ */ react.default.createElement("div", { className: `${blockClass}__messaging` }, /* @__PURE__ */ react.default.createElement(_carbon_react_icons.CheckmarkFilled, {
		size: 16,
		className: `${blockClass}__checkmark-icon`
	}), /* @__PURE__ */ react.default.createElement("p", {
		className: `${blockClass}__messaging-text`,
		role: "alert",
		"aria-live": "assertive"
	}, successMessage)))), /* @__PURE__ */ react.default.createElement(_carbon_react.ModalFooter, { className: `${blockClass}__footer` }, /* @__PURE__ */ react.default.createElement(_carbon_react.Button, {
		type: "button",
		kind: "secondary",
		onClick: onBackHandler
	}, getSecondaryButtonText()), /* @__PURE__ */ react.default.createElement(_carbon_react.Button, {
		...apiKeyLoaded && copyButtonProps,
		type: "submit",
		kind: "primary",
		onClick: submitHandler,
		disabled: isPrimaryButtonDisabled()
	}, getPrimaryButtonText())))));
});
const deprecatedProps = {
	/**
	* deprecated
	* title for a successful edit
	*/
	editSuccessTitle: prop_types.default.string,
	/**
	* deprecated
	* title for a successful key generation
	*/
	generateSuccessTitle: prop_types.default.string
};
APIKeyModal.propTypes = {
	/**
	* the api key that's displayed to the user when a request to create is fulfilled.
	*/
	apiKey: prop_types.default.string,
	/**
	* label for the text input that holds the api key.
	*/
	apiKeyLabel: prop_types.default.string,
	/**
	* the name of the api key. should only be supplied in edit mode.
	*/
	apiKeyName: prop_types.default.string,
	/**
	* body content for the modal
	*/
	body: prop_types.default.string,
	/**
	* optional class name
	*/
	className: prop_types.default.string,
	/**
	* text for the close button
	*/
	closeButtonText: prop_types.default.string,
	/**
	* text for the copy button
	*/
	copyButtonText: prop_types.default.string,
	/**
	* Error message for when the copy function fails
	*/
	copyErrorText: prop_types.default.string,
	/**
	* text description for the copy button icon
	*/
	copyIconDescription: prop_types.default.string,
	/**
	* if you need more options for key creation beyond just the name use custom steps to obtain whatever data is required.
	*/
	/**@ts-ignore*/
	customSteps: prop_types.default.arrayOf(prop_types.default.shape({
		/**
		* designates if the step has passed whatever validation rules are in place.
		*/
		valid: prop_types.default.bool,
		/**
		* designates content is the JSX that holds whatever inputs you need
		*/
		content: prop_types.default.node,
		/**
		* designates the title that's displayed at the top of the modal for each step
		*/
		title: prop_types.default.string
	})),
	/**
	* the content that appears that indicates the key is downloadable
	*/
	downloadBodyText: prop_types.default.string,
	/**
	* designates the name of downloadable json file with the key. if not specified will default to 'apikey'
	*/
	downloadFileName: prop_types.default.string,
	/**
	* designates the file type for the downloadable key
	*/
	downloadFileType: prop_types.default.oneOf(["txt", "json"]),
	/**
	* aria-label for the download link
	*/
	downloadLinkLabel: prop_types.default.string,
	/**
	* anchor text for the download link
	*/
	downloadLinkText: prop_types.default.string,
	/**
	* text for the edit button
	*/
	editButtonText: prop_types.default.string,
	/**
	* designates if the edit request was successful
	*/
	editSuccess: prop_types.default.bool,
	/**
	* title for a successful edit
	*/
	editSuccessMessage: prop_types.default.string,
	/**
	* designates if the modal is in the edit mode
	*/
	editing: prop_types.default.bool,
	/**
	* designates if an error has occurred in a request
	*/
	error: prop_types.default.bool,
	/**
	* text to display if an error has occurred
	*/
	errorText: prop_types.default.string,
	/**
	* default primary button text for modal in assumed default mode create or generate.
	* in create mode this is the button text prior to supplying an api key, which then
	* uses copyButtonText
	*/
	generateButtonText: prop_types.default.string,
	/**
	* content to display if generate request was successful
	*/
	generateSuccessBody: prop_types.default.node,
	/**
	* title for a successful key generation
	*/
	generateSuccessMessage: prop_types.default.string,
	/**
	* default title for the modal in generate key mode
	*/
	generateTitle: prop_types.default.string,
	/**
	* designates if the api input has the visibility toggle enabled
	*/
	hasAPIKeyVisibilityToggle: prop_types.default.bool,
	/**
	* designates if user is able to download the api key
	*/
	hasDownloadLink: prop_types.default.bool,
	/**
	* helper text for password input
	*/
	helperText: prop_types.default.string,
	/**
	* label text that's displayed when hovering over visibility toggler to hide key
	*/
	hideAPIKeyLabel: prop_types.default.string,
	/**
	* Provide a ref to return focus to once the tearsheet is closed.
	*/
	/**@ts-ignore */
	launcherButtonRef: prop_types.default.any,
	/**
	* designates if the modal is in a loading state via a request or some other in progress operation
	*/
	loading: prop_types.default.bool,
	/**
	* text that displays while modal is in the loading state
	*/
	loadingText: prop_types.default.string,
	/**
	* general label text for modal
	*/
	modalLabel: prop_types.default.string,
	/**
	* helper text for name input
	*/
	nameHelperText: prop_types.default.string,
	/**
	* label for api key name input
	*/
	nameLabel: prop_types.default.string,
	/**
	* placeholder text for api key name input
	*/
	namePlaceholder: prop_types.default.string,
	/**
	* designates if a name is required or not for key generation. NOTE- if using custom steps set this to false since you will be using your own validation
	*/
	nameRequired: prop_types.default.bool,
	/**
	* text that displays in the primary button when using custom steps to indicate to the user that there is a next step
	*/
	nextStepButtonText: prop_types.default.string,
	/**
	* handler for on modal close
	*/
	onClose: prop_types.default.func,
	/**
	* Optional callback if you want to use your own copy function instead of the build in one
	* onCopy(apiKey)
	*/
	onCopy: prop_types.default.func,
	/**
	* handler for api key edit
	*/
	onRequestEdit: prop_types.default.func,
	/**
	* handler for api key generation
	*/
	onRequestGenerate: prop_types.default.func,
	/**
	* designates if modal is open or closed
	*/
	open: prop_types.default.bool.isRequired,
	/**
	* The DOM node the tearsheet should be rendered within. Defaults to document.body.
	*/
	portalTarget: prop_types.default.node,
	/**
	* text that displays in the secondary button when using custom steps to indicate to the user that there is a previous step
	*/
	previousStepButtonText: prop_types.default.string,
	/**
	* label text that's displayed when hovering over visibility toggler to show key
	*/
	showAPIKeyLabel: prop_types.default.string,
	...deprecatedProps
};
APIKeyModal.displayName = componentName;
//#endregion
exports.APIKeyModal = APIKeyModal;
