export class RatingManager {
    constructor(selectorOrElement, options = {}) {
        this.hoverValue = null;
        this.handleClick = (e) => {
            if (this.options.readOnly)
                return;
            const star = e.currentTarget;
            const value = this.getStarValue(star, e);
            this.setValue(value);
        };
        this.handleMouseEnter = (e) => {
            if (this.options.readOnly)
                return;
            const star = e.currentTarget;
            this.hoverValue = this.getStarValue(star, e);
            this.updateDisplay();
        };
        this.handleMouseLeave = () => {
        };
        this.handleKeyDown = (e) => {
            if (this.options.readOnly)
                return;
            const step = this.options.half ? 0.5 : 1;
            switch (e.key) {
                case "ArrowRight":
                case "ArrowUp":
                    e.preventDefault();
                    this.setValue(Math.min(this.currentValue + step, this.options.max));
                    break;
                case "ArrowLeft":
                case "ArrowDown":
                    e.preventDefault();
                    this.setValue(Math.max(this.currentValue - step, 0));
                    break;
                case "Home":
                    e.preventDefault();
                    this.setValue(0);
                    break;
                case "End":
                    e.preventDefault();
                    this.setValue(this.options.max);
                    break;
            }
        };
        this.container =
            typeof selectorOrElement === "string"
                ? document.querySelector(selectorOrElement)
                : selectorOrElement;
        this.options = {
            max: options.max ?? 5,
            value: options.value ?? 0,
            readOnly: options.readOnly ?? false,
            half: options.half ?? false,
            starSelector: options.starSelector ?? ".star, [data-value]",
            activeClass: options.activeClass ?? "rating__star--active",
            halfClass: options.halfClass ?? "rating__star--half",
            hoverClass: options.hoverClass ?? "rating__star--hover",
            onChange: options.onChange ?? (() => { }),
        };
        this.currentValue = this.options.value;
        this.stars = [];
        if (!this.container) {
            console.warn("[Stylescape] RatingManager container not found");
            return;
        }
        this.init();
    }
    getValue() {
        return this.currentValue;
    }
    setValue(value) {
        const clamped = Math.min(Math.max(value, 0), this.options.max);
        this.currentValue = this.options.half ? clamped : Math.round(clamped);
        this.updateDisplay();
        this.options.onChange(this.currentValue);
    }
    reset() {
        this.setValue(0);
    }
    setReadOnly(readOnly) {
        this.options.readOnly = readOnly;
        this.container?.classList.toggle("rating--readonly", readOnly);
        if (readOnly) {
            this.container?.setAttribute("aria-readonly", "true");
        }
        else {
            this.container?.removeAttribute("aria-readonly");
        }
    }
    destroy() {
        this.stars.forEach((star) => {
            star.removeEventListener("click", this.handleClick);
            star.removeEventListener("mouseenter", this.handleMouseEnter);
            star.removeEventListener("mouseleave", this.handleMouseLeave);
        });
        this.container?.removeEventListener("keydown", this.handleKeyDown);
        this.container = null;
        this.stars = [];
    }
    init() {
        if (!this.container)
            return;
        this.stars = Array.from(this.container.querySelectorAll(this.options.starSelector));
        if (this.stars.length === 0) {
            this.createStars();
        }
        this.container.setAttribute("role", "slider");
        this.container.setAttribute("aria-valuemin", "0");
        this.container.setAttribute("aria-valuemax", String(this.options.max));
        this.container.setAttribute("aria-valuenow", String(this.currentValue));
        this.container.setAttribute("tabindex", "0");
        if (!this.options.readOnly) {
            this.stars.forEach((star, index) => {
                star.addEventListener("click", this.handleClick);
                star.addEventListener("mouseenter", this.handleMouseEnter);
                star.addEventListener("mouseleave", this.handleMouseLeave);
                if (!star.hasAttribute("data-value")) {
                    star.setAttribute("data-value", String(index + 1));
                }
            });
            this.container.addEventListener("keydown", this.handleKeyDown);
            this.container.addEventListener("mouseleave", () => {
                this.hoverValue = null;
                this.updateDisplay();
            });
        }
        this.updateDisplay();
    }
    createStars() {
        if (!this.container)
            return;
        for (let i = 1; i <= this.options.max; i++) {
            const star = document.createElement("span");
            star.className = "rating__star";
            star.setAttribute("data-value", String(i));
            star.textContent = "★";
            this.container.appendChild(star);
            this.stars.push(star);
        }
    }
    getStarValue(star, event) {
        const baseValue = parseInt(star.getAttribute("data-value") || "0", 10);
        if (this.options.half) {
            const rect = star.getBoundingClientRect();
            const isHalf = event.clientX < rect.left + rect.width / 2;
            return isHalf ? baseValue - 0.5 : baseValue;
        }
        return baseValue;
    }
    updateDisplay() {
        const displayValue = this.hoverValue ?? this.currentValue;
        this.stars.forEach((star) => {
            const value = parseInt(star.getAttribute("data-value") || "0", 10);
            const isActive = value <= displayValue;
            const isHalf = this.options.half && value - 0.5 === displayValue;
            const isHover = this.hoverValue !== null;
            star.classList.toggle(this.options.activeClass, isActive && !isHalf);
            star.classList.toggle(this.options.halfClass, isHalf);
            star.classList.toggle(this.options.hoverClass, isHover && value <= displayValue);
        });
        this.container?.setAttribute("aria-valuenow", String(this.currentValue));
    }
}
export default RatingManager;
//# sourceMappingURL=RatingManager.js.map