<template>
    <div class="search-common-container">
        <!-- 左侧已选择内容 -->
        <div class="left-choose">
            <template v-for="(item, index) in chooseList" :key="index">
                <div class="choose-item" @click.stop="editItem(item, index)">
                    <span>{{ item.label + '：' + (item.objKey ? item.objKey : item.value) }}</span>
                    <el-icon class="el-icon-close" @click.stop="deleteChoose(index)">
                        <Close />
                    </el-icon>
                </div>
            </template>
            <!-- 中间label项 -->
            <div v-if="chooseActive" class="center-label">
                {{ chooseActive + ':' }}
            </div>
            <!-- 右侧选择框 -->
            <div ref="inputCont" class="input-cont" @click="clickInput">
                <el-cascader
                    ref="cascaderRef"
                    :options="cascaderOptionList"
                    :props="{ checkStrictly: true }"
                    clearable
                    filterable
                    popper-class="cascader-dialog"
                />
                <el-input
                    ref="inputRef"
                    v-model="inputVal"
                    :placeholder="placeholder"
                    @blur="closeInput"
                    @input="inputHandel"
                    @keyup.delete="deleteHandel"
                    @keyup.enter="closeInput"
                />
            </div>
        </div>
        <div class="right-btn">
            <!-- 右侧删除按钮 -->
            <div v-if="chooseList.length || chooseActive" class="delete-all">
                <el-icon class="el-icon-delete" @click="resetSearch"><Delete /></el-icon>
            </div>
            <!-- 右侧搜索按钮 -->
            <div class="search-btn">
                <el-icon class="el-icon-search" @click="emitHandel"><Search /></el-icon>
            </div>
        </div>
        <!-- 搜索下拉框 -->
        <div v-show="showSelect && allList.length" ref="selectCont" class="select-content">
            <div
                v-for="(item, index) in allList"
                :key="index"
                class="select-item"
                @click="clickSelect(item)"
            >
                {{ item.title }}
            </div>
        </div>
        <!-- 下拉选择框 -->
        <div v-show="showPullContent" ref="pullCont" class="pull-content">
            <div class="pull-search">
                <el-input v-model="pullInputValue" placeholder="搜索">
                    <template #append>
                        <el-icon @click="searchSele"><Search /></el-icon>
                    </template>
                </el-input>
            </div>
            <div class="pull-main">
                <div v-if="showPull" class="pull-list">
                    <div
                        v-for="(item, index) in pullOptionList.filter((it) => it.show)"
                        :key="index"
                        :class="['pull-item', item.checkbox ? 'pull-active' : '']"
                        @click="itemClickHandler(item)"
                    >
                        <el-checkbox
                            v-if="currentSelectOption.multiple !== false"
                            v-model="item.checkbox"
                            @change="() => $forceUpdate()"
                        />
                        <span>{{ item.name }}</span>
                    </div>
                </div>
                <div v-else class="no-data">
                    <img :src="noDataImage" />
                    <span>暂无数据</span>
                </div>
            </div>
            <div v-if="currentSelectOption.multiple !== false" class="pull-footer">
                <span class="footer-item" @click="closePull">取消</span>
                <span class="footer-item" @click="handelPull">确定</span>
            </div>
        </div>
    </div>
</template>

<script lang="ts" setup name="CommonSearch">
import { ref, computed, watch, onMounted } from 'vue'
import noDataImage from '@/assets/img/common/no-data.svg'
const props = defineProps({
    optionList: {
        type: Array,
        default: () => []
    }
})

const emit = defineEmits(['search', 'update:optionList', 'change'])

