<!-- 图例组件 -->

<script setup lang="ts">
    import { isArray } from 'lodash-es'
    import { createReusableTemplate } from '@vueuse/core'
    import type { Option } from './types'

    const props = defineProps({
        // 显示
        show: {
            type: Boolean,
            default: true,
        },
        // 展开
        expand: {
            type: Boolean,
            default: false,
        },
        // 标题
        title: {
            type: String,
            default: '',
        },
        // 底部距离 rpx
        bottom: {
            type: String,
            default: '30rpx',
        },
        // JSON 数据
        option: {
            type: Object as PropType<Option>,
            default: () => ({}),
        },
    })

    const emits = defineEmits(['register'])

    // 定义复用渲染组件
    const [DefineTemplate, ReuseTemplate] = createReusableTemplate<{ item: Recordable; sub?: boolean }>()

    const positionBottom = computed(() => `calc(30rpx + ${data.bottom})`)
    const data = reactive({
        show: props.show,
        expand: props.expand,
        title: props.title,
        option: props.option,
        bottom: props.bottom,
    })

    function setTitle(title: string) {
        data.title = title
    }

    function setOption(option: Option) {
        data.option = option
    }

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

    function toggleExpand(expand?: boolean) {
        data.expand = expand ?? !data.expand
    }

    function setProps(value: Partial<typeof props>) {
        Object.assign(data, value)
    }

    emits('register', {
        setProps,
        setTitle,
        setOption,
        toggleShow,
        toggleExpand,
    })
</script>

<template>
    <view class="wrap legend flex-center" @click="data.expand = !data.expand">
        <!-- 展开/收起 -->
        <view class="expand-action flex-center" v-show="!data.expand">
            <view class="text">图例</view>
            <Icon icon="ic-round-keyboard-arrow-up" color="#1890ff" size="42" />
        </view>

        <!-- 内容 -->
        <view class="expand-content flex-center" v-show="data.expand">
            <!-- 标题 -->
            <view v-if="data.title" class="title">{{ data.title }}</view>

            <!-- 定义复用渲染组件 -->
            <DefineTemplate v-slot="{ item, sub }">
                <view class="item">
                    <!-- 图标 -->
                    <view v-if="item.icon" class="icon flex-center">
                        <CacheImage :src="item.icon" width="34" height="34" background="transparent" />
                    </view>

                    <!-- 色块 -->
                    <view
                        v-if="item.color"
                        class="color"
                        :style="{ backgroundColor: item.color, ...data.option.blockStyle }"
                    />

                    <!-- 标签 -->
                    <view v-if="item.label" class="label" :style="!sub && { ...data.option.labelStyle }">
                        {{ item.label }}
                    </view>

                    <!-- 子项集合 -->
                    <view v-if="item.items" class="sub-items">
                        <view v-for="(subItem, index) in item.items" :key="index" class="item">
                            <ReuseTemplate :item="subItem" :sub="true" />
                        </view>
                    </view>
                </view>
            </DefineTemplate>

            <!-- JSON -->
            <view class="option">
                <template v-if="isArray(data.option.items?.[0])">
                    <view v-for="(item, index) in data.option.items" :key="index" class="item-wrap">
                        <view v-for="(subItem, subIndex) in item" :key="subIndex" class="items">
                            <ReuseTemplate :item="subItem" />
                        </view>
                    </view>
                </template>

                <template v-else>
                    <view class="item-wrap">
                        <view v-for="(item, index) in data.option.items" :key="index" class="items">
                            <ReuseTemplate :item="item" />
                        </view>
                    </view>
                </template>
            </view>
        </view>
    </view>
</template>

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

    .wrap {
        @include animate();

        position: absolute;
        left: 30rpx;
        bottom: v-bind(positionBottom);
        z-index: 99;
    }

    .legend {
        flex-direction: column;
        padding: 12rpx 20rpx;
        background-color: #fff;
        border-radius: 10rpx;
        box-shadow: 0 0 15rpx rgba(0, 0, 0, 0.3);

        .expand-action {
            font-size: 26rpx;
            font-weight: bold;
            color: #1890ff;

            .text {
                margin-right: 6rpx;
            }
        }

        .expand-content {
            flex-direction: column;
            font-size: 24rpx;
            color: #555;

            .title {
                margin-bottom: 15rpx;
                font-weight: bold;
            }

            .option {
                display: flex;

                .item-wrap {
                    + .item-wrap {
                        margin-left: 15rpx;
                    }

                    .item {
                        display: flex;
                        align-items: center;
                        justify-content: flex-start;

                        .icon {
                            margin-right: 8rpx;
                            padding: 4rpx;
                        }

                        .color {
                            width: 32rpx;
                            height: 12rpx;
                            margin-right: 8rpx;
                            padding: 4rpx;
                        }

                        .label {
                            color: #777;
                            letter-spacing: 1px;
                            white-space: pre-wrap;
                            text-align: center;
                        }
                    }

                    .sub-items {
                        display: flex;

                        .item {
                            flex-direction: column;
                            margin: 2rpx 5rpx;
                        }
                    }
                }
            }
        }
    }
</style>
