import { Host, h } from "@stencil/core";
import { hasShadowDom } from "../../utils/utils";
import { caretDown, addCircle } from "@pine-ds/icons/icons";
/**
 * @part button - Exposes the button element for styling.
 * @part button-content - Exposes the button content for styling.
 * @part button-text - Exposes the button text for styling.
 * @part caret - Exposes the caret icon component for styling. Appears only on the disclosure variant.
 * @part icon - Exposes the icon component for styling.
 * @part loader-svg - Exposes the loader SVG element for color customization. Appears only when loading.
 * @slot (default) - Button text.
 * @slot start - Content to display before the button text.
 * @slot end - Content to display after the button text.
*/
export class PdsButton {
    constructor() {
        /**
         * Determines the button's disabled state.
         * @defaultValue false
         */
        this.disabled = false;
        /**
         * Determines if the button should take up the full width of its container.
         * @defaultValue false
         */
        this.fullWidth = false;
        /**
         * Displays a leading icon in the button. DEPRECATED.
         * @defaultValue null
         * @deprecated Use `start` slot instead.
         */
        this.icon = null;
        /**
         * When true, displays only the icon and visually hides the text (keeping it accessible).
         */
        this.iconOnly = false;
        /**
         * Determines if the button is in a loading state.
         * When true, displays a loader and hides the button text.
         * @defaultValue false
         */
        this.loading = false;
        /**
         * Provides button with a type.
         * @defaultValue button
         */
        this.type = 'button';
        /**
         * Sets the size of the button.
         * @defaultValue default
         */
        this.size = 'default';
        /**
         * Sets the style variant of the button.
         * @defaultValue primary
         */
        this.variant = 'primary';
        this.hasStartContent = false;
        this.hasEndContent = false;
        this.handleStartSlotChange = (event) => {
            this.hasStartContent = event.target.assignedElements({ flatten: true }).length > 0;
        };
        this.handleEndSlotChange = (event) => {
            this.hasEndContent = event.target.assignedElements({ flatten: true }).length > 0;
        };
        this.handleClick = (ev) => {
            if (this.loading) {
                ev.preventDefault();
                return;
            }
            // Prevent form submission for disabled buttons
            if (this.disabled) {
                ev.preventDefault();
                return;
            }
            if (!this.href && this.type != 'button') {
                // Handle form submission for Shadow DOM buttons
                if (hasShadowDom(this.el)) {
                    const form = this.el.closest('form');
                    if (form) {
                        ev.preventDefault();
                        const fakeButton = document.createElement('button');
                        fakeButton.type = this.type;
                        fakeButton.style.display = 'none';
                        form.appendChild(fakeButton);
                        fakeButton.click();
                        fakeButton.remove();
                    }
                }
            }
            this.pdsClick.emit(ev);
        };
    }
    /**
     * Listen for Enter key presses on form inputs to trigger submit
     */
    handleFormKeyDown(event) {
        // Skip if an earlier handler already canceled the event — matches the browser's
        // native implicit-submit behavior, which honors defaultPrevented.
        if (event.defaultPrevented) {
            return;
        }
        // Only handle Enter key for submit buttons that are not disabled
        if (event.key !== 'Enter' || this.type !== 'submit' || this.href || this.disabled) {
            return;
        }
        const target = event.target;
        // Ensure event.target is an Element with matches method before proceeding
        if (!target || typeof target.matches !== 'function') {
            return;
        }
        const form = this.el.closest('form');
        // Check if the Enter key was pressed in a form input within the same form
        if (!form || !target || !form.contains(target)) {
            return;
        }
        // Check if target is a form input element (exclude reset buttons)
        const isFormInput = target.matches('input:not([type="submit"]):not([type="button"]):not([type="reset"])') ||
            target.matches('pds-input') ||
            target.matches('pds-select') ||
            target.matches('pds-switch') ||
            target.matches('pds-checkbox') ||
            target.matches('pds-radio');
        if (isFormInput) {
            // Find all submit buttons in the form and check their actual properties
            const allSubmitButtons = Array.from(form.querySelectorAll('pds-button, button[type="submit"], input[type="submit"]'));
            const enabledSubmitButtons = allSubmitButtons.filter(button => {
                if (button.tagName.toLowerCase() === 'pds-button') {
                    const pdsButton = button;
                    return pdsButton.type === 'submit' && !pdsButton.disabled;
                }
                else {
                    return !button.hasAttribute('disabled');
                }
            });
            // Only synthesize click if this button is strictly the first enabled submit button
            if (enabledSubmitButtons.length > 0 && enabledSubmitButtons[0] === this.el) {
                event.preventDefault();
                this.el.click();
            }
        }
    }
    classNames() {
        const classNames = ['pds-button'];
        if (this.variant) {
            classNames.push('pds-button--' + this.variant);
        }
        if (this.size && this.size !== 'default') {
            classNames.push('pds-button--' + this.size);
        }
        if (this.iconOnly) {
            classNames.push('pds-button--icon-only');
        }
        if (this.loading) {
            classNames.push('pds-button--loading');
        }
        return classNames.join(' ');
    }
    renderStartContent() {
        if (this.variant === 'filter') {
            return (h("pds-icon", { class: this.loading ? 'pds-button__icon--hidden' : '', icon: addCircle, part: "icon", "aria-hidden": "true" }));
        }
        // Deprecated icon prop still takes precedence over start slot
        const hasIcon = this.icon && this.variant !== 'disclosure';
        if (Boolean(hasIcon)) {
            return (h("pds-icon", { class: this.loading ? 'pds-button__icon--hidden' : '', name: this.icon, part: "icon", "aria-hidden": "true" }));
        }
        // Always render the start slot so slotted content is projected reliably.
        // The --empty class hides the wrapper when no content is slotted (prevents empty gap space).
        const startClasses = `pds-button__icon${this.hasStartContent ? '' : ' pds-button__icon--empty'}${this.loading ? ' pds-button__icon--hidden' : ''}`;
        return h("span", { class: startClasses }, h("slot", { name: "start", onSlotchange: this.handleStartSlotChange }));
    }
    renderEndContent() {
        if (this.iconOnly) {
            return null;
        }
        if (this.variant === 'disclosure') {
            return (h("pds-icon", { class: this.loading ? 'pds-button__icon--hidden' : '', icon: caretDown, part: "caret", "aria-hidden": "true" }));
        }
        // Always render the end slot so slotted content is projected reliably.
        // The --empty class hides the wrapper when no content is slotted (prevents empty gap space).
        const endClasses = `pds-button__icon${this.hasEndContent ? '' : ' pds-button__icon--empty'}${this.loading ? ' pds-button__icon--hidden' : ''}`;
        return h("span", { class: endClasses }, h("slot", { name: "end", onSlotchange: this.handleEndSlotChange }));
    }
    render() {
        // Common props for both button and anchor elements
        const commonProps = {
            class: this.classNames(),
            part: 'button',
        };
        const attributes = () => {
            if (this.href) {
                return Object.assign(Object.assign({}, commonProps), { download: this.download, href: this.disabled ? null : this.href, target: this.target });
            }
            return Object.assign(Object.assign({}, commonProps), { 'aria-busy': this.loading ? 'true' : null, 'aria-live': this.loading ? 'polite' : null, 'disabled': this.disabled, 'name': this.name, 'type': this.type, 'value': this.value });
        };
        const ContentElement = this.href ? 'a' : 'button';
        // Hide text when loading or iconOnly is true
        const hideText = this.loading || this.iconOnly;
        const content = (h("div", { class: "pds-button__content", part: "button-content" }, this.renderStartContent(), h("span", { class: `pds-button__text ${hideText ? 'pds-button__text--hidden' : ''}`, part: "button-text" }, h("slot", null)), this.loading && (h("span", { class: "pds-button__loader" }, h("pds-loader", { "is-loading": true, size: "var(--pine-font-size-body-2xl)", variant: "spinner", exportparts: "loader-svg" }, "Loading..."))), this.renderEndContent()));
        return (h(Host, { "aria-disabled": this.disabled ? 'true' : null, id: this.componentId, onClick: this.handleClick, variant: this.variant }, h(ContentElement, Object.assign({}, attributes()), content)));
    }
    static get is() { return "pds-button"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["pds-button.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["pds-button.css"]
        };
    }
    static get properties() {
        return {
            "componentId": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "A unique identifier used for the underlying component `id` attribute."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "component-id"
            },
            "download": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Prompts the user to save the linked URL instead of navigating to it.\nIt can be used without a value to download with the default filename,\nor with a string value to suggest a specific filename for the download.\nOnly applies when href is set."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "download"
            },
            "disabled": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "defaultValue",
                            "text": "false"
                        }],
                    "text": "Determines the button's disabled state."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "disabled",
                "defaultValue": "false"
            },
            "fullWidth": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "defaultValue",
                            "text": "false"
                        }],
                    "text": "Determines if the button should take up the full width of its container."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "full-width",
                "defaultValue": "false"
            },
            "href": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If provided, renders the component as an anchor (`<a>`) element instead of a button.\nWhen using href, button-specific props (type, name, value, loading) will be ignored."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "href"
            },
            "icon": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "defaultValue",
                            "text": "null"
                        }, {
                            "name": "deprecated",
                            "text": "Use `start` slot instead."
                        }],
                    "text": "Displays a leading icon in the button. DEPRECATED."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "icon",
                "defaultValue": "null"
            },
            "iconOnly": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "When true, displays only the icon and visually hides the text (keeping it accessible)."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "icon-only",
                "defaultValue": "false"
            },
            "loading": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "defaultValue",
                            "text": "false"
                        }],
                    "text": "Determines if the button is in a loading state.\nWhen true, displays a loader and hides the button text."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "loading",
                "defaultValue": "false"
            },
            "name": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Provides the button with a submittable name."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "name"
            },
            "target": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'_blank' | '_self' | '_parent' | '_top'",
                    "resolved": "\"_blank\" | \"_parent\" | \"_self\" | \"_top\"",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Specifies where to open the linked document when href is provided.\nOnly applies when href is set."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "target"
            },
            "type": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'button' | 'reset' | 'submit'",
                    "resolved": "\"button\" | \"reset\" | \"submit\"",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "defaultValue",
                            "text": "button"
                        }],
                    "text": "Provides button with a type."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "type",
                "defaultValue": "'button'"
            },
            "value": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Provides button with a submittable value"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "value"
            },
            "size": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'default' | 'small' | 'micro'",
                    "resolved": "\"default\" | \"micro\" | \"small\"",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "defaultValue",
                            "text": "default"
                        }],
                    "text": "Sets the size of the button."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "size",
                "defaultValue": "'default'"
            },
            "variant": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'primary' | 'secondary' | 'tertiary' | 'accent' | 'disclosure' | 'destructive' | 'unstyled' | 'filter'",
                    "resolved": "\"accent\" | \"destructive\" | \"disclosure\" | \"filter\" | \"primary\" | \"secondary\" | \"tertiary\" | \"unstyled\"",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "defaultValue",
                            "text": "primary"
                        }],
                    "text": "Sets the style variant of the button."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "variant",
                "defaultValue": "'primary'"
            }
        };
    }
    static get states() {
        return {
            "hasStartContent": {},
            "hasEndContent": {}
        };
    }
    static get events() {
        return [{
                "method": "pdsClick",
                "name": "pdsClick",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "complexType": {
                    "original": "Event",
                    "resolved": "Event",
                    "references": {
                        "Event": {
                            "location": "import",
                            "path": "@stencil/core",
                            "id": "../../node_modules/@stencil/core/internal/stencil-core/index.d.ts::Event"
                        }
                    }
                }
            }];
    }
    static get elementRef() { return "el"; }
    static get listeners() {
        return [{
                "name": "keydown",
                "method": "handleFormKeyDown",
                "target": "body",
                "capture": false,
                "passive": false
            }];
    }
}
//# sourceMappingURL=pds-button.js.map