interface Option {
    title: string
    value: string
    prop: string
    default: boolean
    defalutValue: any
    type: string
    options: Array<{ name: string; value: string }>
    placeholder: string
    [key: string]: any
}
interface ChooseItem {
    label: string
    value: string | number | Array<string | number>
    prop: string
    objKey: any
    [key: string]: any
}
// 状态定义
const chooseList = ref<ChooseItem[]>([])
const allList = ref<Option[]>([])
const showSelect = ref(false)
const showPullContent = ref(false)
const searchValue = ref('')
const selectCont = ref(null)
const pullCont = ref(null)
const defaultOption = ref<Option>({} as Option)
const placeholder = ref('')
const chooseActive = ref('')
const cascaderOptionList = ref<any[]>([])
const inputVal = ref('')
const inputRef = ref<any>(null)
const cascaderRef = ref<any>(null)
const chooseProp = ref('')
const chooseType = ref('')
const inputCont = ref(null)
const currentSelectOption = ref<any>({})
const pullOptionList = ref<any[]>([])
const pullInputValue = ref('')

const showPull = computed(() => {
    console.log(pullOptionList.value)
    return pullOptionList.value.filter((it) => it.show).length
})

// 初始化
onMounted(() => {
    let hasInitialValue = false
    allList.value = props.optionList as Option[]
    ;(props.optionList as Option[]).forEach((item) => {
        if (item.default) {
            defaultOption.value = item
            placeholder.value = `请输入${item.title}，或选择其他查询项来搜索`
        }
        if (item.defalutValue !== undefined) {
            chooseList.value.push({
                label: item.title,
                value: item.defalutValue,
                prop: item.prop,
                objKey:
                    item.type === 'select'
                        ? item.options
                              .filter((option: any) => item.defalutValue.includes(option.value))
                              .map((option: any) => option.name)
                              .join(', ')
                        : undefined
            })

            hasInitialValue = true
            placeholder.value = ''
        }
    })
    if (hasInitialValue) {
        emitHandel()
    }
})

// 方法定义
const filterateData = () => {
    // 过滤数据逻辑
    allList.value = []
    ;(props.optionList as Option[]).forEach((it: Option) => {
        let isBoolen = true
        chooseList.value.forEach((item) => {
            if (item.label === it.title) {
                isBoolen = false
            }
        })
        if (isBoolen) {
            allList.value.push(it)
        }
    })
}

const clickSelect = (item: Option) => {
    // 点击选择逻辑
    chooseActive.value = item.title
    chooseProp.value = item.prop
    placeholder.value = ''
    inputRef.value?.focus()
    chooseType.value = item.type || ''
    currentSelectOption.value = item
    if (item.type === 'select') {
        pullOptionList.value = item.options
        pullOptionList.value.forEach((it: any) => {
            it.show = true
            it.checkbox = false
        })
        showPullContent.value = true
        setSelect(pullCont)
    }
    if (item.type === 'cascader') {
        cascaderOptionList.value = item.options
        // 获取 el-cascader 组件的输入框元素
        const inputElement = cascaderRef.value
        // 创建并触发一个点击事件
        const clickEvent = new MouseEvent('click', {
            view: window,
            bubbles: true,
            cancelable: true
        })
        inputElement?.dispatchEvent(clickEvent)
    }
}

const clickInput = () => {
    filterateData()
    if (!chooseActive.value) {
        setSelect(selectCont)
        showSelect.value = !showSelect.value
    }
    if (chooseType.value === 'select') {
        showPullContent.value = !showPullContent.value
    }
    if (chooseType.value === 'cascader') {
        const inputElement = cascaderRef.value
        // 创建并触发一个点击事件
        const clickEvent = new MouseEvent('click', {
            view: window,
            bubbles: true,
            cancelable: true
        })
        inputElement?.dispatchEvent(clickEvent)
    }
}

const deleteChoose = (index: number | string, isEmitHandel = true) => {
    if (index === 'all') {
        chooseList.value = []
        chooseActive.value = ''
        showPullContent.value = false
        chooseType.value = ''
    } else {
        chooseList.value.splice(Number(index), 1)
    }
    if (!chooseList.value.length) {
        placeholder.value = `请输入${defaultOption.value.title}，或选择其他查询项来搜索`
    }
    if (isEmitHandel) emitHandel()
}

