var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
/* eslint-disable max-classes-per-file */
import { property, state } from 'lit/decorators.js';
import { BUTTON_COLORS, BUTTON_TYPE_INTERNAL, BUTTON_VARIANTS, DEFAULTS, ICON_BUTTON_SIZES, PILL_BUTTON_SIZES, TERTIARY_BUTTON_COLORS, } from '../../components/button/button.constants';
export const ButtonComponentMixin = (superClass) => {
    class InnerMixinClass extends superClass {
        constructor() {
            super(...arguments);
            /**
             * The visual style variant of the button.
             * - `primary`: Solid background color
             * - `secondary`: Transparent background with solid border
             * - `tertiary`: No background or border, text-only appearance
             * @default primary
             */
            this.variant = DEFAULTS.VARIANT;
            /**
             * The semantic color of the button.
             * - `positive`: For success or confirmation actions
             * - `negative`: For destructive or error actions
             * - `accent`: For informational actions
             * - `promotional`: For promotional actions
             * - `default`: For standard actions
             *
             * Note: Tertiary buttons only support default, accent, and negative colors.
             * @default default
             */
            this.color = DEFAULTS.COLOR;
            /** @internal */
            this.typeInternal = DEFAULTS.TYPE_INTERNAL;
        }
        /**
         * Sets the variant attribute for the button component.
         * If the provided variant is not included in the BUTTON_VARIANTS,
         * it defaults to the value specified in DEFAULTS.VARIANT.
         *
         * @param variant - The variant to set.
         */
        setVariant(variant) {
            this.setAttribute('variant', Object.values(BUTTON_VARIANTS).includes(variant) ? variant : DEFAULTS.VARIANT);
        }
        /**
         * Sets the color attribute for the button.
         * Defaults to DEFAULTS.COLOR if invalid or if the color is not supported for the current variant.
         * Tertiary buttons only support default, accent, and negative colors.
         *
         * @param color - The color to set.
         */
        setColor(color) {
            const isValidColor = Object.values(BUTTON_COLORS).includes(color);
            const isTertiaryUnsupported = this.variant === BUTTON_VARIANTS.TERTIARY && !Object.values(TERTIARY_BUTTON_COLORS).includes(color);
            if (!isValidColor || isTertiaryUnsupported) {
                this.setAttribute('color', `${DEFAULTS.COLOR}`);
            }
            else {
                this.setAttribute('color', color);
            }
        }
        /**
         * Sets the size attribute for the button component.
         * Validates the size based on the button type (icon, pill, or tertiary).
         * Defaults to DEFAULTS.SIZE if invalid.
         *
         * @param size - The size to set.
         */
        setSize(size) {
            const isIconType = this.typeInternal === BUTTON_TYPE_INTERNAL.ICON;
            const isValidSize = isIconType
                ? Object.values(ICON_BUTTON_SIZES).includes(size) &&
                    !(size === ICON_BUTTON_SIZES[20] && this.variant !== BUTTON_VARIANTS.TERTIARY)
                : Object.values(PILL_BUTTON_SIZES).includes(size);
            this.setAttribute('size', isValidSize ? `${size}` : `${DEFAULTS.SIZE}`);
        }
        /**
         * Infers the type of button based on the presence of slot and/or prefix and postfix icons.
         * @param slot - default slot of button
         */
        inferButtonType() {
            var _a, _b, _c, _d, _e, _f;
            // Check for text content in the default slot
            const defaultSlot = (_b = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('slot:not([name])')) === null || _b === void 0 ? void 0 : _b.assignedNodes().filter(node => { var _a; return node.nodeType !== Node.TEXT_NODE || ((_a = node.textContent) === null || _a === void 0 ? void 0 : _a.trim()); }).length;
            // Check for prefix content (either icon property or slot content)
            const prefixSlot = (_d = (_c = this.shadowRoot) === null || _c === void 0 ? void 0 : _c.querySelector('slot[name="prefix"]')) === null || _d === void 0 ? void 0 : _d.assignedNodes().filter(node => { var _a; return node.nodeType !== Node.TEXT_NODE || ((_a = node.textContent) === null || _a === void 0 ? void 0 : _a.trim()); }).length;
            const hasPrefix = this.prefixIcon || (prefixSlot && prefixSlot > 0);
            // Check for postfix content (either icon property or slot content)
            const postfixSlot = (_f = (_e = this.shadowRoot) === null || _e === void 0 ? void 0 : _e.querySelector('slot[name="postfix"]')) === null || _f === void 0 ? void 0 : _f.assignedNodes().filter(node => { var _a; return node.nodeType !== Node.TEXT_NODE || ((_a = node.textContent) === null || _a === void 0 ? void 0 : _a.trim()); }).length;
            const hasPostfix = this.postfixIcon || (postfixSlot && postfixSlot > 0);
            if (defaultSlot && (hasPrefix || hasPostfix)) {
                this.typeInternal = BUTTON_TYPE_INTERNAL.PILL_WITH_ICON;
                this.setAttribute('data-btn-type', 'pill-with-icon');
            }
            else if (!defaultSlot && (hasPrefix || hasPostfix)) {
                this.typeInternal = BUTTON_TYPE_INTERNAL.ICON;
                this.setAttribute('data-btn-type', 'icon');
            }
            else {
                this.typeInternal = BUTTON_TYPE_INTERNAL.PILL;
                this.setAttribute('data-btn-type', 'pill');
            }
        }
    }
    __decorate([
        property({ type: String, attribute: 'prefix-icon', reflect: true }),
        __metadata("design:type", String)
    ], InnerMixinClass.prototype, "prefixIcon", void 0);
    __decorate([
        property({ type: String, attribute: 'postfix-icon', reflect: true }),
        __metadata("design:type", String)
    ], InnerMixinClass.prototype, "postfixIcon", void 0);
    __decorate([
        property({ type: String }),
        __metadata("design:type", String)
    ], InnerMixinClass.prototype, "variant", void 0);
    __decorate([
        property({ type: String }),
        __metadata("design:type", String)
    ], InnerMixinClass.prototype, "color", void 0);
    __decorate([
        state(),
        __metadata("design:type", String)
    ], InnerMixinClass.prototype, "typeInternal", void 0);
    // Cast return type to your mixin's interface intersected with the superClass type
    return InnerMixinClass;
};
