import { SearchBehavior } from '../../interfaces/input-select-options.interface';
import { applyInputgroupStyle } from './apply-inputgroup-style';
export class EdelInputSelectComponent {
    constructor() {
        this.value = null;
        this.search = false;
        this.autofocus = false;
        this.inline = false;
        this.searchBehavior = SearchBehavior.searchWithIncludes;
        this.maxCount = Number.MAX_SAFE_INTEGER;
        this.searchTerm = null;
        this.parsedOptions = [];
        this.selectedOptions = null;
    }
    componentDidLoad() {
        this.isOpen = this.autofocus;
        this.updateOptions();
        this.updateInGroupDidChange();
    }
    render() {
        return [
            h("edel-input-text", { ref: reference => (this.dropdownReference =
                    reference && reference.children.item(0)), value: !this.disabled && !this.search
                    ? this.value || ''
                    : this.searchTerm || '', placeholder: this.selectedOptions
                    ? this.selectedOptions.label
                    : this.value || this.placeholder, autofocus: this.autofocus, disabled: !this.search || this.disabled, inGroup: this.inGroup, onValueChange: $event => this.shouldChangeSearchTerm($event), onKeyUp: $event => this.handleSpecialKeyEvents($event), onStartEdit: () => this.open(), onClick: !this.disabled ? () => this.open() : undefined, "auto-complete": "nope-chrome" }),
            this.isOpen ? this.renderDropdown() : null
        ];
    }
    renderDropdown() {
        return (h("edel-dropdown", { flying: true, connected: true, inline: this.inline, reference: this.dropdownReference, onBackgroundClick: () => this.close() },
            h("edel-linklist", null, this.displayedOptions.map(option => (h("edel-linklist-item", { label: option.label, on: option.value === this.value, note: option.note, icon: option.icon, description: option.description, onEmit: () => this.shouldChangeValue(option) }))))));
    }
    close() {
        this.isOpen = false;
    }
    open() {
        this.isOpen = true;
    }
    handleSpecialKeyEvents(event) {
        if (event.key === 'Escape') {
            this.isOpen = !this.isOpen;
        }
        else if (event.key === 'Enter') {
            this.shouldChangeValue({
                value: this.searchTerm,
                label: this.searchTerm
            });
            event.preventDefault();
            if (event.target instanceof HTMLElement) {
                event.target.blur();
            }
        }
    }
    shouldChangeSearchTerm(newSearchTerm) {
        newSearchTerm.stopPropagation();
        this.searchTerm = newSearchTerm.detail;
        this.open();
        this.value = null;
    }
    shouldChangeValue(options) {
        this.value = options && options.value;
        this.selectedOptions = options;
        this.searchTerm = null;
        this.close();
        this.valueChange.emit(this.value);
    }
    get displayedOptions() {
        return this.searchTerm == null
            ? this.parsedOptions.slice(0, this.maxCount)
            : this.parsedOptions
                .filter(option => {
                const lowerCaseLabel = option.label.toLowerCase();
                switch (this.searchBehavior) {
                    case SearchBehavior.searchWithIncludes:
                        return lowerCaseLabel.includes(this.searchTerm.toLocaleLowerCase());
                    case SearchBehavior.searchWithStartsWith:
                        return lowerCaseLabel.startsWith(this.searchTerm.toLocaleLowerCase());
                    default:
                        break;
                }
            })
                .slice(0, this.maxCount);
    }
    updateOptions() {
        try {
            if (this.options == null) {
                this.parsedOptions = [];
            }
            else if (typeof this.options === 'string') {
                this.parsedOptions = JSON.parse(this.options);
            }
            else {
                this.parsedOptions = this.options;
            }
        }
        catch (error) {
            this.parsedOptions = [];
        }
    }
    updateInGroupDidChange() {
        applyInputgroupStyle(this.inGroup, this.hostElement);
    }
    static get is() { return "edel-input-select"; }
    static get properties() { return {
        "autofocus": {
            "type": Boolean,
            "attr": "autofocus"
        },
        "disabled": {
            "type": Boolean,
            "attr": "disabled"
        },
        "dropdownReference": {
            "state": true
        },
        "hostElement": {
            "elementRef": true
        },
        "inGroup": {
            "type": Boolean,
            "attr": "in-group",
            "watchCallbacks": ["updateInGroupDidChange"]
        },
        "inline": {
            "type": Boolean,
            "attr": "inline"
        },
        "isOpen": {
            "state": true
        },
        "maxCount": {
            "type": Number,
            "attr": "max-count"
        },
        "options": {
            "type": String,
            "attr": "options",
            "watchCallbacks": ["updateOptions"]
        },
        "parsedOptions": {
            "state": true
        },
        "placeholder": {
            "type": String,
            "attr": "placeholder"
        },
        "search": {
            "type": Boolean,
            "attr": "search"
        },
        "searchBehavior": {
            "type": String,
            "attr": "search-behavior"
        },
        "searchTerm": {
            "state": true
        },
        "selectedOptions": {
            "state": true
        },
        "value": {
            "type": String,
            "attr": "value",
            "mutable": true
        }
    }; }
    static get events() { return [{
            "name": "valueChange",
            "method": "valueChange",
            "bubbles": true,
            "cancelable": true,
            "composed": true
        }]; }
}
