import { h, Host, } from "@stencil/core";
import { getPercentageClass } from "./get-percentage-class";
import { createRandomString } from "../../util/random-string";
const DEFAULT_FACTOR = 1;
const DEFAULT_MAX_VALUE = 100;
const DEFAULT_MIN_VALUE = 0;
const MAX_VISIBLE_STEP_DOTS = 20;
/**
 * @exampleComponent limel-example-slider-basic
 * @exampleComponent limel-example-slider-multiplier
 * @exampleComponent limel-example-slider-multiplier-percentage-colors
 * @exampleComponent limel-example-slider-unit
 * @exampleComponent limel-example-slider-composite
 */
export class Slider {
    constructor() {
        /**
         * Disables the slider when `true`,
         * and visually shows that the field is editable but disabled.
         * This tells the users that if certain requirements are met,
         * the slider may become interactable.
         */
        this.disabled = false;
        /**
         * Disables the slider when `true`. This visualizes the slider slightly differently.
         * But shows no visual sign indicating that the slider field
         * is disabled or can ever become interactable.
         */
        this.readonly = false;
        /**
         * Default value: 1.
         * The factor that the properties `value`, `valuemax`, `valuemin`, and
         * `step` are multiplied by. On `change` divides the value by the factor,
         * so the original format stays the same.
         */
        this.factor = DEFAULT_FACTOR;
        /**
         * Set to `true` to indicate that the slider is required.
         */
        this.required = false;
        /**
         * Set to `true` to indicate that the current value of the slider is invalid.
         */
        this.invalid = false;
        /**
         * Set to `true` to display percentage-based colors on the slider.
         * The colors change in intervals of 10% as the value changes,
         * creating a color spectrum from red (low) → orange → yellow → green → teal (high).
         */
        this.displaysPercentageColors = false;
        /**
         * Unit to display next to the value
         */
        this.unit = '';
        /**
         * The maximum value allowed
         */
        this.valuemax = DEFAULT_MAX_VALUE;
        /**
         * The minimum value allowed
         */
        this.valuemin = DEFAULT_MIN_VALUE;
        this.renderStepDots = (min, max) => {
            if (!this.step) {
                return;
            }
            const step = this.multiplyByFactor(this.step);
            const count = Math.floor((max - min) / step) + 1;
            if (count > MAX_VISIBLE_STEP_DOTS) {
                return;
            }
            return Array.from({ length: count }, () => h("span", { class: "step-dot" }));
        };
        this.renderHelperLine = () => {
            if (!this.helperText) {
                return;
            }
            return (h("limel-helper-line", { helperText: this.helperText, helperTextId: this.helperTextId, invalid: this.invalid }));
        };
        this.handleInput = (event) => {
            event.stopPropagation();
            const input = event.target;
            const value = Number(input.value);
            this.displayValue = value;
            this.setPercentageClass(value / this.factor);
        };
        this.handleChange = (event) => {
            event.stopPropagation();
            const input = event.target;
            let value = Number(input.value);
            const step = this.multiplyByFactor(this.step);
            if (!this.isMultipleOfStep(value, step)) {
                value = this.roundToStep(value, step);
            }
            this.change.emit(value / this.factor);
        };
        this.getContainerClassList = () => {
            if (!this.percentageClass) {
                return {};
            }
            return {
                [this.percentageClass]: true,
            };
        };
        this.multiplyByFactor = (value) => {
            return Math.round(value * this.factor);
        };
        this.getValue = () => {
            let value = this.value;
            if (!Number.isFinite(value)) {
                value = this.valuemin;
            }
            return value;
        };
        this.getFraction = () => {
            const min = this.multiplyByFactor(this.valuemin);
            const max = this.multiplyByFactor(this.valuemax);
            if (max === min) {
                return 0;
            }
            return Math.max(0, Math.min(1, (this.displayValue - min) / (max - min)));
        };
        this.setPercentageClass = (value) => {
            this.percentageClass = getPercentageClass((value - this.valuemin) / (this.valuemax - this.valuemin));
        };
        this.isMultipleOfStep = (value, step) => {
            if (!step) {
                return true;
            }
            return value % step === 0;
        };
        this.roundToStep = (value, step) => {
            return Math.round(value / step) * step;
        };
        this.labelId = createRandomString();
        this.helperTextId = createRandomString();
    }
    componentWillLoad() {
        this.displayValue = this.multiplyByFactor(this.getValue());
        this.setPercentageClass(this.getValue());
    }
    render() {
        const min = this.multiplyByFactor(this.valuemin);
        const max = this.multiplyByFactor(this.valuemax);
        const fraction = this.getFraction();
        const inputProps = {};
        if (this.step) {
            inputProps.step = this.multiplyByFactor(this.step);
        }
        if (this.disabled || this.readonly) {
            inputProps.disabled = true;
        }
        return (h(Host, { key: '00987f40cc3a4a7d47a5efec7257acbfcde2df06', class: this.getContainerClassList() }, h("limel-notched-outline", { key: '90d73bb40733a3bd85b0c7d6fb0420f4b48de9e9', labelId: this.labelId, label: this.label, required: this.required, invalid: this.invalid, disabled: this.disabled, readonly: this.readonly, hasValue: !!this.value, hasFloatingLabel: true }, h("div", { key: 'd35d56c074af9c68663a7f2c475794f82cc2f924', slot: "content" }, h("div", { key: '28367643903a7c888eb4c381e498d179afb2374a', class: "slider", style: { '--slider-fraction': `${fraction}` } }, h("input", Object.assign({ key: '9e2f5519e946f39444b21c893fa7c45db769b1d6', type: "range", min: min, max: max, value: this.displayValue, "aria-labelledby": this.labelId, "aria-describedby": this.helperText
                ? this.helperTextId
                : undefined, onInput: this.handleInput, onChange: this.handleChange }, inputProps)), h("div", { key: '58525aba7ff932188e1395a71f43a5b3a448cfcc', class: "track" }, h("div", { key: '4e4c6f0eb6fea869a9e204c79adb8ca2c481f566', class: "active" }), this.renderStepDots(min, max)), h("div", { key: '326cefe13667b61450ed270fee96ec6bca479fa6', class: "thumb" }, h("div", { key: '716621ccf495c5f9ec27758b62d5f15b9995cf06', class: "knob" }), h("div", { key: '110c06b6803a4120ee1c613880b2ea8243702c89', class: "indicator", "aria-hidden": "true" }, this.displayValue))), h("div", { key: '0c82e7f841b39be2380a450898c231c37282e502', class: "range-labels" }, h("span", { key: '40088f1c268470bc585f5dbcf92f479641a6c2e0', class: "min" }, this.multiplyByFactor(this.valuemin), this.unit), h("span", { key: '8375f191def455fb3967209d18d839ada677c477', class: "max" }, this.multiplyByFactor(this.valuemax), this.unit)))), this.renderHelperLine()));
    }
    watchValue() {
        this.displayValue = this.multiplyByFactor(this.getValue());
        this.setPercentageClass(this.getValue());
    }
    static get is() { return "limel-slider"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["slider.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["slider.css"]
        };
    }
    static get properties() {
        return {
            "disabled": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Disables the slider when `true`,\nand visually shows that the field is editable but disabled.\nThis tells the users that if certain requirements are met,\nthe slider may become interactable."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "disabled",
                "defaultValue": "false"
            },
            "readonly": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Disables the slider when `true`. This visualizes the slider slightly differently.\nBut shows no visual sign indicating that the slider field\nis disabled or can ever become interactable."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "readonly",
                "defaultValue": "false"
            },
            "factor": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Default value: 1.\nThe factor that the properties `value`, `valuemax`, `valuemin`, and\n`step` are multiplied by. On `change` divides the value by the factor,\nso the original format stays the same."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "factor",
                "defaultValue": "DEFAULT_FACTOR"
            },
            "label": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Label to display next to the input"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "label"
            },
            "helperText": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Optional helper text to display below the slider"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "helper-text"
            },
            "required": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Set to `true` to indicate that the slider is required."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "required",
                "defaultValue": "false"
            },
            "invalid": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Set to `true` to indicate that the current value of the slider is invalid."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "invalid",
                "defaultValue": "false"
            },
            "displaysPercentageColors": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Set to `true` to display percentage-based colors on the slider.\nThe colors change in intervals of 10% as the value changes,\ncreating a color spectrum from red (low) \u2192 orange \u2192 yellow \u2192 green \u2192 teal (high)."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "displays-percentage-colors",
                "defaultValue": "false"
            },
            "unit": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Unit to display next to the value"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "unit",
                "defaultValue": "''"
            },
            "value": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The value of the input"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "value"
            },
            "valuemax": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The maximum value allowed"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "valuemax",
                "defaultValue": "DEFAULT_MAX_VALUE"
            },
            "valuemin": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The minimum value allowed"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "valuemin",
                "defaultValue": "DEFAULT_MIN_VALUE"
            },
            "step": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The stepping interval to use when adjusting the value"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "step"
            }
        };
    }
    static get states() {
        return {
            "percentageClass": {},
            "displayValue": {}
        };
    }
    static get events() {
        return [{
                "method": "change",
                "name": "change",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the value has been changed"
                },
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                }
            }];
    }
    static get watchers() {
        return [{
                "propName": "value",
                "methodName": "watchValue"
            }];
    }
}
