/**
 * Copyright IBM Corp. 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 "../../globals/settings.js";
import { carbonElement } from "../../globals/decorators/carbon-element.js";
import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.126.0/helpers/decorate.js";
import iconLoader from "../../globals/internal/icon-loader.js";
import FocusMixin from "../../globals/mixins/focus.js";
import "../button/button.js";
import { FORM_ELEMENT_COLOR_SCHEME } from "../../globals/shared-enums.js";
import { CODE_SNIPPET_TYPE } from "./defs.js";
import code_snippet_default$1 from "./code-snippet.scss.js";
import "../copy/copy.js";
import "../copy-button/index.js";
import { LitElement, html } from "lit";
import { property } from "lit/decorators.js";
import { styleMap } from "lit/directives/style-map.js";
import ChevronDown16 from "@carbon/icons/es/chevron--down/16.js";
//#region src/components/code-snippet/code-snippet.ts
/**
* Copyright IBM Corp. 2019, 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.
*/
/**  eslint-disable @typescript-eslint/no-non-null-assertion -- https://github.com/carbon-design-system/carbon/issues/20452 */
/**
* Observes resize of the given element with the given resize observer.
*
* @param observer The resize observer.
* @param elem The element to observe the resize.
*/
const observeResize = (observer, elem) => {
	if (!elem) return null;
	observer.observe(elem);
	return { release() {
		observer.unobserve(elem);
		return null;
	} };
};
/**
* Basic code snippet.
*
* @element cds-custom-code-snippet
*/
let CDSCodeSnippet = class CDSCodeSnippet extends FocusMixin(LitElement) {
	constructor(..._args) {
		super(..._args);
		this._expandedCode = false;
		this._hObserveResize = null;
		this._rowHeightInPixels = 16;
		this._hasRightOverflow = true;
		this._hasLeftOverflow = false;
		this._shouldShowMoreLessBtn = false;
		this._resizeObserver = new ResizeObserver(() => {
			const codeContainerRef = this.shadowRoot?.querySelector(`.cds-custom--snippet-container`);
			const codeContentRef = codeContainerRef?.querySelector("code");
			const { type, maxCollapsedNumberOfRows, maxExpandedNumberOfRows, minExpandedNumberOfRows, _rowHeightInPixels: rowHeightInPixels, _handleScroll: handleScroll } = this;
			if (codeContentRef && type === "multi") {
				const { height } = codeContentRef.getBoundingClientRect();
				if (maxCollapsedNumberOfRows > 0 && (maxExpandedNumberOfRows <= 0 || maxExpandedNumberOfRows > maxCollapsedNumberOfRows) && height > maxCollapsedNumberOfRows * rowHeightInPixels) this._shouldShowMoreLessBtn = true;
				else this._shouldShowMoreLessBtn = false;
				if (this._expandedCode && minExpandedNumberOfRows > 0 && height <= minExpandedNumberOfRows * rowHeightInPixels) this._expandedCode = false;
			}
			if (codeContentRef && type === "multi" || codeContainerRef && type === "single") handleScroll();
			this.requestUpdate();
		});
		this.copyText = "";
		this.disabled = false;
		this.feedback = "Copied!";
		this.feedbackTimeout = 2e3;
		this.hideCopyButton = false;
		this.maxCollapsedNumberOfRows = 15;
		this.maxExpandedNumberOfRows = 0;
		this.minCollapsedNumberOfRows = 3;
		this.minExpandedNumberOfRows = 16;
		this.showLessText = "Show less";
		this.showMoreText = "Show more";
		this.tooltipContent = "Copy to clipboard";
		this.wrapText = false;
		this.type = "single";
	}
	/**
	* Handles `click` event on the copy button.
	*/
	_handleCopyClick() {
		const { ownerDocument: doc } = this;
		const selection = doc.defaultView.getSelection();
		selection.removeAllRanges();
		const code = doc.createElement("code");
		code.className = `cds-custom--visually-hidden`;
		const pre = doc.createElement("pre");
		const text = Array.from(this.childNodes).filter((node) => node.nodeType === Node.TEXT_NODE);
		pre.textContent = this.copyText || text[0].textContent;
		code.appendChild(pre);
		doc.body.appendChild(code);
		const range = doc.createRange();
		range.selectNodeContents(code);
		selection.addRange(range);
		doc.execCommand("copy");
		doc.body.removeChild(code);
		selection.removeAllRanges();
	}
	_getCodeRefDimensions(ref) {
		const { clientWidth: codeClientWidth, scrollLeft: codeScrollLeft, scrollWidth: codeScrollWidth } = ref;
		return {
			horizontalOverflow: codeScrollWidth > codeClientWidth,
			codeClientWidth,
			codeScrollWidth,
			codeScrollLeft
		};
	}
	/**
	* Handles `scroll` event.
	*/
	_handleScroll() {
		if (this) {
			const codeContainerRef = this?.shadowRoot?.querySelector(`.cds-custom--snippet-container`);
			const codeContentRef = codeContainerRef?.querySelector("pre");
			if (this.type === "inline" || this.type === "single" && !codeContainerRef || this.type === "multi" && !codeContentRef) return;
			const { horizontalOverflow, codeClientWidth, codeScrollWidth, codeScrollLeft } = this.type === "single" ? this._getCodeRefDimensions(codeContainerRef) : this._getCodeRefDimensions(codeContentRef);
			this._hasLeftOverflow = horizontalOverflow && !!codeScrollLeft;
			this._hasRightOverflow = horizontalOverflow && codeScrollLeft + codeClientWidth !== codeScrollWidth;
			this.requestUpdate();
		}
	}
	/**
	* Handles `click` event on the show more or show less button.
	*/
	_handleClickExpanded() {
		this._expandedCode = !this._expandedCode;
		this.requestUpdate();
	}
	connectedCallback() {
		super.connectedCallback();
		if (this._hObserveResize) this._hObserveResize = this._hObserveResize.release();
		this._hObserveResize = observeResize(this._resizeObserver, this);
	}
	disconnectedCallback() {
		if (this._hObserveResize) this._hObserveResize = this._hObserveResize.release();
	}
	updated() {
		if (this._expandedCode) this.setAttribute("expanded-code", "");
		else this.removeAttribute("expanded-code");
	}
	render() {
		const { disabled, feedback, feedbackTimeout, hideCopyButton, maxExpandedNumberOfRows, minExpandedNumberOfRows, maxCollapsedNumberOfRows, minCollapsedNumberOfRows, type, wrapText, tooltipContent, showMoreText, showLessText, _expandedCode: expandedCode, _handleCopyClick: handleCopyClick, _handleScroll: handleScroll, _hasRightOverflow: hasRightOverflow, _hasLeftOverflow: hasLeftOverflow, _rowHeightInPixels: rowHeightInPixels, _shouldShowMoreLessBtn: shouldShowMoreLessBtn } = this;
		let classes = `cds-custom--snippet`;
		if (type) classes += ` cds-custom--snippet--${type}`;
		if (type !== "inline" && disabled) classes += ` cds-custom--snippet--disabled`;
		if (hideCopyButton) classes += ` cds-custom--snippet--no-copy`;
		if (wrapText) classes += ` cds-custom--snippet--wraptext`;
		if (type == "multi" && hasRightOverflow) classes += ` cds-custom--snippet--has-right-overflow`;
		const expandButtonClass = `cds-custom--snippet-btn--expand`;
		const disabledCopyButtonClasses = disabled ? `cds-custom--snippet--disabled` : "";
		const expandCodeBtnText = expandedCode ? showLessText : showMoreText;
		if (type === "inline") return html`
        <cds-custom-copy ?disabled=${disabled} button-class-name="${classes}" @click="${handleCopyClick}">
          <code slot="icon"><slot></slot></code>
          <span slot="tooltip-content">${tooltipContent}</span>
        </cds-custom-copy>
      `;
		const styles = {};
		if (type === "multi") if (expandedCode) {
			if (maxExpandedNumberOfRows > 0) styles["max-height"] = maxExpandedNumberOfRows * rowHeightInPixels + "px";
			if (minExpandedNumberOfRows > 0) styles["min-height"] = minExpandedNumberOfRows * rowHeightInPixels + "px";
		} else {
			if (maxCollapsedNumberOfRows > 0) styles["max-height"] = maxCollapsedNumberOfRows * rowHeightInPixels + "px";
			if (minCollapsedNumberOfRows > 0) styles["min-height"] = minCollapsedNumberOfRows * rowHeightInPixels + "px";
		}
		return html`
      <div
        role="${type === "single" || type === "multi" ? "textbox" : null}"
        tabindex="${(type === "single" || type === "multi") && !disabled ? 0 : null}"
        class="${"cds-custom"}--snippet-container"
        aria-label="${"code-snippet"}"
        aria-readonly="${type === "single" || type === "multi" ? true : null}"
        aria-multiline="${type === "multi" ? true : null}"
        @scroll="${type === "single" && handleScroll || null}"
        style=${styleMap(styles)}>
        <pre
          @scroll="${type === "multi" && handleScroll || null}"><code><slot></slot></code></pre>
      </div>

      ${hasLeftOverflow ? html`
            <div class="${"cds-custom"}--snippet__overflow-indicator--left"></div>
          ` : ``}
      ${hasRightOverflow && type !== "multi" ? html`
            <div class="${"cds-custom"}--snippet__overflow-indicator--right"></div>
          ` : ``}
      ${hideCopyButton ? `` : html`
            <cds-custom-copy-button
              ?disabled=${disabled}
              button-class-name=${disabledCopyButtonClasses}
              feedback=${feedback}
              feedback-timeout=${feedbackTimeout}
              @click="${handleCopyClick}">
              ${tooltipContent}
            </cds-custom-copy-button>
          `}
      ${shouldShowMoreLessBtn ? html`
            <cds-custom-button
              kind="ghost"
              size="sm"
              button-class-name=${expandButtonClass}
              ?disabled=${disabled}
              @click=${() => this._handleClickExpanded()}>
              <span class="${"cds-custom"}--snippet-btn--text">
                ${expandCodeBtnText}
              </span>
              ${iconLoader(ChevronDown16, {
			class: `cds-custom--icon-chevron--down cds-custom--snippet__icon`,
			role: "img",
			slot: "icon"
		})}
            </cds-custom-button>
          ` : ``}
    `;
	}
	static {
		this.shadowRootOptions = {
			...LitElement.shadowRootOptions,
			delegatesFocus: true
		};
	}
	static {
		this.styles = code_snippet_default$1;
	}
};
__decorate([property({ attribute: "copy-text" })], CDSCodeSnippet.prototype, "copyText", void 0);
__decorate([property({
	type: Boolean,
	reflect: true
})], CDSCodeSnippet.prototype, "disabled", void 0);
__decorate([property()], CDSCodeSnippet.prototype, "feedback", void 0);
__decorate([property({
	type: Number,
	attribute: "feedback-timeout"
})], CDSCodeSnippet.prototype, "feedbackTimeout", void 0);
__decorate([property({
	type: Boolean,
	reflect: true,
	attribute: "hide-copy-button"
})], CDSCodeSnippet.prototype, "hideCopyButton", void 0);
__decorate([property()], CDSCodeSnippet.prototype, "maxCollapsedNumberOfRows", void 0);
__decorate([property()], CDSCodeSnippet.prototype, "maxExpandedNumberOfRows", void 0);
__decorate([property()], CDSCodeSnippet.prototype, "minCollapsedNumberOfRows", void 0);
__decorate([property()], CDSCodeSnippet.prototype, "minExpandedNumberOfRows", void 0);
__decorate([property({ attribute: "show-less-text" })], CDSCodeSnippet.prototype, "showLessText", void 0);
__decorate([property({ attribute: "show-more-text" })], CDSCodeSnippet.prototype, "showMoreText", void 0);
__decorate([property({ attribute: "tooltip-content" })], CDSCodeSnippet.prototype, "tooltipContent", void 0);
__decorate([property({
	type: Boolean,
	reflect: true,
	attribute: "wrap-text"
})], CDSCodeSnippet.prototype, "wrapText", void 0);
__decorate([property({ reflect: true })], CDSCodeSnippet.prototype, "type", void 0);
CDSCodeSnippet = __decorate([carbonElement(`cds-custom-code-snippet`)], CDSCodeSnippet);
var code_snippet_default = CDSCodeSnippet;
//#endregion
export { FORM_ELEMENT_COLOR_SCHEME as CODE_SNIPPET_COLOR_SCHEME, CODE_SNIPPET_TYPE, code_snippet_default as default };

//# sourceMappingURL=code-snippet.js.map