<!-- 顶部时间栏 Bar 组件 -->

<script setup lang="ts">
    import type { Dayjs } from 'dayjs'
    import dayjs from 'dayjs'
    import type { TimeBarButton, TimeBarLabel, TimeBarTime } from './types'
    import { formatTime, isAfter, isBefore } from './hook'
    import { deepMerge } from '@/utils'

    const props = defineProps({
        // 是否显示
        show: {
            type: Boolean,
            default: true,
        },
        // 是否只读
        readonly: {
            type: Boolean,
            default: false,
        },
        // 对齐方式
        align: {
            type: String,
            default: 'left',
        },
        // 标签
        label: {
            type: Object as PropType<TimeBarLabel>,
            default: () =>
                ({
                    text: '时间',
                }) as TimeBarLabel,
        },
        // 时间
        time: {
            type: Object as PropType<TimeBarTime>,
            default: () => ({}) as TimeBarTime,
        },
        // 最小时间
        minTime: {
            type: Object as PropType<Dayjs>,
        },
        // 最大时间
        maxTime: {
            type: Object as PropType<Dayjs>,
        },
        // 扩展按钮
        buttons: {
            type: Array as PropType<TimeBarButton[]>,
            default: () => [] as TimeBarButton[],
        },
    })

    const emits = defineEmits(['register'])

    const data = reactive({
        show: props.show,
        readonly: props.readonly,
        align: props.align,
        label: props.label,
        time: props.time,
        minTime: props.minTime,
        maxTime: props.maxTime,
        buttons: props.buttons,
    })

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

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

        // if (!data?.time?.value) {
        //     const time = dayjs()
        //     data.time.value = data.time.type === 'range' ? [time.subtract(1, 'days'), time] : [time]
        // }
    }

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

    function getTime(): Dayjs[] {
        return toRaw(data.time.value)
    }

    function setTime(value: Dayjs[]) {
        data.time.value = value
    }

    function getCheckedOption() {
        return toRaw(checkedLabelOption.value)
    }

    function setCheckedOption(index: number) {
        onLabelOptionChange((_, i) => i === index)
    }

    function getTimeBarValue() {
        return {
            option: getCheckedOption(),
            value: getTime(),
        }
    }

    const labelText = computed(() => checkedLabelOption.value?.text || data.label.text || '')
    const timePickerType = computed(() => checkedLabelOption.value?.timeType || data.time?.timeType || 3)
    const timeText = computed(() => {
        const format = checkedLabelOption.value?.format || data.time?.format
        return data.time?.value?.map((item) => dayjs(item).format(format)).join(' - ') || ''
    })

    // ================== Option 下拉选择相关开始 ===================
    const dropdownMenu = ref(null)
    const showDropdownMenu = ref(false)
    const checkedLabelOption = computed(() => data.label?.options?.find((option) => option.checked) || {})
    function changeLabelOption(option: TimeBarLabel['options'][0]) {
        showDropdownMenu.value = false
        onLabelOptionChange((item) => item.value === option.value)
    }
    function onLabelOptionChange(cb: (e: TimeBarLabel['options'][0], i: number) => boolean) {
        data.label.options.forEach((item, index) => {
            item.checked = cb(item, index)
            if (item.checked) {
                data.label?.onChange?.(getTimeBarValue())
            }
        })
    }
    function openDropdownMenu() {
        if (data.readonly) {
            return
        }

        showDropdownMenu.value = true
        dropdownMenu.value?.show()
    }
    // ================== Option 下拉选择相关结束 ===================

    // ================== TimePicker 选择相关开始 ===================
    const showTimePicker = ref(false)
    const zIndex = computed(() => (showTimePicker.value ? 200 : 110))
    function changeTime(e: Recordable) {
        if (e.startDate) {
            const [startTime, endTime] = [dayjs(e.startDate.result), dayjs(e.endDate.result)]
            if (isAfter(endTime, data.maxTime)) {
                Message.toast('结束时间不能大于最大时间')
            } else if (isBefore(startTime, data.minTime)) {
                Message.toast('开始时间不能小于最小时间')
            } else {
                data.time.value = [startTime, endTime]
            }
        } else {
            const [startTime] = [dayjs(e.result)]
            if (isAfter(startTime, data.maxTime)) {
                Message.toast('时间不能大于最大时间')
            } else if (isBefore(startTime, data.minTime)) {
                Message.toast('时间不能小于最小时间')
            } else {
                data.time.value = [startTime]
            }
        }
        showTimePicker.value = false
    }
    function openTimePicker() {
        if (!data.readonly) {
            showTimePicker.value = true
        }
    }
    watch(
        () => data.time.value,
        () => data.time.onChange?.(getTimeBarValue()),
    )
    // ================== TimePicker 选择相关结束 ===================

    emits('register', {
        setProps,
        getProp,
        toggleShow,
        getTime,
        setTime,
        getCheckedOption,
        setCheckedOption,
        getTimeBarValue,
    })
