<template>
    <div class="Cascader">
        <q-select
            ref="selectRef"
            filled
            :label="label"
            :option-value="optionValue"
            :option-label="optionLabel"
            :options="multiple ? options : flatOptions"
            v-model="check"
            clearable
            emit-value
            map-options
            :multiple="multiple"
            popup-content-class="option_box"
            @clear="clear"
        >
            <template #selected v-if="multiple">
                <div class="tag" v-if="checkBoxLabel.length > 0">{{ checkBoxLabel[0] }}</div>
                <div class="tag" v-if="checkBoxLabel.length > 1">+{{ checkBoxLabel.length - 1 }}</div>
            </template>
            <template #before-options>
                <div class="flex no-wrap before-options-box">
                    <div class="child_box">
                        <div
                            v-for="(_item,_index) in options"
                            :key="_index"
                            class="flex justify-between items-center"
                        >
                            <q-radio
                                v-model="radio"
                                :val="_item[optionValue]"
                                :label="_item[optionLabel]"
                                v-if="!multiple"
                                @click.stop="getChild(_index)"
                            />
                            <q-checkbox
                                v-model="checkbox"
                                :val="_item[optionValue]"
                                :label="_item[optionLabel]"
                                indeterminate-value
                                v-if="multiple"
                                @mouseenter.stop="getChild(_index)"
                                @update:model-value="getLabel($event, _item[optionLabel], _item[optionValue])"
                            />
                            <q-icon
                                name="chevron_right"
                                v-if="_item[optionChildren] && _item[optionChildren].length > 0"
                            />
                        </div>
                    </div>
                    <div class="child_box" v-if="childrenList && childrenList.length > 0">
                        <div
                            v-for="(_item,_index) in childrenList"
                            :key="_index"
                            class="flex justify-between items-center"
                        >
                            <q-radio
                                v-model="radio"
                                :val="_item[optionValue]"
                                :label="_item[optionLabel]"
                                v-if="!multiple"
                                @click.stop="getChild2(_index)"
                            />
                            <q-checkbox
                                v-model="checkbox"
                                :val="_item[optionValue]"
                                :label="_item[optionLabel]"
                                v-if="multiple"
                                indeterminate-value
                                @mouseenter.stop="getChild2(_index)"
                                @update:model-value="getLabel($event, _item[optionLabel], _item[optionValue])"
                            />
                            <q-icon
                                name="chevron_right"
                                v-if="_item[optionChildren] && _item[optionChildren].length > 0"
                            />
                        </div>
                    </div>
                    <div class="child_box" v-if="childrenList2 && childrenList2.length > 0">
                        <div
                            v-for="(_item,_index) in childrenList2"
                            :key="_index"
                            class="flex justify-between items-center"
                        >
                            <q-radio
                                v-model="radio"
                                :val="_item[optionValue]"
                                :label="_item[optionLabel]"
                                v-if="!multiple"
                                @click.stop="getChild3(_index)"
                            />
                            <q-checkbox
                                v-model="checkbox"
                                :val="_item[optionValue]"
                                :label="_item[optionLabel]"
                                v-if="multiple"
                                indeterminate-value
                                @mouseenter.stop="getChild3(_index)"
                                @update:model-value="getLabel($event, _item[optionLabel], _item[optionValue])"
                            />
                            <q-icon
                                name="chevron_right"
                                v-if="_item[optionChildren] && _item[optionChildren].length > 0"
                            />
                        </div>
                    </div>
                    <div class="child_box" v-if="childrenList3 && childrenList3.length > 0">
                        <div
                            v-for="(_item,_index) in childrenList3"
                            :key="_index"
                            class="flex justify-between items-center"
                        >
                            <q-radio
                                v-model="radio"
                                :val="_item[optionValue]"
                                :label="_item[optionLabel]"
                                v-if="!multiple"
                            />
                            <q-checkbox
                                v-model="checkbox"
                                :val="_item[optionValue]"
                                :label="_item[optionLabel]"
                                v-if="multiple"
                                indeterminate-value
                                @update:model-value="getLabel($event, _item[optionLabel], _item[optionValue])"
                            />
                            <q-icon
                                name="chevron_right"
                                v-if="_item[optionChildren] && _item[optionChildren].length > 0"
                            />
                        </div>
                    </div>
                </div>
            </template>
            <template #option>
                <div style="display:none"></div>
            </template>
        </q-select>
    </div>
</template>
<script lang="ts">
import {
    ref, watch
} from 'vue'

