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;
};
import { LitElement, unsafeCSS } from 'lit';
import { property } from 'lit/decorators.js';
import { styles as hostStyles } from './host-styles';
export default class BaseElement extends LitElement {
    /**
     * Override the default styles property to fetch and convert string CSS files. Components can override this behavior
     * by setting their own `static styles = []` property.
     */
    static get styles() {
        const styles = Array.isArray(this.css) ? this.css : this.css ? [this.css] : [];
        return [hostStyles, ...styles].map((style) => (typeof style === 'string' ? unsafeCSS(style) : style));
    }
    #hasRecordedInitialProperties;
    constructor() {
        super();
        this.#hasRecordedInitialProperties = false;
        this.initialReflectedProperties = new Map();
        /**
         * Methods for setting and checking custom states.
         */
        this.customStates = {
            /** Adds or removes the specified custom state. */
            set: (customState, active) => {
                if (!this.internals?.states)
                    return;
                if (active) {
                    this.internals.states.add(customState);
                }
                else {
                    this.internals.states.delete(customState);
                }
            },
            /** Determines whether or not the element currently has the specified state. */
            has: (customState) => {
                if (!this.internals?.states)
                    return false;
                return this.internals.states.has(customState);
            },
        };
        try {
            this.internals = this.attachInternals();
        }
        catch {
            /* Need to tell people if they need a polyfill. */
            console.error('Element internals are not supported in your browser. Consider using a polyfill');
        }
        this.customStates.set('wa-defined', true);
        const Self = this.constructor;
        for (const [property, spec] of Self.elementProperties) {
            if (spec.default === 'inherit' && spec.initial !== undefined && typeof property === 'string') {
                this.customStates.set(`initial-${property}-${spec.initial}`, true);
            }
        }
    }
    attributeChangedCallback(name, oldValue, newValue) {
        if (!this.#hasRecordedInitialProperties) {
            this.constructor.elementProperties.forEach((obj, prop) => {
                if (obj.reflect && this[prop] != null) {
                    this.initialReflectedProperties.set(prop, this[prop]);
                }
            });
            this.#hasRecordedInitialProperties = true;
        }
        super.attributeChangedCallback(name, oldValue, newValue);
    }
    willUpdate(changedProperties) {
        super.willUpdate(changedProperties);
        // Run the morph fixing *after* willUpdate.
        this.initialReflectedProperties.forEach((value, prop) => {
            // If a prop changes to `null`, we assume this happens via an attribute changing to `null`.
            if (changedProperties.has(prop) && this[prop] == null) {
                // Silly type gymnastics to appease the compiler.
                this[prop] = value;
            }
        });
    }
    /**
     * Given a native event, this function cancels it and dispatches it again from the host element using the desired
     * event options.
     */
    relayNativeEvent(event, eventOptions) {
        event.stopImmediatePropagation();
        this.dispatchEvent(new event.constructor(event.type, {
            ...event,
            ...eventOptions,
        }));
    }
}
__decorate([
    property()
], BaseElement.prototype, "dir", void 0);
__decorate([
    property()
], BaseElement.prototype, "lang", void 0);
