<template>
    <div :class="{ 'show': show }" class="header-search">
        <el-tooltip content="菜单搜索" placement="bottom" effect="light">
            <el-icon @click.stop="click">
                <Search />
            </el-icon>
        </el-tooltip>
        <el-select ref="headerSearchSelect" v-model="search" :remote-method="querySearch" filterable default-first-option
            remote placeholder="Search" class="header-search-select" @change="change">
            <el-option v-for="item in options" :key="item.path" :value="item" :label="item.item.title.join(' > ')" />
        </el-select>
    </div>
</template>
  
<script lang="ts" setup>
import Fuse from 'fuse.js'
import path from 'path-browserify';
import { ref, computed, watch, nextTick } from 'vue'
import { useRouter } from 'vue-router';
import { useRoutesStore } from "@/framework/store/modules/routes";
const routesStore = useRoutesStore();
let router = useRouter()

const search = ref('')
const options = ref([])
const searchPool = ref([])
const show = ref(false)
const fuse = ref({})

const routes = computed(() => {
    return routesStore.routes.filter((item: any) => {
        return item.meta && !item.meta.hidden && item.meta.title && item.children && item.children.length > 0
    })
})

watch(searchPool, (list) => {
    initFuse(list)
})
watch(show, (value) => {
    if (value) {
        document.body.addEventListener('click', close)
    } else {
        document.body.removeEventListener('click', close)
    }
})





const generateRoutes = (routes: any, basePath = '/', prefixTitle = []) => {
    let res: any = []

    for (const router of routes) {
        const data:any = {
            path: path.resolve(basePath, router.path),
            title: [...prefixTitle]
        }

        if (router.meta && router.meta.title) {
            data.title = [...data.title, router.meta.title]
            res.push(data)
        }
        if (router.children) {
            const tempRoutes: any = generateRoutes(router.children, data.path, data.title)
            if (tempRoutes.length >= 1) {
                res = [...res, ...tempRoutes]
            }
        }
    }
    return res
}

searchPool.value = generateRoutes(routes.value)

const initFuse = (list: any) => {
    fuse.value = new Fuse(list, {
        shouldSort: true,
        threshold: 0.4,
        location: 0,
        distance: 100,
        // maxPatternLength: 32,
        minMatchCharLength: 1,
        keys: [{
            name: 'title',
            weight: 0.7
        }, {
            name: 'path',
            weight: 0.3
        }]
    })
}

const headerSearchSelect:any = ref(null)

const click = () => {
    show.value = !show.value
    if (show.value) {
        headerSearchSelect.value && headerSearchSelect.value.focus()
    }
}
const close = () => {
    headerSearchSelect.value && headerSearchSelect.value.blur()
    options.value = []
    show.value = false
}
const change = (val: any) => {
    router .push(val.item.path)
    search.value = ''
    options.value = []
    nextTick(() => {
        show.value = false
    })
}

const querySearch = (query) => {
    if (query !== '') {
        options.value = fuse.value.search(query)
    } else {
        options.value = []
    }
}







</script>
  
<style lang="scss" scoped>
.header-search {
    font-size: 1.3rem;
    margin-right: 32px;
    margin-top: -2px;
    display: flex;
    align-items: center;

    .search-icon {
        cursor: pointer;
        font-size: 18px;
        vertical-align: middle;
    }

    .header-search-select {
        font-size: 18px;
        transition: width 0.2s;
        width: 0;
        overflow: hidden;
        background: transparent;
        border-radius: 0;
        display: inline-block;
        vertical-align: middle;

        .el-input__inner {
            border-radius: 0;
            border: 0;
            padding-left: 0;
            padding-right: 0;
            box-shadow: none !important;
            border-bottom: 1px solid #d9d9d9;
            vertical-align: middle;
        }
    }

    &.show {
        .header-search-select {
            width: 210px;
            margin-left: 10px;
        }
    }
}
</style>
  