</script>

<template>
    <view class="wrap time-bar" :class="[data.align]" v-show="data.show">
        <view class="label">
            <Icon
                icon="ic-outline-access-time"
                size="36"
                color="#333"
                class="icon"
                v-if="data.label.breforeIcon !== false"
            />
            <template v-if="data.label.options?.length">
                <fui-dropdown-menu
                    :size="28"
                    selectedColor="#465CFF"
                    :options="data.label.options"
                    @click="changeLabelOption"
                    @close="showDropdownMenu = false"
                    ref="dropdownMenu"
                >
                    <view class="fui-filter__item flex-center" @tap="openDropdownMenu">
                        <text>{{ checkedLabelOption.text }}</text>
                        <view class="fui-filter__icon" :class="{ 'fui-icon__ani': showDropdownMenu }">
                            <fui-icon name="turningdown" :size="32" />
                        </view>
                    </view>
                </fui-dropdown-menu>
            </template>
            <template v-else>
                <view class="text after">{{ labelText }}</view>
            </template>
        </view>

        <view class="flex flex-auto justify-between items-center h-55rpx">
            <view class="time-wrap" :class="{ left: data.buttons?.length }" @tap="openTimePicker">
                <view class="time flex items-center" :class="{ readonly: data.readonly }">{{ timeText }}</view>
                <Icon icon="ic-baseline-keyboard-arrow-right" size="46" color="#666" v-if="!data.readonly" />
            </view>

            <view class="buttons" v-if="data.buttons?.length">
                <!--  -->
                <fui-button
                    bold
                    :size="24"
                    width="130rpx"
                    height="55rpx"
                    radius="8rpx"
                    color="#1890FF"
                    background="#E7F3FF"
                    v-for="(button, index) in data.buttons"
                    :key="`time_bar_button_${index}`"
                    @tap="button.onClick?.({ index, label: button.label }, getTimeBarValue())"
                >
                    <fui-icon
                        v-if="button.icon"
                        :name="button.icon"
                        :size="28"
                        style="color: #1890ff !important; margin-right: 6rpx"
                    />
                    <text>{{ button.label }}</text>
                    <Icon icon="ic-baseline-keyboard-arrow-right" size="32" color="#666" />
                </fui-button>
            </view>
        </view>

        <!-- 时间选择组件 -->
        <fui-date-picker
            start="开始时间"
            end="结束时间"
            :range="data.time.type === 'range'"
            :show="showTimePicker"
            :type="timePickerType"
            :value="formatTime(data.time?.value?.[0])"
            :valueEnd="formatTime(data.time?.value?.[1])"
            :minDate="formatTime(data.minTime)"
            :maxDate="formatTime(data.maxTime)"
            @change="changeTime"
            @cancel="showTimePicker = false"
        />
    </view>
</template>

<style lang="scss" scoped>
    @use '../../common.scss' as *;

    .wrap {
        @include animate();

        position: absolute;
        top: 0;
        left: 0;
        // 层级需要比其他 widget 高，否则 picker 会被遮挡
        z-index: v-bind(zIndex);
        background-color: white;
    }

    .time-bar {
        padding: 20rpx;
        box-sizing: border-box;
        width: 100%;
        display: flex;
        align-items: center;
        font-size: 28rpx;
        // box-shadow: 0 0 15rpx rgba(0, 0, 0, 0.1);

        &.center {
            justify-content: center;
        }

        > .label {
            display: flex;
            align-items: center;
            font-size: 28rpx;
            color: #333;

            .icon {
                margin-right: 6rpx;
            }

            .text {
                margin-right: 2rpx;

                &.after::after {
                    content: '：';
                }
            }

            .fui-filter__item {
                /* #ifdef H5 */
                cursor: pointer;
                /* #endif */
                background-color: #fff;
                margin-right: 6rpx;
            }

            .fui-filter__icon {
                transition: all 0.15s linear;
                margin-left: 5rpx;
            }

            .fui-icon__ani {
                transform: rotate(180deg);
            }

            :deep(.fui-dropdown__menu-list) {
                width: 230rpx;
            }
        }

        .time-wrap {
            display: flex;
            justify-content: space-between;
            flex: auto;

            &.left {
                justify-content: flex-start;
                flex: none;

                .time {
                    max-width: 350rpx;
                }
            }

            .time {
                white-space: nowrap;
                overflow: hidden;
                text-overflow: ellipsis;
                color: #1890ff;

                &.readonly {
                    color: #666;
                }
            }
        }
    }
</style>
