<!-- 吸附过滤器组件 -->

<script setup lang="ts">
    import type { Option, OptionItem } from './types'
    import { deepMerge } from '@/utils'

    const props = defineProps({
        // 是否显示
        show: {
            type: Boolean,
            default: true,
        },
        // 布局
        layout: {
            type: String,
            default: 'horizontal',
        },
        // 风格
        style: {
            type: String,
            default: 'button',
        },
        // 距离顶部的距离
        top: {
            type: Number,
            default: 125,
        },
        // 距离左侧的距离
        left: {
            type: Number,
            default: 30,
        },
        // 选项
        options: {
            type: Array as PropType<Option[]>,
            default: () => [],
        },
    })

    const emits = defineEmits(['register'])

    const positionTop = computed(() => `${data.top}rpx`)
    const positionLeft = computed(() => `${data.left}rpx`)
    const data = reactive({
        show: props.show,
        layout: props.layout,
        style: props.style,
        top: props.top,
        left: props.left,
        options: props.options,
    })

    function toggleShow(show?: boolean) {
        data.show = show ?? !data.show
    }

    function setProps(value: Partial<typeof props>) {
        deepMerge(data, value)
    }

    function getProp(key: keyof typeof props) {
        return data[key]
    }

    function setOptionItems(key: string, items: OptionItem[]) {
        data.options = data.options.map((option) => {
            if (option.key === key) {
                option.items = items
            }
            return option
        })
    }

    function setOptionItemChecked(key: string, value: string) {
        data.options = data.options.map((option) => {
            if (option.key === key) {
                option.items = option.items.map((item) => {
                    item.checked = item.value === value
                    return item
                })
            }
            return option
        })
    }

    const zIndex = computed(() => (model.show ? 200 : 110))
    const model = reactive({
        show: false,
        activeOption: null as Option | null,
    })
    function optionClick(option: Option) {
        console.log(option)

        model.activeOption = option
        model.show = true
    }

    function getItemLabel(option: Option) {
        return option.items.find((item) => item.checked)?.text ?? option.placeholder
    }
    function optionChange(e: { text: string; value: string }) {
        const currentOptionChecked = model.activeOption?.items.find((item) => item.checked)
        data.options = data.options.map((option) => {
            if (option.key === model.activeOption?.key) {
                option.items = option.items.map((item) => {
                    item.checked = item.value === e.value
                    return item
                })
            }
            return option
        })

        // 判断是否真的发生了变化
        if (
            currentOptionChecked?.value !==
            data.options.find((option) => option.key === model.activeOption?.key)?.items.find((item) => item.checked)
                ?.value
        ) {
            model.activeOption?.onChange?.(
                {
                    key: model.activeOption.key,
                    value: toRaw(model.activeOption.items.find((item) => item.checked)),
                },
                data.options.map((option) => {
                    return {
                        key: option.key,
                        value: toRaw(option.items.find((item) => item.checked)),
                    }
                }),
            )
        }

        closePicker()
    }
    function closePicker() {
        model.activeOption = null
        model.show = false
    }

    emits('register', {
        setProps,
        getProp,
        toggleShow,
        setOptionItems,
        setOptionItemChecked,
    })
</script>

<template>
    <view class="wrap affix-filter" :class="[data.layout, data.style]">
        <!--  -->
        <view class="filter-item flex-center" v-for="option in data.options" :key="option.key">
            <view class="fui-filter__item flex-center" @tap="optionClick(option)">
                <text>{{ getItemLabel(option) }}</text>
                <view class="ml-10rpx icon" :class="{ open: model.activeOption?.key === option.key }">
                    <fui-icon name="turningdown" :size="32" color="#999" />
                </view>
            </view>
        </view>

        <!-- 复用选择器 -->
        <fui-picker
            linkage
            :options="model.activeOption?.items"
            :show="model.show"
            @change="optionChange"
            @cancel="closePicker"
        />
    </view>
</template>

<style lang="scss" scoped>
    @import '../../common.scss';

    .affix-filter {
        display: flex;
        box-sizing: border-box;
        position: absolute;
        top: v-bind(positionTop);
        left: v-bind(positionLeft);
        z-index: v-bind(zIndex);

        &.vertical {
            flex-direction: column;

            .filter-item + .filter-item {
                margin-top: 30rpx;
            }
        }

        &.horizontal {
            .filter-item + .filter-item {
                margin-left: 30rpx;
            }
        }

        &.bar {
            width: 100%;
            background-color: white;
            left: 0;
            padding: 10rpx 30rpx;

            .filter-item {
                flex: 1;
                box-shadow: none !important;
            }
        }

        .filter-item {
            background-color: white;
            padding: 15rpx 30rpx;
            font-size: 28rpx;
            color: #333;
            border-radius: 10rpx;
            box-shadow: 0 0 15rpx rgba(0, 0, 0, 0.1);

            .icon {
                @include animate();
                transform: rotate(0deg);

                &.open {
                    transform: rotate(180deg);
                }
            }
        }
    }
</style>
