<script lang="ts" setup>
    import md5 from 'crypto-js/md5'
    import { nanoid } from 'nanoid'
    import { getPoster, isImage, isVideo } from './utils'
    import CacheImage from '@/components/CacheImage/index.vue'

    type Asset = Recordable & { url: string }
    const props = defineProps({
        width: {
            type: [String, Number],
            default: '96',
        },
        height: {
            type: [String, Number],
            default: '96',
        },
        mode: {
            type: String,
            default: 'aspectFit',
        },
        background: {
            type: String,
            default: '#F7F7f7',
        },
        assets: {
            type: Array as PropType<Asset[]>,
        },
    })

    // 生成预览容器高度
    const height = computed(() => `${props.height}rpx`)
    // 分离图片和视频资源地址
    const images = computed(() => props.assets.filter((item) => isImage(item.url)))
    const videos = computed(() => props.assets.filter((item) => isVideo(item.url)))

    // 预览图片
    function preview(index: number) {
        uni.previewImage({
            urls: images.value.map((item) => {
                // #ifdef APP-PLUS
                const hash = md5(item.url).toString()
                const key = `G_CACHE_IMAGE_${hash}`
                if (uni.getStorageSync(key)) {
                    return uni.getStorageSync(key)
                }
                // #endif

                return item.url
            }),
            current: index,
        })
    }

    // 初始化视频组件配置
    const videoId = nanoid()
    const videoContext = ref()
    const playVideoSrc = ref()
    // 播放视频
    function play(index: number) {
        playVideoSrc.value = videos.value[index].url
        videoContext.value?.requestFullScreen()
        videoContext.value?.play()
    }
    function videoFullScreenChange(e: any) {
        // 非全屏状态下停止播放
        if (!e.detail.fullScreen) {
            videoContext.value.seek(0)
            videoContext.value.pause()
        }
    }

    onMounted(() => {
        // 初始化视频组件上下文对象
        videoContext.value = uni.createVideoContext(videoId)
    })
</script>

<template>
    <view class="preview-wrap">
        <!-- 视频预览 -->
        <CacheImage
            class="preview-video"
            :background="props.background"
            :mode="props.mode"
            v-for="(item, index) in videos"
            :key="item.url"
            :src="getPoster(item.url)"
            :width="props.width"
            :height="props.height"
            :radius="10"
            @tap="play(index)"
        >
            <view class="icon-wrap" :style="{ width: props.width, height: props.height }">
                <fui-icon class="video-play-icon" name="suspend" size="40" color="#fff" />
            </view>
        </CacheImage>

        <!-- 图片预览 -->
        <CacheImage
            class="preview-image"
            :background="props.background"
            :mode="props.mode"
            v-for="(item, index) in images"
            :key="item.url"
            :src="getPoster(item.url)"
            :width="props.width"
            :height="props.height"
            :radius="10"
            @tap="preview(index)"
        />

        <!-- 视频 -->
        <video
            :id="videoId"
            :src="playVideoSrc"
            class="video"
            autoplay
            controls
            @fullscreenchange="videoFullScreenChange"
        ></video>
    </view>
</template>

<style lang="less" scoped>
    .preview-wrap {
        display: flex;
        flex-wrap: wrap;
        margin: -10rpx;

        .preview-image,
        .preview-video {
            margin: 10rpx !important;
            position: relative;

            :deep(.fui-lazyload__img) {
                height: v-bind(height) !important;
            }

            .icon-wrap {
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background-color: rgb(0 0 0 / 50%);
                border-radius: 10rpx;

                .video-play-icon {
                    position: absolute;
                    top: 50%;
                    left: 50%;
                    transform: translate(-50%, -50%);
                }
            }
        }

        .video {
            position: absolute;
            top: -999999px;
        }
    }
</style>
