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, html } from 'lit';
import { property, state } from 'lit/decorators.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { EventEmitterMixin } from '../../util/EventEmitterMixin.js';
import onFind from '../../util/onFind.js';
import { ReadyMixin } from '../../util/ReadyMixin.js';
import { TooltipController } from '../../util/TooltipController.js';
import '../icon/Icon.js';
import './Widget.css';
/**
 * A widget component for displaying content with header, body, and footer sections.
 *
 * ## Architecture: Light DOM + Manager Pattern
 *
 * This component uses **Light DOM** (no Shadow Root) with the **Manager Pattern**:
 * - User-provided children are physically moved into internal containers
 * - Movement is based on `slot` attributes (pseudo-slots)
 * - The `onFind` utility automatically redistributes dynamically-added content
 *
 * ### Node Redistribution Rules
 * - `slot="controls"` → Moved to header actions area (before system buttons)
 * - `slot="footer"` → Moved to footer container
 * - *(no slot)* → Moved to body container (default)
 *
 * ## Features
 *
 * - **Collapsible**: Optional chevron toggle to hide/show body and footer
 * - **Fullscreen**: Optional maximize button for fullscreen mode via `:state(fullscreen)` custom state
 * - **Dynamic Content**: `onFind` handles content added after initialization
 * - **Accessible**: Full ARIA support and keyboard navigation
 * - **Themeable**: CSS custom properties for colors and spacing
 *
 * ## Accessibility
 *
 * - **Collapse toggle**: `aria-expanded`, `aria-controls`, `aria-label`
 * - **Fullscreen toggle**: `aria-pressed`, `aria-label`
 * - **Body region**: `role="region"`, `aria-labelledby` linking to heading
 * - **Tab order**: Natural flow via physical DOM placement
 * - **Collapsed content**: Hidden via `inert` attribute and CSS grid collapse
 *
 * @element btu-widget
 *
 * @fires {CustomEvent} btu-widget-ready - Fired after first render and redistribution
 * @fires {CustomEvent<{collapsed: boolean}>} btu-widget-collapse-changed - Fired when collapsed state changes
 * @fires {CustomEvent<{fullscreen: boolean}>} btu-widget-fullscreen-changed - Fired when fullscreen state changes
 *
 * @cssprop --widget-background - Body and footer background color (default: --btu-theme-white)
 * @cssprop --widget-border - Widget border and dividers (default: 1px solid gray-200)
 * @cssprop --widget-border-color - Color of header bottom divider (default: gray-200)
 * @cssprop --header-background - Header background color (default: transparent)
 *
 * @cssstate collapsed - Applied when the widget is collapsed, targetable via :state(collapsed)
 * @cssstate fullscreen - Applied when the widget is in fullscreen mode, targetable via :state(fullscreen)
 *
 * @slot - Default pseudo-slot: elements without slot attribute are moved to body
 * @slot controls - Pseudo-slot: buttons/actions moved to header actions area
 * @slot footer - Pseudo-slot: content moved to footer container
 *
 * @example
 * ```html
 * <!-- Basic usage with heading property -->
 * <btu-widget heading="My Widget">
 *   <button slot="controls">Action</button>
 *   <div>Main body content</div>
 * </btu-widget>
 * ```
 */
