import { buildSearchStatus } from "@coveo/headless";
import { createPopperLite, preventOverflow } from "@popperjs/core";
import { LitElement, html } from "lit";
import { customElement, state } from "lit/decorators.js";
import { createRef, ref } from "lit/directives/ref.js";
import { when } from "lit/directives/when.js";
import { renderButton } from "../../common/button.js";
import { popoverClass } from "../../common/facets/popover/popover-type.js";
import { bindStateToController } from "../../../decorators/bind-state.js";
import { bindingGuard } from "../../../decorators/binding-guard.js";
import { bindings } from "../../../decorators/bindings.js";
import { errorGuard } from "../../../decorators/error-guard.js";
import { withTailwindStyles } from "../../../decorators/with-tailwind-styles.js";
import { multiClassMap, tw } from "../../../directives/multi-class-map.js";
import arrow_bottom_rounded from "../../../images/arrow-bottom-rounded.js";
import facet_common_tw_css from "../../common/facets/facet-common.tw.css.js";
import "../../common/atomic-focus-trap/atomic-focus-trap.js";
import "../../common/atomic-icon/atomic-icon.js";
function _ts_decorate(decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) 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;
}
function _ts_metadata(k, v) {
    if ("object" == typeof Reflect && "function" == typeof Reflect.metadata) return Reflect.metadata(k, v);
}
class AtomicPopover extends LitElement {
    initialize() {
        this.searchStatus = buildSearchStatus(this.bindings.engine);
        if (0 === this.children.length) {
            this.error = new Error('One child is required inside a set of popover tags.');
            return;
        }
        if (this.children.length > 1) this.error = new Error('Cannot have more than one child inside a set of popover tags.');
    }
    connectedCallback() {
        super.connectedCallback();
        this.addEventListener('atomic/initializePopover', this.handleInitializePopover);
        this.addEventListener('keydown', this.handleKeyDown);
    }
    disconnectedCallback() {
        super.disconnectedCallback();
        this.removeEventListener('atomic/initializePopover', this.handleInitializePopover);
        this.removeEventListener('keydown', this.handleKeyDown);
    }
    render() {
        if (!this.searchStatus || this.searchStatusState?.hasError) return html``;
        if (!this.searchStatusState?.firstSearchExecuted) return html`
        <div
          part="placeholder"
          aria-hidden="true"
          class="bg-neutral h-8 w-32 animate-pulse rounded"
        ></div>
      `;
        if (!this.searchStatusState?.hasResults || !this.childFacet?.hasValues()) return html``;
        return html`
      <atomic-focus-trap
        .source=${this.buttonRef.value}
        .container=${this.popupRef.value}
        .active=${this.isOpen}
        .shouldHideSelf=${false}
      >
        ${this.renderPopover()}
      </atomic-focus-trap>
      ${when(this.isOpen, ()=>this.renderBackdrop())}
    `;
    }
    updated() {
        if (!this.buttonRef.value || !this.popupRef.value) return;
        if (this.popperInstance) this.popperInstance.forceUpdate();
        else this.popperInstance = createPopperLite(this.buttonRef.value, this.popupRef.value, {
            placement: 'bottom-start',
            modifiers: [
                preventOverflow
            ]
        });
    }
    renderDropdownButton() {
        const label = this.label;
        const hasActiveValues = !!this.childFacet.numberOfActiveValues();
        const count = this.childFacet.numberOfActiveValues().toLocaleString(this.bindings.i18n.language);
        const ariaLabel = this.bindings.i18n.t('popover', {
            label
        });
        const buttonClasses = tw({
            'hover:border-primary-light focus-visible:border-primary-light group box-border flex h-full max-w-60 min-w-24 items-center rounded p-2.5 hover:border focus-visible:border overflow-hidden relative': true,
            'border-primary ring-ring-primary text-primary z-9999 ring-3': this.isOpen
        });
        const labelClasses = tw({
            'mr-1.5 truncate': true,
            'group-hover:text-primary-light group-focus:text-primary': !this.isOpen
        });
        const countClasses = tw({
            'group-hover:text-primary-light group-focus:text-primary mr-1.5 truncate text-sm': true,
            hidden: !hasActiveValues,
            'text-primary': this.isOpen,
            'text-neutral-dark': !this.isOpen
        });
        const iconClasses = tw({
            'group-hover:text-primary-light group-focus:text-primary ml-auto w-2': true,
            'rotate-180': this.isOpen
        });
        const buttonClassString = Object.entries(buttonClasses).filter(([, value])=>value).map(([key])=>key).join(' ');
        return renderButton({
            props: {
                ref: this.buttonRef,
                style: 'square-neutral',
                onClick: ()=>this.toggleOpen(),
                part: 'popover-button',
                ariaExpanded: this.isOpen ? 'true' : 'false',
                ariaLabel,
                ariaControls: this.popoverId,
                class: buttonClassString
            }
        })(html`
      <span
        title=${label}
        part="value-label"
        class=${multiClassMap(labelClasses)}
      >
        ${label}
      </span>
      <span part="value-count" class=${multiClassMap(countClasses)}>
        ${this.bindings.i18n.t('between-parentheses', {
            text: count
        })}
      </span>
      <atomic-icon
        part="arrow-icon"
        class=${multiClassMap(iconClasses)}
        .icon=${arrow_bottom_rounded}
      ></atomic-icon>
    `);
    }
    renderBackdrop() {
        return html`
      <div
        part="backdrop"
        class="fixed top-0 right-0 bottom-0 left-0 z-9998 cursor-pointer bg-transparent"
        @click=${()=>this.closePopover()}
      ></div>
    `;
    }
    renderPopover() {
        return html`
      <div class=${`relative ${this.isOpen ? 'z-9999' : ''}`}>
        ${this.renderDropdownButton()}
        <div
          id=${this.popoverId}
          ${ref(this.popupRef)}
          part="facet"
          class=${`absolute pt-0.5 ${this.isOpen ? 'block' : 'hidden'}`}
        >
          <slot></slot>
        </div>
      </div>
    `;
    }
    get popoverId() {
        return `${this.childFacet?.facetId}-popover`;
    }
    get label() {
        return this.childFacet.label();
    }
    closePopover() {
        this.isOpen = false;
    }
    toggleOpen() {
        this.isOpen = !this.isOpen;
    }
    constructor(...args){
        super(...args), this.buttonRef = createRef(), this.popupRef = createRef(), this.isOpen = false, this.handleInitializePopover = (event)=>{
            if (this.childFacet || !event.detail) return;
            this.childFacet = event.detail;
            this.childFacet.element.classList.add(popoverClass);
        }, this.handleKeyDown = (e)=>{
            if ('Escape' === e.key && this.isOpen) this.closePopover();
        };
    }
}
AtomicPopover.styles = [
    facet_common_tw_css
];
_ts_decorate([
    state(),
    _ts_metadata("design:type", "u" < typeof Bindings ? Object : Bindings)
], AtomicPopover.prototype, "bindings", void 0);
_ts_decorate([
    state(),
    _ts_metadata("design:type", "u" < typeof Error ? Object : Error)
], AtomicPopover.prototype, "error", void 0);
_ts_decorate([
    bindStateToController('searchStatus'),
    state(),
    _ts_metadata("design:type", "u" < typeof SearchStatusState ? Object : SearchStatusState)
], AtomicPopover.prototype, "searchStatusState", void 0);
_ts_decorate([
    state()
], AtomicPopover.prototype, "isOpen", void 0);
_ts_decorate([
    state(),
    _ts_metadata("design:type", "u" < typeof PopoverChildFacet ? Object : PopoverChildFacet)
], AtomicPopover.prototype, "childFacet", void 0);
_ts_decorate([
    bindingGuard(),
    errorGuard(),
    _ts_metadata("design:type", Function),
    _ts_metadata("design:paramtypes", []),
    _ts_metadata("design:returntype", void 0)
], AtomicPopover.prototype, "render", null);
AtomicPopover = _ts_decorate([
    customElement('atomic-popover'),
    bindings(),
    withTailwindStyles
], AtomicPopover);
export { AtomicPopover };