const setSelect = (refDom) => {
    // 设置选择逻辑
    let inputDom = inputCont.value
    // 选择框dom
    let selectDom = refDom.value
    let left = inputDom?.getBoundingClientRect().left + 6
    let top = inputDom?.getBoundingClientRect().top + 36
    // 设置选择框的位置
    selectDom.style.top = top + 'px'
    selectDom.style.left = left + 'px'
}

const closeInput = () => {
    // 关闭输入框逻辑
    setTimeout(() => {
        if (inputVal.value) {
            let label = chooseActive.value ? chooseActive.value : defaultOption.value?.title || ''
            let prop = chooseProp.value ? chooseProp.value : defaultOption.value?.prop || ''
            chooseList.value.push({
                label: label,
                value: inputVal.value,
                prop: prop,
                objKey: undefined
            })
            inputVal.value = ''
            placeholder.value = ''
            chooseActive.value = ''
            if (!showSelect.value) emitHandel()
        }
        showSelect.value = false
    }, 150)
}

const inputHandel = () => {
    // 输入处理逻辑
    if ((chooseList.value.length && !chooseActive.value) || chooseType.value === 'select') {
        inputVal.value = ''
    } else {
        showSelect.value = false
    }
}
const deleteHandel = () => {
    if (!inputVal.value && !showPullContent.value) {
        chooseActive.value = ''
        chooseProp.value = ''
        showPullContent.value = false
        chooseType.value = ''
        if (chooseList.value.length) {
            showPullContent.value = false
            chooseType.value = ''
        }
        if (!chooseList.value.length) {
            placeholder.value = `请输入${defaultOption.value.title}，或选择其他查询项来搜索`
        }
        inputRef.value?.blur()
        emitHandel()
    }
}

const closePull = () => {
    showPullContent.value = false
}

const handelPull = () => {
    let value, objKey
    if (currentSelectOption.value.multiple !== false) {
        value = pullOptionList.value.flatMap((it) => (it.checkbox ? it.value : []))
        objKey = pullOptionList.value.flatMap((it) => (it.checkbox ? it.name : []))
        if (!value.length) return
    } else {
        const selected = pullOptionList.value.find((it) => it.checkbox)
        if (!selected) return
        value = selected.value
        objKey = selected.name
    }
    chooseList.value.push({
        label: chooseActive.value,
        value: value,
        prop: chooseProp.value,
        objKey: objKey
    })
    pullOptionList.value.forEach((it) => (it.checkbox = false))
    showPullContent.value = false
    chooseActive.value = ''
    chooseType.value = ''
    inputRef.value?.blur()
    pullInputValue.value = ''
    emitHandel()
}

const searchSele = () => {
    pullOptionList.value.forEach((it) => {
        if (it.name.indexOf(pullInputValue.value) > -1) {
            it.show = true
        } else {
            it.show = false
        }
    })
}

// 右侧搜索按钮点击
const emitHandel = () => {
    setTimeout(() => {
        emit(
            'search',
            (props.optionList as Option[]).map((i: Option) => {
                const { prop = '', title: label = '', isNumberValue = false } = i
                let value =
                    chooseList.value.find((_i) => JSON.stringify(_i.prop) === JSON.stringify(prop))
                        ?.value || ''
                if (isNumberValue) {
                    if (Array.isArray(value)) {
                        value = value.map((_i) => +_i)
                    } else {
                        value = +value
                    }
                }
                return {
                    prop,
                    label,
                    value
                }
            })
        )
    }, 200)
}