export default class Widget extends EventEmitterMixin(ReadyMixin(LitElement)) {
    constructor() {
        super(...arguments);
        this._internals = this.attachInternals();
        /**
         * Heading text displayed in the header.
         * @attr
         */
        this.heading = '';
        /**
         * Whether the widget can be collapsed/expanded.
         * When true, a chevron toggle button appears in the header.
         * @attr
         */
        this.collapsible = false;
        /**
         * Whether the widget is currently collapsed.
         * When true, body and footer are hidden. Implies collapsible.
         * @attr
         */
        this.collapsed = false;
        /**
         * Whether the widget can enter fullscreen mode.
         * When true, a fullscreen toggle button appears in the header.
         * @attr
         */
        this.fullscreenable = false;
        this._isFullscreen = false;
        this._collapseTooltip = new TooltipController(this, {
            target: 'button[data-tooltip="collapse"]',
            text: () => (this.collapsed ? 'Expand' : 'Collapse'),
            position: 'bottom',
            noArrow: true,
            offset: 'sm',
        });
        this._fullscreenTooltip = new TooltipController(this, {
            target: 'button[data-tooltip="fullscreen"]',
            text: () => (this._isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'),
            position: 'bottom',
            noArrow: true,
            offset: 'sm',
        });
        /** @internal */
        this._instanceId = Widget._idCounter++;
        /** @internal */
        this.bodyId = `widget-body-${this._instanceId}`;
        /** @internal */
        this.dialogId = `widget-dialog-${this._instanceId}`;
    }
    static { this._idCounter = 0; }
    createRenderRoot() {
        return this;
    }
    /**
     * Whether the widget is currently in fullscreen mode (read-only).
     * Use `btu-widget-fullscreen-changed` event to react to changes.
     */
    get isFullscreen() {
        return this._isFullscreen;
    }
    willUpdate(changed) {
        super.willUpdate(changed);
        if (changed.has('collapsed')) {
            if (this.collapsed) {
                this._internals.states.add('collapsed');
            }
            else {
                this._internals.states.delete('collapsed');
            }
        }
    }
    connectedCallback() {
        super.connectedCallback();
        this.classList.add('blokk');
        this._restoreState();
        // Light-dismiss: close dialog on backdrop click
        this._lightDismissHandler = (e) => {
            const dialog = e.target;
            if (dialog instanceof HTMLDialogElement && dialog.id === this.dialogId) {
                dialog.close();
            }
        };
        document.addEventListener('click', this._lightDismissHandler);
        // Set up dialog after render (works on both first connect and reconnect)
        this.updateComplete.then(() => this._setupDialog());
    }
    disconnectedCallback() {
        super.disconnectedCallback();
        // Clean up light-dismiss listener
        if (this._lightDismissHandler) {
            document.removeEventListener('click', this._lightDismissHandler);
            this._lightDismissHandler = undefined;
        }
        // Clean up dialog close listener
        if (this._dialog && this._dialogCloseHandler) {
            this._dialog.removeEventListener('close', this._dialogCloseHandler);
            this._dialogCloseHandler = undefined;
        }
    }
    firstUpdated() {
        const actionsContainer = this.querySelector('.btu-widget__actions');
        const bodyContainer = this.querySelector('.btu-widget__body');
        const footerContainer = this.querySelector('.btu-widget__footer');
        if (actionsContainer && bodyContainer && footerContainer) {
            // Anchor node: first system button in actions container (collapse/fullscreen buttons)
            const systemAnchor = actionsContainer.querySelector('[data-widget-internal]');
            onFind(this, ':scope > :not([data-widget-internal]):not([data-tooltip-internal])', el => {
                const slot = el.getAttribute('slot');
                if (slot === 'controls') {
                    actionsContainer.insertBefore(el, systemAnchor);
                }
                else if (slot === 'footer') {
                    footerContainer.appendChild(el);
                }
                else {
                    bodyContainer.appendChild(el);
                }
            });
        }
        this.emit('btu-widget-ready');
    }
    /**
     * Toggles the collapsed state of the widget.
     * Emits 'btu-widget-collapse-changed' event with collapsed state.
     * @internal
     */
    handleToggle() {
        this.collapsed = !this.collapsed;
        if (!this.collapsible)
            this.collapsible = true;
        this.emit('btu-widget-collapse-changed', { collapsed: this.collapsed });
        this._persistState();
    }
    /**
     * Toggles the fullscreen state of the widget using native dialog element.
     * Moves the content wrapper into the dialog on fullscreen, back out on exit.
     * Uses dialog.showModal() for proper modal behavior with backdrop.
     * Uses View Transition API for smooth fullscreen animation.
     * Emits 'btu-widget-fullscreen-changed' event with fullscreen state.
     * @internal
     */
    handleFullscreen() {
        if (!this._dialog) {
            console.warn('Widget: Dialog element not found');
            return;
        }
        const content = this.querySelector('.btu-widget__content');
        if (!content)
            return;
        const body = content.querySelector('.btu-widget__body');
        const updateFullscreen = () => {
            this._isFullscreen = !this._isFullscreen;
            if (this._isFullscreen) {
                this._internals.states.add('fullscreen');
                if (body) {
                    body.classList.add('max-h-[calc(100vh-3rem-4rem)]', 'overflow-auto');
                }
                this._dialog.appendChild(content);
                this._dialog.showModal();
            }
            else {
                this._internals.states.delete('fullscreen');
                if (body) {
                    body.classList.remove('max-h-[calc(100vh-3rem-4rem)]', 'overflow-auto');
                }
                this._dialog.close();
                this.insertBefore(content, this._dialog);
            }
            this.emit('btu-widget-fullscreen-changed', { fullscreen: this._isFullscreen });
        };
        // Use View Transition API if supported
        if (document.startViewTransition) {
            this._dialog.style.viewTransitionName = 'widget';
            document
                .startViewTransition(() => {
                updateFullscreen();
            })
                .finished.finally(() => {
                if (this._dialog) {
                    this._dialog.style.viewTransitionName = '';
                }
            });
        }
        else {
            updateFullscreen();
        }
    }
    /**
     * Sets up the dialog element and event listeners.
     * @internal
     */
    _setupDialog() {
        // Clean up existing handler (reconnection scenario)
        if (this._dialog && this._dialogCloseHandler) {
            this._dialog.removeEventListener('close', this._dialogCloseHandler);
        }
        this._dialog = this.querySelector(`#${this.dialogId}`);
        if (!this._dialog) {
            console.warn('Widget: Dialog element not found');
            return;
        }
        // Handle ESC key and light dismiss — move content back out of dialog
        this._dialogCloseHandler = () => {
            if (this._isFullscreen) {
                const content = this._dialog.querySelector('.btu-widget__content');
                if (content) {
                    const body = content.querySelector('.btu-widget__body');
                    if (body) {
                        body.classList.remove('max-h-[calc(100vh-3rem-4rem)]', 'overflow-auto');
                    }
                    this.insertBefore(content, this._dialog);
                }
                this._isFullscreen = false;
                this._internals.states.delete('fullscreen');
                this.emit('btu-widget-fullscreen-changed', { fullscreen: false });
            }
        };
        this._dialog.addEventListener('close', this._dialogCloseHandler);
    }
    /**
     * Restores widget state from LocalStorage if id is set.
     * Only restores if no explicit collapsed attribute is present on the element.
     *
     * Attribute Precedence:
     * - If collapsed attribute is explicitly present in HTML: Use that value (ignore LocalStorage)
     * - If collapsed attribute is absent: Restore from LocalStorage
     *
     * @internal
     */
    _restoreState() {
        if (!this.id) {
            return;
        }
        // If collapsed attribute is explicitly set in HTML, respect that over LocalStorage
        if (this.hasAttribute('collapsed')) {
            return;
        }
        const storageKey = `btu-widget-state-${this.id}`;
        try {
            const storedState = localStorage.getItem(storageKey);
            if (storedState) {
                const state = JSON.parse(storedState);
                if (typeof state.collapsed === 'boolean') {
                    this.collapsed = state.collapsed;
                }
            }
        }
        catch (e) {
            console.warn(`Widget: Failed to parse stored state for ${storageKey}`, e);
        }
    }
    /**
     * Persists widget state to LocalStorage if id is set.
     *
     * @internal
     */
    _persistState() {
        if (!this.id) {
            return;
        }
        const storageKey = `btu-widget-state-${this.id}`;
        const state = { collapsed: this.collapsed };
        try {
            localStorage.setItem(storageKey, JSON.stringify(state));
        }
        catch (e) {
            console.warn(`Widget: Failed to persist state for ${this.id}`, e);
        }
    }
    render() {
        const contentClasses = 'btu-widget__content overflow-hidden rounded-[inherit] [border:var(--widget-border,1px_solid_oklch(var(--btu-theme-gray-200)))]';
        const headerClasses = 'btu-widget__header flex items-center justify-between gap-2 px-4 py-2 [background-color:var(--header-background,oklch(var(--btu-theme-gray-50)))] [border-bottom-width:1px] [border-bottom-style:solid] [border-bottom-color:var(--widget-border-color,oklch(var(--btu-theme-gray-200)))] transition-[border-color] duration-200';
        const headingClasses = 'btu-widget__heading btu-heading-5 capitalize text-gray-900 flex-1';
        const actionsClasses = 'btu-widget__actions flex items-center gap-2';
        const buttonBaseClasses = 'btu-button btu-button-text-hidden btu-button-fill-none btu-button-gray btu-button-sm';
        const collapseClasses = buttonBaseClasses;
        const fullscreenClasses = buttonBaseClasses;
        const bodyClasses = 'btu-widget__body p-4 [background:var(--widget-background,var(--btu-theme-white))]';
        const footerClasses = 'btu-widget__footer p-4 [border-top:var(--widget-border,1px_solid_oklch(var(--btu-theme-gray-200)))] empty:hidden [background:var(--widget-background,var(--btu-theme-white))]';
        const dialogClasses = 'btu-widget__dialog border-0 rounded-xl p-0 m-6 overflow-hidden w-[calc(100vw-3rem)] max-w-[calc(100vw-3rem)] max-h-[calc(100vh-3rem)] [background:var(--widget-background,var(--btu-theme-white))]';
        return html `
      <div class="${contentClasses}" data-widget-internal>
        <div class="${headerClasses}" data-widget-internal>
          ${this.heading
            ? html `<span id="widget-heading-${this.bodyId}" class="${headingClasses}">${this.heading}</span>`
            : ''}
          <div class="${actionsClasses}" data-widget-internal>
            ${this.collapsible || this.collapsed
            ? html `
                  <button
                    class="${collapseClasses}"
                    data-widget-internal
                    data-tooltip="collapse"
                    @click="${this.handleToggle}"
                    aria-label="${this.collapsed ? 'Expand widget' : 'Collapse widget'}"
                    aria-expanded="${!this.collapsed}"
                    aria-controls="${this.bodyId}"
                  >
                    <btu-icon class="btu-widget__collapse-chevron" symbol="chevron-up" size="sm"></btu-icon>
                  </button>
                `
            : ''}
            ${this.fullscreenable
            ? html `
                  <button
                    class="${fullscreenClasses}"
                    data-widget-internal
                    data-tooltip="fullscreen"
                    @click="${this.handleFullscreen}"
                    aria-label="${this._isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}"
                    aria-pressed="${this._isFullscreen}"
                  >
                    <btu-icon symbol="${this._isFullscreen ? 'minimize-2' : 'maximize-2'}" size="sm"></btu-icon>
                  </button>
                `
            : ''}
          </div>
        </div>
        <div class="btu-widget__collapsible" ?inert="${this.collapsed}" data-widget-internal>
          <div class="btu-widget__collapsible-inner" data-widget-internal>
            <div
              id="${this.bodyId}"
              class="${bodyClasses}"
              role="region"
              aria-labelledby="${ifDefined(this.heading ? `widget-heading-${this.bodyId}` : undefined)}"
              data-widget-internal
            ></div>
            <div class="${footerClasses}" data-widget-internal></div>
          </div>
        </div>
      </div>
      <dialog id="${this.dialogId}" class="${dialogClasses}" data-widget-internal></dialog>
    `;
    }
}
__decorate([
    property({ type: String })
], Widget.prototype, "heading", void 0);
__decorate([
    property({ type: Boolean })
], Widget.prototype, "collapsible", void 0);
__decorate([
    property({ type: Boolean })
], Widget.prototype, "collapsed", void 0);
__decorate([
    property({ type: Boolean })
], Widget.prototype, "fullscreenable", void 0);
__decorate([
    state()
], Widget.prototype, "_isFullscreen", void 0);
// Register custom element with guard to prevent double registration
// (common with yarn link, HMR, or webpack bundle duplication)
if (!customElements.get('btu-widget')) {
    customElements.define('btu-widget', Widget);
}
//# sourceMappingURL=Widget.js.map