<template>
    <div id="searchable-select">
        <div id="ss-modal" @click.self="hideModal" v-if="modalShow">
            <div id="ss-selector">
                <div class="p-2">
                    <input type="text" class="form-control" v-model="q" :placeholder="xtitle">
                </div>
                <div class="p-2">
                    <ul id="vue-search-list" class="list-group list-group-flush">
                        <template v-for="item in items">
                            <li
                                v-if="finder(item[titleField])"
                                @click="selecting(item[valueField])"
                                :class="`list-group-item ${val == item[valueField]?'selected':''}`">
                                <template v-if="xlang == null">
                                    {{ item[titleField] }}
                                </template>
                                <template v-else>
                                    {{ item[titleField]?.[xlang] ?? item[titleField] }}
                                </template>
                            </li>
                        </template>
                    </ul>
                </div>
            </div>
        </div>
        <div class="input-group mb-3">
            <div class="input-group-prepend" id="vue-search-btn" @click="showModal">
                <span class="input-group-text" id="basic-addon1">
                    <i class="ri-search-2-line"></i>
                </span>
            </div>
            <select :id="xid" :class="getClass" v-model="val" @change="select">
                <option value=""> {{ xtitle }}</option>
                <option v-for="item in items"
                        :value="item[valueField]"
                        :selected="item[valueField] == val">
                    <template v-if="xlang == null">
                        {{ item[titleField] }}
                    </template>
                    <template v-else>
                        {{ item[titleField]?.[xlang] ?? item[titleField] }}
                    </template>
                </option>
            </select>
        </div>
    </div>
    <input type="hidden" :name="xname" :value="val">
</template>

<script>
export default {
    name: "searchable-select",
    components: {},
    data: () => {
        return {
            modalShow: false, // modal handle
            q: '', // search query
            val: '',
        }
    },
    emits: ['update:modelValue'],
    props: {
        vuexDispatch:{
          default: null,
        },
        xlang: {
            default: null
        },
        modelValue: {
            default: NaN,
        },
        items: {
            required: true,
            default: [],
            type: Array,
        },
        valueField: {
            default: 'id',
            type: String,
        },
        titleField: {
            default: 'title',
            type: String,
        },
        xname: {
            default: "",
            type: String,
        },
        xtitle: {
            default: "Please select",
            type: String,
        },
        xvalue: {
            default: "",
            type: String,
        },
        xid: {
            default: "",
            type: String,
        },
        customClass: {
            default: "",
            type: String,
        },
        err: {
            default: false,
            type: Boolean,
        },

        onSelect: {
            default: function () {

            },
            type: Function,
        },
        closeOnSelect: {
            default: false,
            type: Boolean,
        },
    },
    mounted() {
        if (!isNaN(this.modelValue)) {
            this.val = this.modelValue;
        } else {
            this.val = this.xvalue;
        }
    },
    computed: {
        getClass: function () {
            if (this.err == true || (typeof this.err == 'String' && this.err.trim() == '1')) {
                return 'form-control is-invalid ' + this.customClass;
            }
            return 'form-control ' + this.customClass;
        },
    },
    methods: {
        finder(term = '') {
            //(q != '' && item[titleField].indexOf(q) != -1) || (q == '')
            if (this.q == '' || term == '') {
                return true;
            }
            if (typeof term == 'string' && term.toLocaleLowerCase().indexOf(this.q.toLocaleLowerCase()) != -1) {
                return true
            } else if (typeof term == 'object') {
                try {
                    for (const t in term) {
                        if (term[t].toLowerCase().indexOf(this.q.toLocaleLowerCase()) != -1) {
                            return true;
                        }
                    }
                } catch (e) {

                    console.log(e.message);
                }
            } else {
                return true;
            }
            return false;
        },
        selecting(i) {
            this.val = i;
            this.onSelect(this.val);
            if (this.closeOnSelect) {
                this.hideModal();
            }
        },
        select() {
            this.onSelect(this.val);
        },
        hideModal: function () {
            this.modalShow = false;
        },
        showModal() {
            this.modalShow = true;
        }
    },
    watch: {
        val(newValue) {
            if (!isNaN(this.modelValue)) {
                this.$emit('update:modelValue', newValue);
            }
            if (this.vuexDispatch != null){
                this.$store.dispatch(this.vuexDispatch, newValue);
            }
        }
    }
}
</script>

<style scoped>
#searchable-select {

}

#vue-search-btn {
    cursor: pointer;
    user-select: none;
}

#vue-search-btn:hover .input-group-text {
    background: darkred;
}


#ss-modal {
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    z-index: 999;
    background: #00000033;
    backdrop-filter: blur(4px);
    user-select: none;
}

#ss-selector {
    height: 60vh;
    border-radius: 7px;
    min-width: 350px;
    width: 400px;
    max-width: 90%;
    margin: 20vh auto;
    background: #ffffff99;
    padding: 5px;
}

#vue-search-list {
    height: calc(60vh - 90px);
    overflow-x: auto;
}

#vue-search-list .list-group-item:hover {
    background: deepskyblue;
}

#vue-search-list .list-group-item.selected {
    background: dodgerblue;
    color: white;;
}
</style>