export default {
    props: {
        multiple: {
            type: Boolean,
            default: false
        },
        options: {
            type: Array,
            default: () => []
        },
        optionLabel: {
            type: String,
            default: 'label'
        },
        optionValue: {
            type: String,
            default: 'Id'
        },
        optionChildren: {
            type: String,
            default: 'children'
        },
        label: {
            type: String,
            default: "请选择"
        }
    },
    // 
    setup(props) {
        const selectRef = ref<any>(null)
        let flatOptions = ref<any>([{}])
        const flat = (arr: any) => {
            arr.map(e => {
                flatOptions.value.push(e)
                if (e[props.optionChildren] && e[props.optionChildren].length > 0) {
                    flat(e[props.optionChildren])
                }
            })
        }
        let radio = ref("")
        let checkbox = ref<any>([])
        let check = ref<Array<any> | string>("")
        let checkBoxLabel = ref<Array<any>>([])
        let childrenList = ref([])
        let childrenList2 = ref([])
        let childrenList3 = ref([])
        watch(() => props.options, () => {
            flat(props.options)
            console.log('flatOptions', flatOptions.value)
        })
        watch(() => radio.value, (val) => {
            check.value = val
            console.log('单选', val)
        })
        watch(() => [...checkbox.value], (val) => {
            check.value = val
            selectArray.value = []
            console.log('多选2', checkbox.value)
        })
        const getChild = (index) => {
            childrenList.value = props.options[index][props.optionChildren]
            childrenList2.value = []
        }
        const getChild2 = (index) => {
            childrenList2.value = childrenList.value[index][props.optionChildren]
            childrenList3.value = []
        }
        const getChild3 = (index) => {
            childrenList3.value = childrenList2.value[index][props.optionChildren]
        }
        const getLabel = (val, label, curVal) => {
            const index = val.indexOf(curVal)
            if (index > -1) {
                checkBoxLabel.value.push(label)
            } else {
                const labelIndex = checkBoxLabel.value.indexOf(label)
                if (labelIndex > -1) {
                    checkBoxLabel.value.splice(labelIndex, 1)
                }
            }
            console.log(228,  label, curVal)
            getselectArray(props.options, curVal)


        }

        const clear = () => {
            checkBoxLabel.value = []
            if (props.multiple) {
                checkbox.value = []
            } else {
                radio.value = ""
            }
        }
        //处理选中框-------------
        let selectArray = ref<Array<any>>([])
        
        const getselectArray = (arr: any[], checkVal) => {
            const index = checkbox.value.indexOf(checkVal)
            //父级id数组
            arr.map(e => {
                const child = e[props.optionChildren]
                if (checkVal == e[props.optionValue]) {
                    if (index > -1) {
                        mapChildAdd(child)
                    } else {
                        mapChildDel(child)
                    }
                } else {
                    getselectArray(child, checkVal)
                }
                if(child.length>0){
                     //处理父级
                    mapfather(child, e[props.optionValue],checkVal)
                }
            })
        }
        const mapChildAdd = (arr: any[]) => {
            arr.map(e => {
                const index = checkbox.value.indexOf(e[props.optionValue])
                if (index == -1) {
                    checkbox.value.push(e[props.optionValue])
                }
                const child = e[props.optionChildren]
                if (child.length > 0) {
                    mapChildAdd(child)
                }
            })
        }
        const mapChildDel = (arr: any[]) => {
            arr.map(e => {
                const delIndex = checkbox.value.indexOf(e[props.optionValue])
                checkbox.value.splice(delIndex, 1)
                const child = e[props.optionChildren]
                if (child.length > 0) {
                    mapChildDel(child)
                }
            })
        }
        const mapfather = (arr: any[], faId,checkVal) => {
           
            //  判断自己是否选中
             const self = checkbox.value.indexOf(checkVal) > -1
             //  判断兄弟节点是否选中
            //  const bro = child.every(e=>.indexOf(checkVal) > -1
             arr.map(e => {
                 
                if (self) {
                      const child = e[props.optionChildren]
                    if (child.length > 0) {
                         faId=faId+','+e[props.optionValue]
                        mapfather(child, faId,checkVal)
                    }

                } else {
                    if(checkVal===e[props.optionValue]){
                         console.log('当前',e[props.optionValue])
                         console.log('Ids',faId.split(','))
                        faId.split(',').map(_e=>{
                            const faIndex = checkbox.value.indexOf(_e)
                            checkbox.value.splice(faIndex,1)
                        })
                    }
                    return
                }
               
            })
        }
        return {
            selectRef,
            radio,
            checkbox,
            check,
            checkBoxLabel,
            childrenList,
            childrenList2,
            childrenList3,
            getChild,
            getChild2,
            getChild3,
            getLabel,
            clear,
            flatOptions,
            selectArray,
            getselectArray,
        }
    }
}

</script>
<style lang="scss" scoped>
.tag {
    border-radius: 2px;
    padding: 2px 4px;
    margin: 0 2px;
    text-overflow: ellipsis;
    background-color: #fff;
    color: #909399;
}
.before-options-box {
    position: sticky;
    top: 0;
    z-index: 10;
}
.child_box {
    min-width: 200px;
    height: 200px !important;
    overflow: scroll;
    border-left: 1px solid #dfe4ed;
}
.option_box {
    height: 200px !important;
    overflow: hidden;
}
</style>