const editItem = (item, index) => {
    // 编辑项目逻辑
    chooseList.value.splice(index, 1)
    let obj = {}
    optionList.value.forEach((it) => {
        if (it.prop === item.prop) {
            obj = it
        }
    })
    chooseActive.value = obj.title
    chooseProp.value = obj.prop
    inputVal.value = item.value
    placeholder.value = ''
    inputRef.value?.focus()
    chooseType.value = obj.type || ''
    currentSelectOption.value = obj
    if (obj.type === 'select') {
        inputVal.value = ''
        pullOptionList.value = obj.options
        pullOptionList.value.forEach((it) => {
            it.show = true
            if (obj.multiple !== false) {
                item.value.forEach((respon) => {
                    if (it.value === respon) {
                        it.checkbox = true
                    }
                })
            } else {
                if (it.value === item.value) {
                    it.checkbox = true
                }
            }
        })
        showPullContent.value = true
        setSelect(pullCont)
    }
}

const resetSearch = () => {
    deleteChoose('all')
    emitHandel()
}

const itemClickHandler = (item: any) => {
    if (currentSelectOption.value.multiple === false) {
        pullOptionList.value.forEach((it) => {
            it.checkbox = false
        })
        item.checkbox = true
        handelPull()
    }
}

// 查询参数变化，重置选择列表
watch(
    () => props.optionList,
    (newVal) => {
        showSelect.value = false
        showPullContent.value = false
    },
    { deep: true }
)
</script>

<style lang="scss" scoped>
.search-common-container {
    box-sizing: border-box;
    width: 100%;
    min-height: 38px;
    padding: 4px 10px;
    font-size: 14px;
    border: 1px solid var(--theme-search-common-border);
    border-radius: 2px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    transition: 0.3s;
    position: relative;
    background-color: var(--theme-search-common-bg);

    * {
        transition: all 0.2s;
    }

    .left-choose {
        display: flex;
        flex-wrap: wrap;
        row-gap: 5px;
        column-gap: 5px;
        flex: 1;

        .choose-item {
            cursor: pointer;
            position: relative;
            font-size: 13px;
            line-height: 24px;
            padding: 2px 22px 2px 9px;
            border-radius: 2px;
            max-width: 300px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            background: var(--theme-box-color-1);
            color: $color-white;
            border: 1px solid $system-border-color3;
            box-sizing: border-box;

            .el-icon-close {
                position: absolute;
                top: 2px;
                right: 0;
                font-size: 13px;
                padding: 4px;
                cursor: pointer;
                transition: color 0.15s;
                color: $color-text-placeholder;

                &:hover {
                    color: $color-danger;
                }
            }
            &:nth-child(1) {
                margin-left: 0;
            }
        }

        .input-cont {
            flex: 1;
            display: flex;
            align-items: center;
        }
    }

    .center-label {
        font-size: 14px;
        display: flex;
        align-items: center;
        white-space: nowrap;
        margin-left: 10px;
        color: var(--theme-select-title-text);
    }

    &:hover {
        border-color: $system-border-color1;
    }

    .right-btn {
        display: flex;

        .delete-all {
            display: flex;
            align-items: center;
            justify-content: center;
            margin-right: 10px;

            .el-icon-delete {
                font-size: 16px;
                color: $color-text-placeholder;
                cursor: pointer;

                &:hover {
                    color: $color-danger;
                }
            }
        }

        .search-btn {
            width: 20px;
            display: flex;
            padding: 0 0 0 10px;
            justify-content: center;
            align-items: center;
            position: relative;

            .el-icon-search {
                font-size: 16px;
                color: $color-text-placeholder;
                cursor: pointer;

                &:hover {
                    color: $system-hover-active-text;
                }
            }
            &::before {
                content: '';
                position: absolute;
                top: 0;
                left: 0;
                width: 1px;
                height: 16px;
                background-color: $color-text-secondary;
            }
        }
    }

    .select-content {
        min-width: 120px;
        max-height: 320px;
        overflow: auto;
        position: fixed;
        top: 0;
        left: 0;
        z-index: 900;
        background-color: var(--theme-select-title-bg);
        border: 1px solid $system-border-color1;
        animation: slide-in-top 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
        border-radius: 3px;

        .select-item {
            color: var(--theme-select-title-text);
            font-size: 14px;
            height: 22px;
            line-height: 22px;
            padding: 5px 12px;
            transition: 0.3s;
            cursor: pointer;

            &:hover {
                color: $system-hover-active-text;
                // background: var();
            }
        }
    }

    .pull-content {
        min-width: 240px;
        position: fixed;
        top: 0;
        left: 0;
        z-index: 5;
        background: $system-module-color2;
        border: 1px solid $system-border-color1;
        border-radius: 3px;
        animation: slide-in-top 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
        .pull-search {
            position: relative;
            padding: 12px;

            .el-input-group {
                border: 1px solid $system-border-color3;
                border-radius: 5px;

                &:hover {
                    border: 1px solid $system-border-color1;
                }

                .el-icon-search {
                    color: $color-text-placeholder;
                    cursor: pointer;
                }

                :deep(.el-input__inner) {
                    border: none;
                }
            }
        }

        .pull-main {
            max-height: 240px;
            border-bottom: 1px solid $system-border-color3;
            border-top: 1px solid $system-border-color3;
            overflow: auto;

            &::-webkit-scrollbar {
                width: 6px !important;
            }

            /* 滚动条滑块 */
            &::-webkit-scrollbar-thumb {
                border-radius: 6px;
            }

            .pull-list {
                padding: 10px 0;

                .pull-item {
                    height: 34px;
                    font-size: 14px;
                    padding: 0 10px;
                    margin-top: 1px;
                    display: flex;
                    justify-content: flex-start;
                    align-items: center;
                    cursor: pointer;
                    transition: 0.3s;

                    span {
                        margin-left: 6px;
                        vertical-align: middle;
                        font-size: 14px;
                        color: $system-table-text-color;
                    }

                    &:hover {
                        background-color: $system-active-bgColor;
                    }

                    &.pull-active {
                        background-color: $system-active-bgColor;

                        span {
                            color: $system-hover-active-text;
                        }
                    }
                    .el-checkbox {
                        margin-top: 4px;
                    }
                }
            }

            .no-data {
                height: 170px;
                display: flex;
                justify-content: center;
                align-items: center;
                flex-direction: column;

                span {
                    margin-top: 10px;
                }
            }
        }

        .pull-footer {
            padding: 10px;
            display: flex;
            justify-content: space-between;
            align-items: center;

            .footer-item {
                cursor: pointer;
                color: $system-table-text-color;
            }
        }
    }

    @keyframes slide-in-top {
        0% {
            opacity: 0;
            transform: translateY(-10px);
        }
        100% {
            opacity: 1;
            transform: translateY(0);
        }
    }
}

