import { safeCustomElement } from "../../shared/safe-custom-element.js";
import { TailwindStyledElement } from "../../shared/tailwind-element/index.js";
import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.127.0/helpers/decorate.js";
import "../lukso-icon/index.js";
import "../lukso-sanitize/index.js";
import "../lukso-profile/index.js";
import "../lukso-form-description/index.js";
import "../lukso-form-error/index.js";
import "../lukso-form-label/index.js";
import "../lukso-username/index.js";
import { uniqId } from "../../shared/tools/uniq-id.js";
import "../lukso-dropdown/index.js";
import "../lukso-dropdown-option/index.js";
import "../lukso-tooltip/index.js";
import style_default from "./style.css?inline.js";
import { html, nothing } from "lit";
import { property, state } from "lit/decorators.js";
import { tv } from "tailwind-variants";
import makeBlockie from "ethereum-blockies-base64";
//#region src/components/lukso-select/index.ts
var LuksoSelect = class LuksoSelect extends TailwindStyledElement(style_default) {
	constructor() {
		super();
		this.value = "";
		this.placeholder = "";
		this.label = "";
		this.id = "";
		this.description = "";
		this.error = "";
		this.isFullWidth = false;
		this.isReadonly = false;
		this.isDisabled = false;
		this.borderless = false;
		this.options = "";
		this.isOpen = false;
		this.openTop = false;
		this.isLargeIcon = false;
		this.isRight = false;
		this.size = "large";
		this.showSelectionCounter = false;
		this.optionsParsed = [];
		this.valueParsed = void 0;
		this.rightSlotWidth = 0;
		this.inputStyles = tv({
			base: `bg-neutral-100
      border border-solid placeholder:text-neutral-70 select-none whitespace-nowrap
      outline-none transition transition-all duration-150 appearance-none
      text-neutral-20 cursor-pointer border-neutral-90 group-hover:border-neutral-35
      flex items-center w-full`,
			variants: {
				isDisabled: { true: "cursor-not-allowed text-neutral-60 group-hover:border-neutral-90" },
				hasError: { true: "border-red-85 group-hover:border-red-65" },
				borderless: { true: "border-0" },
				size: {
					small: "h-7 px-3 py-2 pr-8 paragraph-inter-12-regular rounded-8",
					medium: "h-10 px-3 py-3 pr-11 paragraph-inter-14-regular rounded-10",
					large: "h-12 px-4 py-3 pr-11 paragraph-inter-14-regular rounded-12",
					"x-large": ""
				}
			}
		});
		this.counterStyles = tv({
			base: "border border-neutral-20",
			variants: {
				isDisabled: { true: "opacity-60 cursor-not-allowed" },
				size: {
					small: "paragraph-inter-10-semi-bold rounded-4 py-[1px] px-[5px] ml-1.5",
					medium: "paragraph-inter-14-semi-bold rounded-8 py-[2px] px-[10px] ml-3",
					large: "paragraph-inter-14-semi-bold rounded-8 py-[2px] px-[10px] ml-3",
					"x-large": ""
				}
			}
		});
		this.iconWrapperStyles = tv({
			base: "absolute right-0 flex items-center",
			variants: { size: {
				small: "mr-2",
				medium: "mr-3",
				large: "mr-3",
				"x-large": ""
			} }
		});
		this.iconStyles = tv({
			base: "transition cursor-pointer",
			variants: {
				isDisabled: { true: "opacity-60 cursor-not-allowed" },
				isOpen: { true: "rotate-180" }
			}
		});
		if (!this.id) this.id = uniqId();
	}
	handleRightSlotChange(event) {
		const assigned = event.target.assignedElements();
		if (!assigned.length) {
			this.rightSlotWidth = 0;
			return;
		}
		requestAnimationFrame(() => {
			this.rightSlotWidth = assigned.reduce((acc, el) => acc + el.getBoundingClientRect().width, 0);
		});
	}
	connectedCallback() {
		super.connectedCallback();
		window.addEventListener("click", this.handleOutsideDropdownClick.bind(this));
		window.addEventListener("keydown", this.handleDropdownKeydown.bind(this));
	}
	disconnectedCallback() {
		super.disconnectedCallback();
		window.removeEventListener("click", this.handleOutsideDropdownClick);
		window.removeEventListener("keydown", this.handleDropdownKeydown);
	}
	willUpdate(changedProperties) {
		if (changedProperties.has("selected")) {
			const selectedOption = this.shadowRoot?.querySelector(`[data-index="${changedProperties.get("selected")}"`);
			if (selectedOption) if ("scrollIntoViewIfNeeded" in selectedOption && typeof selectedOption.scrollIntoViewIfNeeded === "function") selectedOption.scrollIntoViewIfNeeded();
			else selectedOption.scrollIntoView({
				behavior: "smooth",
				block: "center"
			});
		}
		if (changedProperties.has("options") && !!this.options) try {
			this.optionsParsed = JSON.parse(this.options);
		} catch (error) {
			console.warn("Could not parse options", error);
			this.optionsParsed = [];
		}
		if (changedProperties.has("value") && !!this.value) try {
			const value = JSON.parse(this.value);
			this.valueParsed = Array.isArray(value) ? value : [value];
		} catch (error) {
			console.warn("Could not parse value", error);
		}
	}
	inputTemplate() {
		const inputStyles = this.inputStyles({
			isDisabled: this.isDisabled,
			hasError: !!this.error,
			borderless: this.borderless,
			size: this.size
		});
		const basePr = {
			small: 32,
			medium: 44,
			large: 44
		}[this.size];
		const paddingRightStyle = this.rightSlotWidth && basePr ? `padding-right: ${basePr + this.rightSlotWidth + 8}px` : nothing;
		return html`
      <div
        id=${this.id}
        data-testid=${this.id ? `select-${this.id}` : "select"}
        class=${inputStyles}
        style=${paddingRightStyle}
        @blur=${this.handleBlur}
        @click=${this.handleClick}
      >
        ${this.placeholder ? this.placeholder : nothing}
        ${!this.placeholder && this.valueParsed?.length ? this.selectedValueTemplate() : nothing}
        ${this.showSelectionCounter && this.valueParsed?.length ? this.selectedOptionsCounterTemplate() : nothing}
      </div>
    `;
	}
	selectedOptionsCounterTemplate() {
		return html`<div class=${this.counterStyles({
			isDisabled: this.isDisabled,
			size: this.size
		})}>${this.valueParsed?.length}</div>`;
	}
	optionsTemplate() {
		const optionTemplates = [];
		let _options = [];
		const groups = this.optionsParsed.reduce((acc, option) => {
			if (option.group && !acc.includes(option.group)) acc.push(option.group);
			return acc;
		}, []);
		if (groups.length > 0) for (const group of groups) _options.push({
			group,
			values: this.optionsParsed.filter((option) => option.group === group)
		});
		else _options = this.optionsParsed;
		for (const option of Object.entries(_options)) {
			const index = Number(option[0]);
			if ("values" in option[1]) optionTemplates.push(this.optionGroupedTemplate(option[1], index));
			else optionTemplates.push(this.optionByTypeTemplate(option[1], index));
		}
		return html`<lukso-dropdown
      size=${this.size}
      is-open
      is-open-on-outside-click
      max-height=${this.maxHeight}
      ?is-full-width=${this.isFullWidth}
      ?is-right=${this.isRight}
      ?open-top=${this.openTop}
      >${optionTemplates}</lukso-dropdown
    >`;
	}
	optionByTypeTemplate(option, index) {
		switch (option.type) {
			case "profile": return this.optionProfileTemplate(option, index);
			case "secondary-with-tooltip": return this.optionSecondaryWithTooltipTemplate(option, index);
			default: return this.optionStringTemplate(option, index);
		}
	}
	optionGroupedTemplate(option, index) {
		return html`<div
        class="paragraph-inter-10-bold-uppercase text-neutral-20 p-1 text-left"
      >
        ${option.group}
      </div>
      ${option.values.map((value) => this.optionByTypeTemplate(value, index))}`;
	}
	optionStringTemplate(option, index) {
		return html`<lukso-dropdown-option
      data-id="${option.id}"
      data-index="${index + 1}"
      ?is-selected=${!!this.valueParsed?.find((value) => value.id === option.id)}
      ?is-active=${this.selected === index + 1 && !this.valueParsed?.find((value) => value.id === option.id)}
      size=${this.size}
      ?is-group=${!!option.group}
      ?is-disabled=${this.isDisabled}
      ?is-readonly=${this.isReadonly}
      @click=${() => this.handleSelect(option)}
    >
      ${this.optionStringValue(option)}
    </lukso-dropdown-option>`;
	}
	optionProfileTemplate(option, index) {
		return html`<lukso-dropdown-option
      data-id="${option.id}"
      data-index="${index + 1}"
      ?is-selected=${!!this.valueParsed?.find((value) => value.id === option.id)}
      ?is-active=${this.selected === index + 1 && !this.valueParsed?.find((value) => value.id === option.id)}
      size=${this.size}
      ?is-disabled=${this.isDisabled}
      ?is-readonly=${this.isReadonly}
      @click=${() => this.handleSelect(option)}
    >
      ${this.optionProfileValue(option)}
    </lukso-dropdown-option>`;
	}
	optionSecondaryWithTooltipTemplate(option, index) {
		return html`<lukso-dropdown-option
      data-id="${option.id}"
      data-index="${index + 1}"
      ?is-selected=${!!this.valueParsed?.find((value) => value.id === option.id)}
      ?is-active=${this.selected === index + 1 && !this.valueParsed?.find((value) => value.id === option.id)}
      size=${this.size}
      ?is-disabled=${this.isDisabled}
      ?is-readonly=${this.isReadonly}
      @click=${() => this.handleSelect(option)}
    >
      ${option.value}
      ${option.secondaryValue ? html`<span class="paragraph-inter-14-regular text-neutral-60 shrink-0"
            >${option.secondaryValue}</span
          >` : nothing}
      ${option.tooltip ? html`<div class="ml-auto shrink-0 flex items-center">
            <lukso-tooltip text="${option.tooltip}">
              <lukso-icon
                name="information"
                size=${this.size === "small" ? "x-small" : "small"}
              ></lukso-icon>
            </lukso-tooltip>
          </div>` : nothing}
    </lukso-dropdown-option>`;
	}
	optionStringValue(option) {
		return option.value ?? "";
	}
	optionProfileValue(option) {
		const address = option.address ?? "";
		const eoaProfilePicture = html`<lukso-profile
      profile-address="${address}"
      profile-url="${address ? makeBlockie(address) : ""}"
      size="x-small"
    ></lukso-profile>`;
		const lsp3ProfilePicture = html`<lukso-profile
      profile-address="${address}"
      profile-url="${option.image}"
      size="x-small"
      has-identicon
    ></lukso-profile>`;
		return html`${option.isEOA ? eoaProfilePicture : lsp3ProfilePicture}
      <lukso-username
        name="${option.name?.toLowerCase()}"
        address="${address}"
        name-color="neutral-20"
        slice-by="4"
        size=${this.size}
        class="ml-1"
      ></lukso-username>`;
	}
	selectedValueTemplate() {
		const firstOption = this.optionsParsed[0];
		if (!firstOption) return "";
		if (firstOption.type === "profile") {
			const foundValues = this.optionsParsed.filter((option) => !!this.valueParsed?.find((value) => value.id === option.id));
			const optionProfileValues = [];
			for (const value of foundValues) optionProfileValues.push(this.optionProfileValue(value));
			return optionProfileValues;
		}
		const foundValues = this.optionsParsed.filter((option) => !!this.valueParsed?.find((value) => value.id === option.id));
		if (firstOption.type === "secondary-with-tooltip") return html`${foundValues.map((value, index) => html`${index > 0 ? ", " : ""}${value.value ?? ""}${value.secondaryValue ? html`<span
                class="paragraph-inter-14-regular text-neutral-60 shrink-0 ml-1"
                >${value.secondaryValue}</span
              >` : nothing}`)}`;
		return foundValues.map((value) => this.optionStringValue(value)).join(", ");
	}
	handleOutsideDropdownClick(event) {
		const element = event.target;
		if (element.tagName === "LUKSO-SELECT" && this.id === element.id) return;
		this.isOpen = false;
	}
	async handleDropdownKeydown(event) {
		if (event.key === "ArrowUp" && this.selected && this.selected > 1 && this.isOpen) {
			event.preventDefault();
			this.selected = this.selected - 1;
		}
		if (event.key === "ArrowDown" && this.optionsParsed?.length && this.isOpen) {
			event.preventDefault();
			if (!this.selected) this.selected = 1;
			else if (this.selected < this.optionsParsed.length) this.selected = this.selected + 1;
		}
		if (event.key === "Enter" && this.isOpen) {
			if (this.optionsParsed?.length && this.selected) {
				const selectedResult = this.optionsParsed[this.selected - 1];
				await this.handleSelect(selectedResult);
			}
		}
		if (event.key === "Escape") this.isOpen = false;
	}
	async handleSelect(option) {
		if (this.isReadonly || this.isDisabled) return;
		await this.updateComplete;
		this.isOpen = false;
		const selectEvent = new CustomEvent("on-select", {
			detail: { value: option },
			bubbles: false,
			composed: true
		});
		this.dispatchEvent(selectEvent);
	}
	async handleBlur(event) {
		await this.updateComplete;
		const target = event.target;
		const blurEvent = new CustomEvent("on-blur", {
			detail: {
				value: target.value,
				event
			},
			bubbles: false,
			composed: true
		});
		this.dispatchEvent(blurEvent);
	}
	handleClick() {
		if (this.isDisabled) return;
		this.isOpen = !this.isOpen;
	}
	render() {
		const iconStyles = this.iconStyles({
			isDisabled: this.isDisabled,
			isOpen: this.isOpen
		});
		const iconWrapperStyles = this.iconWrapperStyles({ size: this.size });
		return html`
      <div class="relative w-[inherit]">
        <lukso-form-label label=${this.label}></lukso-form-label>
        <lukso-form-description
          description=${this.description}
        ></lukso-form-description>
        <div class="group">
          <div class="flex relative items-center">
            ${this.inputTemplate()}
            <div class="${iconWrapperStyles}">
              <slot
                name="right"
                @slotchange=${this.handleRightSlotChange}
              ></slot>
              <lukso-icon
                name=${this.isLargeIcon ? "arrow-down-lg" : "arrow-down-sm"}
                class="${iconStyles}"
                @click=${this.handleClick}
              ></lukso-icon>
            </div>
          </div>
          <!-- options dropdown -->
          ${this.isOpen && this.optionsParsed.length > 0 ? this.optionsTemplate() : nothing}
        </div>
        <lukso-form-error error=${this.error}></lukso-form-error>
      </div>
    `;
	}
};
__decorate([property({ type: String })], LuksoSelect.prototype, "value", void 0);
__decorate([property({ type: String })], LuksoSelect.prototype, "placeholder", void 0);
__decorate([property({ type: String })], LuksoSelect.prototype, "label", void 0);
__decorate([property({ type: String })], LuksoSelect.prototype, "id", void 0);
__decorate([property({ type: String })], LuksoSelect.prototype, "description", void 0);
__decorate([property({ type: String })], LuksoSelect.prototype, "error", void 0);
__decorate([property({
	type: Boolean,
	attribute: "is-full-width"
})], LuksoSelect.prototype, "isFullWidth", void 0);
__decorate([property({
	type: Boolean,
	attribute: "is-readonly"
})], LuksoSelect.prototype, "isReadonly", void 0);
__decorate([property({
	type: Boolean,
	attribute: "is-disabled"
})], LuksoSelect.prototype, "isDisabled", void 0);
__decorate([property({ type: Boolean })], LuksoSelect.prototype, "borderless", void 0);
__decorate([property({ type: String })], LuksoSelect.prototype, "options", void 0);
__decorate([property({ type: Number })], LuksoSelect.prototype, "selected", void 0);
__decorate([property({
	type: Boolean,
	attribute: "is-open"
})], LuksoSelect.prototype, "isOpen", void 0);
__decorate([property({
	type: Boolean,
	attribute: "open-top"
})], LuksoSelect.prototype, "openTop", void 0);
__decorate([property({
	type: Boolean,
	attribute: "is-large-icon"
})], LuksoSelect.prototype, "isLargeIcon", void 0);
__decorate([property({
	type: Boolean,
	attribute: "is-right"
})], LuksoSelect.prototype, "isRight", void 0);
__decorate([property({ type: String })], LuksoSelect.prototype, "size", void 0);
__decorate([property({
	type: Boolean,
	attribute: "show-selection-counter"
})], LuksoSelect.prototype, "showSelectionCounter", void 0);
__decorate([property({
	type: Number,
	attribute: "max-height",
	reflect: true
})], LuksoSelect.prototype, "maxHeight", void 0);
__decorate([state()], LuksoSelect.prototype, "optionsParsed", void 0);
__decorate([state()], LuksoSelect.prototype, "valueParsed", void 0);
__decorate([state()], LuksoSelect.prototype, "rightSlotWidth", void 0);
LuksoSelect = __decorate([safeCustomElement("lukso-select")], LuksoSelect);
//#endregion
export { LuksoSelect };
