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 { cn } from "../../shared/tools/cn.js";
import "../../shared/tools/index.js";
import "../lukso-form-description/index.js";
import "../lukso-form-error/index.js";
import "../lukso-form-label/index.js";
import style_default from "./style.css?inline.js";
import { RULES_MAP } from "./rules.js";
import { html, nothing } from "lit";
import { property, state } from "lit/decorators.js";
import { tv } from "tailwind-variants";
//#region src/components/lukso-input/index.ts
var FOCUS_DELAY_MS = 10;
var LuksoInput = class LuksoInput extends TailwindStyledElement(style_default) {
	constructor(..._args) {
		super(..._args);
		this.value = "";
		this.type = "text";
		this.autocomplete = "on";
		this.isFullWidth = false;
		this.isReadonly = false;
		this.isDisabled = false;
		this.autofocus = false;
		this.borderless = false;
		this.size = "large";
		this.rightIcon = "";
		this.isRightIconClickable = false;
		this.keepFocusOnEscape = false;
		this.rules = [];
		this.hasFocus = false;
		this.hasHighlight = false;
		this.inputStyles = tv({
			slots: {
				wrapper: "group flex",
				input: `bg-neutral-100 border-solid placeholder:text-neutral-70 w-full
        outline-none transition transition-all duration-150 appearance-none`,
				unit: `bg-neutral-100 text-neutral-60 flex items-center relative border-solid transition
        transition-all duration-150 before:bg-neutral-90 before:absolute
        before:left-0 before:w-[1px] whitespace-nowrap cursor-pointer`,
				rightIcon: "absolute top-1/2 transform -translate-y-1/2"
			},
			variants: {
				hasError: {
					true: {
						input: "border-red-85",
						unit: "border-red-85"
					},
					false: {
						input: "border-neutral-90",
						unit: "border-neutral-90"
					}
				},
				hasHighlight: { true: {
					input: "border-neutral-35",
					unit: "border-neutral-35"
				} },
				hasUnit: { true: { input: "!border-r-0 !rounded-r-0" } },
				hasRightIcon: { true: {} },
				borderless: {
					true: {
						input: "border-0",
						unit: "border-0"
					},
					false: {
						input: "border",
						unit: "border border-l-0"
					}
				},
				isReadonly: { true: {
					input: "cursor-not-allowed",
					rightIcon: "cursor-not-allowed"
				} },
				isDisabled: {
					true: {
						input: "text-neutral-60 cursor-not-allowed",
						rightIcon: "cursor-not-allowed opacity-50"
					},
					false: { input: "text-neutral-20" }
				},
				isFullWidth: {
					true: { wrapper: "w-full" },
					false: { wrapper: "w-[350px]" }
				},
				size: {
					small: {
						input: "h-7 px-3 py-1 paragraph-inter-12-regular rounded-8",
						unit: "h-7 paragraph-inter-12-regular px-2 rounded-r-8 before:top-[calc(50%-6px)] before:h-[12px]",
						rightIcon: "right-3"
					},
					medium: {
						input: "h-10 px-3.5 py-2 paragraph-inter-14-regular rounded-[10px]",
						unit: "h-10 paragraph-inter-12-regular px-3 rounded-r-[10px] before:top-[calc(50%-12px)] before:h-6",
						rightIcon: "right-4"
					},
					large: {
						input: "h-12 px-4 py-2 paragraph-inter-14-regular rounded-12",
						unit: "h-12 paragraph-inter-12-regular pl-3 pr-4 rounded-r-12 before:top-[calc(50%-12px)] before:h-6",
						rightIcon: "right-4"
					},
					"x-large": {
						input: "h-17 px-5 py-5 paragraph-inter-16-regular rounded-[14px]",
						unit: "h-17 paragraph-inter-16-regular pl-3 pr-4 rounded-r-[14px] before:top-[calc(50%-12px)] before:h-6",
						rightIcon: "right-4"
					}
				},
				isRightIconClickable: { true: { rightIcon: "cursor-pointer" } }
			},
			compoundVariants: [
				{
					isFullWidth: false,
					hasUnit: true,
					class: { wrapper: "w-[300px]" }
				},
				{
					isFullWidth: false,
					hasUnit: false,
					size: "small",
					class: { wrapper: "w-[190px]" }
				},
				{
					isFullWidth: false,
					hasUnit: true,
					size: "small",
					class: { wrapper: "w-[210px]" }
				},
				{
					hasHighlight: true,
					hasError: true,
					class: {
						input: "border-red-65",
						unit: "border-red-65"
					}
				},
				{
					hasRightIcon: true,
					size: [
						"medium",
						"large",
						"x-large"
					],
					class: { input: "pr-10" }
				},
				{
					hasRightIcon: true,
					size: "small",
					class: { input: "pr-7" }
				}
			]
		});
	}
	connectedCallback() {
		super.connectedCallback();
		if (this.autofocus) setTimeout(() => {
			(this.shadowRoot?.querySelector("input"))?.focus();
		}, FOCUS_DELAY_MS);
	}
	inputTemplate(styles) {
		return html`
      <input
        name=${this.name ? this.name : nothing}
        type=${this.type}
        .value=${this.value}
        placeholder=${this.placeholder ? this.placeholder : nothing}
        ?autofocus=${this.autofocus}
        min=${this.min ? this.min : nothing}
        max=${this.max ? this.max : nothing}
        autocomplete=${this.autocomplete}
        ref=${this.ref ? this.ref : nothing}
        id=${this.id ? this.id : nothing}
        data-testid=${this.name ? `input-${this.name}` : "input"}
        accept=${this.accept ? this.accept : nothing}
        ?readonly=${this.isReadonly ? true : void 0}
        ?disabled=${this.isDisabled ? true : void 0}
        class=${cn(styles, this.customClass)}
        @focus=${this.handleFocus}
        @input=${this.handleInput}
        @change=${this.handleChange}
        @blur=${this.handleBlur}
        @keyup=${this.handleKeyUp}
        @keydown=${this.handleKeyDown}
        @keypress=${this.handleKeyPress}
        @mouseenter=${this.handleMouseOver}
        @mouseleave=${this.handleMouseOut}
        @click=${this.handleInputClick}
      />
    `;
	}
	unitTemplate(styles) {
		return html`<div
      class=${styles}
      @mouseenter=${this.handleMouseOver}
      @mouseleave=${this.handleMouseOut}
      @click=${this.handleUnitClick}
    >
      ${this.unit}
    </div>`;
	}
	rightIconTemplate(styles) {
		const iconSize = this.size === "small" ? "small" : "medium";
		return html`<lukso-icon
      name=${this.rightIcon}
      size=${iconSize}
      class=${styles}
      @click=${this.handleRightIconClick}
    ></lukso-icon>`;
	}
	handleFocus() {
		if (!this.isReadonly && !this.isDisabled) {
			this.hasFocus = true;
			this.hasHighlight = true;
		}
	}
	async handleBlur(event) {
		this.hasFocus = false;
		this.hasHighlight = false;
		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);
	}
	async handleChange(event) {
		await this.updateComplete;
		const target = event.target;
		const changeEvent = new CustomEvent("on-change", {
			detail: {
				value: target?.value,
				event
			},
			bubbles: false,
			composed: true
		});
		this.dispatchEvent(changeEvent);
	}
	async handleInput(event) {
		const target = event.target;
		if (this.activeRules.length > 0) {
			const blockRules = this.activeRules.filter((rule) => rule.type === "disallow");
			const allowRules = this.activeRules.filter((rule) => rule.type === "allow");
			const sanitized = blockRules.reduce((val, rule) => rule.sanitize(val), allowRules.length > 0 ? target.value.split("").filter((ch) => allowRules.some((rule) => rule.validate(target, ch))).join("") : target.value);
			if (sanitized !== target.value) {
				const cursor = target.selectionStart ?? sanitized.length;
				target.value = sanitized;
				target.setSelectionRange(cursor, cursor);
			}
		}
		this.value = target?.value;
		await this.updateComplete;
		const changeEvent = new CustomEvent("on-input", {
			detail: {
				value: target?.value,
				event
			},
			bubbles: false,
			composed: true
		});
		this.dispatchEvent(changeEvent);
	}
	async handleKeyUp(event) {
		await this.updateComplete;
		const target = event.target;
		const keyEvent = new CustomEvent("on-key-up", {
			detail: {
				value: target?.value,
				event
			},
			bubbles: true,
			composed: true
		});
		this.dispatchEvent(keyEvent);
		if (event.key === "Escape" && !this.keepFocusOnEscape) this.blur();
	}
	get activeRules() {
		return this.rules.map((name) => RULES_MAP[name]).filter(Boolean);
	}
	async handleKeyDown(event) {
		if (event.key.length === 1 && this.activeRules.length > 0) {
			const input = event.target;
			const blockRules = this.activeRules.filter((rule) => rule.type === "disallow");
			const allowRules = this.activeRules.filter((rule) => rule.type === "allow");
			const passesBlock = blockRules.every((rule) => rule.validate(input, event.key));
			const passesAllow = allowRules.length === 0 || allowRules.some((rule) => rule.validate(input, event.key));
			if (!passesBlock || !passesAllow) {
				event.preventDefault();
				return;
			}
		}
		await this.updateComplete;
		const target = event.target;
		const keyEvent = new CustomEvent("on-key-down", {
			detail: {
				value: target.value,
				event
			},
			bubbles: true,
			composed: true
		});
		this.dispatchEvent(keyEvent);
	}
	async handleKeyPress(event) {
		await this.updateComplete;
		const target = event.target;
		const keyEvent = new CustomEvent("on-key-press", {
			detail: {
				value: target?.value,
				event
			},
			bubbles: true,
			composed: true
		});
		this.dispatchEvent(keyEvent);
	}
	handleMouseOver() {
		if (!this.isReadonly && !this.isDisabled) this.hasHighlight = true;
	}
	handleMouseOut() {
		if (!this.hasFocus) this.hasHighlight = false;
	}
	handleUnitClick() {
		const input = this.shadowRoot?.querySelector("input");
		const clickEvent = new CustomEvent("on-unit-click", {
			detail: { input },
			bubbles: true,
			composed: true
		});
		this.dispatchEvent(clickEvent);
		input?.focus();
	}
	async handleInputClick(event) {
		await this.updateComplete;
		const target = event.target;
		const clickEvent = new CustomEvent("on-input-click", {
			detail: {
				value: target.value,
				event
			},
			bubbles: false,
			composed: true
		});
		this.dispatchEvent(clickEvent);
	}
	handleRightIconClick() {
		const input = this.shadowRoot?.querySelector("input");
		const clickEvent = new CustomEvent("on-right-icon-click", {
			detail: { input },
			bubbles: true,
			composed: true
		});
		this.dispatchEvent(clickEvent);
	}
	render() {
		const { wrapper, input, unit, rightIcon } = this.inputStyles({
			hasError: !!this.error,
			hasHighlight: this.hasHighlight,
			borderless: this.borderless,
			isReadonly: this.isReadonly,
			isDisabled: this.isDisabled,
			isFullWidth: this.isFullWidth,
			hasUnit: !!this.unit,
			size: this.size,
			hasRightIcon: !!this.rightIcon,
			isRightIconClickable: this.isRightIconClickable
		});
		return html`
      <div class="w-[inherit]">
        <lukso-form-label
          for-name=${this.name}
          label=${this.label}
        ></lukso-form-label>
        <lukso-form-description
          description=${this.description}
        ></lukso-form-description>
        <div class=${wrapper()}>
          <div class="relative w-[inherit]">
            ${this.inputTemplate(input())}
            ${this.rightIcon ? this.rightIconTemplate(rightIcon()) : nothing}
          </div>
          ${this.unit ? this.unitTemplate(unit()) : nothing}
        </div>
        <lukso-form-error error=${this.error}></lukso-form-error>
      </div>
    `;
	}
};
__decorate([property({ type: String })], LuksoInput.prototype, "value", void 0);
__decorate([property({ type: String })], LuksoInput.prototype, "name", void 0);
__decorate([property({ type: String })], LuksoInput.prototype, "type", void 0);
__decorate([property({ type: String })], LuksoInput.prototype, "placeholder", void 0);
__decorate([property({ type: String })], LuksoInput.prototype, "label", void 0);
__decorate([property({ type: String })], LuksoInput.prototype, "autocomplete", void 0);
__decorate([property({ type: String })], LuksoInput.prototype, "id", void 0);
__decorate([property({ type: String })], LuksoInput.prototype, "ref", void 0);
__decorate([property({ type: String })], LuksoInput.prototype, "accept", void 0);
__decorate([property({ type: String })], LuksoInput.prototype, "description", void 0);
__decorate([property({ type: String })], LuksoInput.prototype, "error", void 0);
__decorate([property({ type: String })], LuksoInput.prototype, "unit", void 0);
__decorate([property({
	type: String,
	attribute: "custom-class"
})], LuksoInput.prototype, "customClass", void 0);
__decorate([property({
	type: Boolean,
	attribute: "is-full-width"
})], LuksoInput.prototype, "isFullWidth", void 0);
__decorate([property({
	type: Boolean,
	attribute: "is-readonly"
})], LuksoInput.prototype, "isReadonly", void 0);
__decorate([property({
	type: Boolean,
	attribute: "is-disabled"
})], LuksoInput.prototype, "isDisabled", void 0);
__decorate([property({ type: Boolean })], LuksoInput.prototype, "autofocus", void 0);
__decorate([property({ type: Number })], LuksoInput.prototype, "max", void 0);
__decorate([property({ type: Number })], LuksoInput.prototype, "min", void 0);
__decorate([property({ type: Boolean })], LuksoInput.prototype, "borderless", void 0);
__decorate([property({ type: String })], LuksoInput.prototype, "size", void 0);
__decorate([property({
	type: String,
	attribute: "right-icon"
})], LuksoInput.prototype, "rightIcon", void 0);
__decorate([property({
	type: Boolean,
	attribute: "is-right-icon-clickable"
})], LuksoInput.prototype, "isRightIconClickable", void 0);
__decorate([property({
	type: Boolean,
	attribute: "keep-focus-on-escape"
})], LuksoInput.prototype, "keepFocusOnEscape", void 0);
__decorate([property({ type: Array })], LuksoInput.prototype, "rules", void 0);
__decorate([state()], LuksoInput.prototype, "hasFocus", void 0);
__decorate([state()], LuksoInput.prototype, "hasHighlight", void 0);
LuksoInput = __decorate([safeCustomElement("lukso-input")], LuksoInput);
//#endregion
export { LuksoInput };
