/**
 * 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.
 */

import { __toESM } from "../../_virtual/_rolldown/runtime.js";
import { require_classnames } from "../../node_modules/classnames/index.js";
import { pkg } from "../../settings.js";
import { usePreviousValue } from "../../global/js/hooks/usePreviousValue.js";
import { useFocus } from "../../global/js/hooks/useFocus.js";
import { getDevtoolsProps } from "../../global/js/utils/devtools.js";
import { usePortalTarget } from "../../global/js/hooks/usePortalTarget.js";
import uuidv4 from "../../global/js/utils/uuidv4.js";
import { APIKeyDownloader } from "./APIKeyDownloader.js";
import React, { forwardRef, useEffect, useRef, useState } from "react";
import PropTypes from "prop-types";
import { Button, ComposedModal, Form, InlineLoading, ModalBody, ModalFooter, ModalHeader, PasswordInput, TextInput, unstable_FeatureFlags } from "@carbon/react";
import { CheckmarkFilled, Copy, ErrorFilled, InformationFilled } from "@carbon/react/icons";

//#region src/components/APIKeyModal/APIKeyModal.tsx
var import_classnames = /* @__PURE__ */ __toESM(require_classnames());
const componentName = "APIKeyModal";
const defaults = {
	apiKeyName: "",
	customSteps: []
};
const APIKeyModal = 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] = useState(null);
	const [successMessage, setSuccessMessage] = useState(null);
	const [copyError, setCopyError] = useState(false);
	const [name, setName] = useState(apiKeyName);
	const [currentStep, setCurrentStep] = useState(0);
	const copyRef = useRef(void 0);
	const apiKeyInputId = useRef(uuidv4());
	const nameInputId = useRef(uuidv4());
	const renderPortalUse = 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.createElement(Copy, {
			size: 16,
			...props
		}),
		iconDescription: copyIconDescription,
		ref: copyRef
	};
	const blockClass = `${pkg.prefix}--apikey-modal`;
	const localRef = useRef(void 0);
	const PasswordInputRef = useRef(null);
	const modalRef = ref || localRef;
	const { firstElement, keyDownListener, claimFocus } = useFocus(modalRef);
	const prevOpen = usePreviousValue(open);
	useEffect(() => {
		if (copyRef.current && open && apiKeyLoaded) copyRef.current.focus();
		if (PasswordInputRef?.current) PasswordInputRef?.current.setAttribute("readOnly", "true");
	}, [open, apiKeyLoaded]);
	useEffect(() => {
		if (open) setTimeout(() => claimFocus(), 0);
	}, [
		modalRef,
		open,
		firstElement
	]);
	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;
	};
	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.createElement(unstable_FeatureFlags, { enableExperimentalFocusWrapWithoutSentinels: true }, /* @__PURE__ */ React.createElement(ComposedModal, {
		...rest,
		open,
		...getDevtoolsProps(componentName),
		ref: modalRef,
		onKeyDown: keyDownListener,
		className: (0, import_classnames.default)(className, blockClass),
		onClose: onCloseHandler,
		size: "sm",
		"aria-label": modalLabel,
		preventCloseOnClickOutside: true
	}, /* @__PURE__ */ React.createElement(ModalHeader, {
		className: `${blockClass}__header`,
		title,
		label: modalLabel
	}), /* @__PURE__ */ React.createElement(ModalBody, { className: `${blockClass}__body-container` }, hasSteps && !apiKeyLoaded ? customSteps[currentStep]?.content : /* @__PURE__ */ React.createElement(React.Fragment, null, body && /* @__PURE__ */ React.createElement("p", { className: `${blockClass}__body` }, body), !editing && apiKey && hasAPIKeyVisibilityToggle && /* @__PURE__ */ React.createElement(PasswordInput, {
		value: apiKey,
		labelText: apiKeyLabel,
		id: apiKeyInputId.current,
		showPasswordLabel: showAPIKeyLabel,
		hidePasswordLabel: hideAPIKeyLabel,
		tooltipPosition: "left",
		helperText,
		ref: PasswordInputRef
	}), !editing && apiKey && !hasAPIKeyVisibilityToggle && /* @__PURE__ */ React.createElement(TextInput, {
		value: apiKey,
		labelText: apiKeyLabel,
		id: apiKeyInputId.current
	}), (editing || !apiKeyLoaded && nameRequired) && /* @__PURE__ */ React.createElement(Form, {
		onSubmit: submitHandler,
		"aria-label": title ?? void 0
	}, /* @__PURE__ */ React.createElement(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.createElement(InlineLoading, {
		description: loadingText,
		className: `${blockClass}__loader`
	}), (copyError || error) && /* @__PURE__ */ React.createElement("div", { className: `${blockClass}__messaging` }, /* @__PURE__ */ React.createElement("div", { className: `${blockClass}__error-icon` }, /* @__PURE__ */ React.createElement(ErrorFilled, { size: 16 })), /* @__PURE__ */ React.createElement("p", {
		className: `${blockClass}__messaging-text`,
		role: "alert",
		"aria-live": "assertive"
	}, copyError ? copyErrorText : errorText)), apiKeyLoaded && /* @__PURE__ */ React.createElement("div", { className: `${blockClass}__messaging` }, /* @__PURE__ */ React.createElement(InformationFilled, { size: 16 }), hasDownloadLink ? /* @__PURE__ */ React.createElement(APIKeyDownloader, {
		apiKey,
		body: downloadBodyText,
		fileName: downloadFileName,
		linkText: downloadLinkText,
		fileType: downloadFileType,
		downloadLinkLabel
	}) : /* @__PURE__ */ React.createElement("div", {
		className: `${blockClass}__messaging-text`,
		role: "alert",
		"aria-live": "assertive"
	}, generateSuccessBody)), (editSuccess || apiKeyLoaded && successMessage) && /* @__PURE__ */ React.createElement("div", { className: `${blockClass}__messaging` }, /* @__PURE__ */ React.createElement(CheckmarkFilled, {
		size: 16,
		className: `${blockClass}__checkmark-icon`
	}), /* @__PURE__ */ React.createElement("p", {
		className: `${blockClass}__messaging-text`,
		role: "alert",
		"aria-live": "assertive"
	}, successMessage)))), /* @__PURE__ */ React.createElement(ModalFooter, { className: `${blockClass}__footer` }, /* @__PURE__ */ React.createElement(Button, {
		type: "button",
		kind: "secondary",
		onClick: onBackHandler
	}, getSecondaryButtonText()), /* @__PURE__ */ React.createElement(Button, {
		...apiKeyLoaded && copyButtonProps,
		type: "submit",
		kind: "primary",
		onClick: submitHandler,
		disabled: isPrimaryButtonDisabled()
	}, getPrimaryButtonText())))));
});
const deprecatedProps = {
	editSuccessTitle: PropTypes.string,
	generateSuccessTitle: PropTypes.string
};
APIKeyModal.propTypes = {
	apiKey: PropTypes.string,
	apiKeyLabel: PropTypes.string,
	apiKeyName: PropTypes.string,
	body: PropTypes.string,
	className: PropTypes.string,
	closeButtonText: PropTypes.string,
	copyButtonText: PropTypes.string,
	copyErrorText: PropTypes.string,
	copyIconDescription: PropTypes.string,
	customSteps: PropTypes.arrayOf(PropTypes.shape({
		valid: PropTypes.bool,
		content: PropTypes.node,
		title: PropTypes.string
	})),
	downloadBodyText: PropTypes.string,
	downloadFileName: PropTypes.string,
	downloadFileType: PropTypes.oneOf(["txt", "json"]),
	downloadLinkLabel: PropTypes.string,
	downloadLinkText: PropTypes.string,
	editButtonText: PropTypes.string,
	editSuccess: PropTypes.bool,
	editSuccessMessage: PropTypes.string,
	editing: PropTypes.bool,
	error: PropTypes.bool,
	errorText: PropTypes.string,
	generateButtonText: PropTypes.string,
	generateSuccessBody: PropTypes.node,
	generateSuccessMessage: PropTypes.string,
	generateTitle: PropTypes.string,
	hasAPIKeyVisibilityToggle: PropTypes.bool,
	hasDownloadLink: PropTypes.bool,
	helperText: PropTypes.string,
	hideAPIKeyLabel: PropTypes.string,
	launcherButtonRef: PropTypes.any,
	loading: PropTypes.bool,
	loadingText: PropTypes.string,
	modalLabel: PropTypes.string,
	nameHelperText: PropTypes.string,
	nameLabel: PropTypes.string,
	namePlaceholder: PropTypes.string,
	nameRequired: PropTypes.bool,
	nextStepButtonText: PropTypes.string,
	onClose: PropTypes.func,
	onCopy: PropTypes.func,
	onRequestEdit: PropTypes.func,
	onRequestGenerate: PropTypes.func,
	open: PropTypes.bool.isRequired,
	portalTarget: PropTypes.node,
	previousStepButtonText: PropTypes.string,
	showAPIKeyLabel: PropTypes.string,
	...deprecatedProps
};
APIKeyModal.displayName = componentName;

//#endregion
export { APIKeyModal };