:deep(.el-input__inner) {
    border: 0;
    height: 100%;
    // padding: 0 10px;
    font-size: 14px !important;
}

:deep(.el-input) {
    height: 100%;
}

:deep(.el-checkbox .el-checkbox__input) {
    width: 16px;
    height: 16px;

    &::after {
        border-width: 1px;
        height: 8px;
        left: 5px;
    }
}

:deep(.el-input-group__append) {
    padding: 10px;
    background-color: var(--theme-system-module-1);
    border: none;
    box-shadow: none;
}
:deep(.el-input__wrapper) {
    box-shadow: none !important;
}
:deep(.el-cascader) {
    width: 0;
    height: 22px;
    opacity: 0;
    pointer-events: none;
    animation: none !important;

    .el-input__inner {
        height: 22px;
        line-height: 22px;
    }

    .el-input__suffix {
        display: none;
    }

    .el-icon-arrow-down {
        display: none;
    }

    .el-input__suffix-inner {
        display: none;
    }

    .el-cascader-menu {
        min-width: 120px;
    }
}
:deep(.el-input--large .el-input__wrapper) {
    padding: 1px 6px;
}
</style>

<style lang="scss">
.cascader-dialog {
    animation: none !important;

    .popper__arrow {
        display: none !important;
    }
}
</style>
