<template>
    <div @click="openDialog">
        <slot></slot>
    </div>
    <el-dialog v-model="showDialog" :title="t('upload.select' + type)" width="60%" class="attachment-dialog" :destroy-on-close="true">
        <div class="flex border-t border-b main-wrap border-color w-full h-[40vh]">
            <!-- 素材 -->
            <div class="attachment-list-wrap flex flex-col p-[15px] flex-1 overflow-hidden">
                <el-row :gutter="15" class="h-[32px]">
                    <el-col :span="10">
                        <div class="flex" v-if="prop.type != 'news'">
                            <upload-media :type="prop.type" @success="getAttachmentList()">
                                <el-button type="primary">{{ t('upload.upload' + type) }}</el-button>
                            </upload-media>
                        </div>
                        <div class="flex" v-else>
                            <el-button type="primary" :loading="syncLoading" @click="syncWechatNews">{{ syncLoading ? '同步中' : '同步微信图文'}}</el-button>
                        </div>
                    </el-col>
                </el-row>
                <div class="flex-1 my-[15px] h-0" v-loading="attachment.loading">
                    <el-scrollbar>
                        <!-- 素材管理 -->
                        <div v-if="attachment.data.length">
                            <div class="flex flex-wrap" v-if="prop.type != 'news'">
                                <div class="attachment-item mr-[10px] mb-[10px] w-[120px]" v-for="(item, index) in attachment.data" :key="index" @click="selectedFile = item">
                                    <div
                                        class="attachment-wrap w-full rounded cursor-pointer overflow-hidden relative flex items-center justify-center h-[120px]">
                                        <el-image :src="img(item.value)" fit="contain" v-if="type == 'image'" :preview-src-list="item.image_list" />
                                        <video :src="img(item.value)" v-else-if="type == 'video'"></video>
                                        <div class="absolute z-[1] flex items-center justify-center w-full h-full inset-0 bg-black bg-opacity-60" v-show="selectedFile.id == item.id">
                                            <icon name="element Select" color="#fff" size="40px" />
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div class="relative" ref="waterfallContainerRef" v-else>
                                <div ref="waterfallItemRef" class="absolute attachment-item mr-[10px] mb-[10px] w-[280px] rounded-lg overflow-hidden border border-color" v-for="(item, index) in attachment.data"
                                     :style="{ left: listPosition[index] ? listPosition[index].left : '', top: listPosition[index] ? listPosition[index].top : '' }"
                                     :key="index" @click="selectedFile = item">
                                    <div class="relative">
                                        <div class="w-full h-[130px] relative">
                                            <el-image :src="item.value.news_item[0].thumb_url" class="w-full h-full"/>
                                            <div class="absolute left-0 bottom-0 p-[10px] w-full truncate text-white leading-none" v-if="item.value.news_item.length > 1">
                                                {{ item.value.news_item[0].title }}
                                            </div>
                                        </div>
                                        <div v-if="item.value.news_item.length > 1">
                                            <template v-for="(newsItem, newsIndex) in item.value.news_item">
                                                <div class="px-[15px] py-[10px] flex" :class="{'border-b border-color' : newsIndex < item.value.news_item.length - 1 }" v-if="newsIndex > 0">
                                                    <div class="flex-1 w-0 truncate">
                                                        {{ newsItem.title }}
                                                    </div>
                                                    <div class="w-[50px] h-[50px] ml-[10px]">
                                                        <el-image :src="newsItem.thumb_url" class="w-full h-full"/>
                                                    </div>
                                                </div>
                                            </template>
                                        </div>
                                        <div class="px-[15px] py-[10px]" v-else>
                                            {{ item.value.news_item[0].title }}
                                        </div>
                                        <div class="absolute z-[1] flex items-center justify-center w-full h-full inset-0 bg-black bg-opacity-60" v-show="selectedFile.id == item.id">
                                            <icon name="element Select" color="#fff" size="40px" />
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="flex items-center justify-center" v-else>
                            <el-empty v-if="!attachment.loading" :description="t('upload.mediaEmpty')" :image-size="100" />
                        </div>
                    </el-scrollbar>
                </div>
                <el-row :gutter="20">
                    <el-col span="24">
                        <div class="flex h-full justify-end items-center">
                            <el-pagination v-model:current-page="attachment.page" :small="true"
                                v-model:page-size="attachment.limit" :page-sizes="[10, 20, 30, 40, 60]"
                                layout="total, sizes, prev, pager, next, jumper" :total="attachment.total"
                                @size-change="getAttachmentList()" @current-change="getAttachmentList" />
                        </div>
                    </el-col>
                </el-row>
            </div>
        </div>

        <template #footer>
            <span class="dialog-footer">
                <el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
                <el-button type="primary" @click="confirm">{{ t('confirm') }}</el-button>
            </span>
        </template>
    </el-dialog>
</template>

<script lang="ts" setup>
    import { reactive, ref, nextTick } from 'vue'
    import { t } from '@/lang'
    import UploadMedia from './upload-media.vue'
    import { img, debounce } from '@/utils/common'
    import { getMediaList, syncNews } from '@/app/api/wechat'

    const prop = defineProps({
        type: {
            type: String,
            default: 'image'
        }
    })

    const showDialog = ref(false)

    const openDialog = () => {
        prop.type == 'news' && waterfall()
        showDialog.value = true
    }

    const attachment: Record<string, any> = reactive({
        loading: true,
        page: 1,
        total: 0,
        limit: 10,
        data: []
    })

    /**
     * 查询素材
     */
    const getAttachmentList = (page: number = 1) => {
        attachment.loading = true
        attachment.page = page
        getMediaList({
            page: attachment.page,
            limit: attachment.limit,
            type: prop.type
        }).then(res => {
            attachment.data = res.data.data
            attachment.total = res.data.total
            attachment.loading = false
            prop.type == 'news' && waterfall()
        }).catch(() => {
            attachment.loading = false
        })
    }
    getAttachmentList()

    const emits = defineEmits(['success'])
    const selectedFile: Record<string, any> = ref({})

    const confirm = () => {
        emits('success', selectedFile.value)
    }

    const syncLoading = ref(false)
    const syncWechatNews = () => {
        if (syncLoading.value) return
        syncLoading.value = true

        syncNews().then(() => {
            syncLoading.value = false
            getAttachmentList()
        }).catch(() => {
            syncLoading.value = false
        })
    }

    const meta = document.createElement('meta')
    meta.content = 'same-origin'
    meta.name = 'referrer'
    document.getElementsByTagName('head')[0].appendChild(meta)

    // 瀑布流计算
    const waterfallContainerRef = ref(null)
    const waterfallItemRef = ref([])
    const listPosition = ref([])
    const waterfall = debounce(() => {
        nextTick(() => {
            const containerWidth = waterfallContainerRef.value.clientWidth
            const column = parseInt(containerWidth / 292)
            const heights = []
            const positions = []

            waterfallItemRef.value.forEach((item, i) => {
                if (i < column) {
                    const position = {}
                    position.top = '0px'
                    if (i % column == 0) {
                        position.left = item.clientWidth * i + "px"
                    } else {
                        position.left = item.clientWidth * i + (i % column * 10) + "px"
                    }
                    positions[i] = position
                    heights[i] = item.clientHeight + 10
                } else {
                    let minHeight = Math.min(...heights) //  找到第一列的最小高度
                    let minIndex = heights.findIndex(item => item === minHeight) // 找到最小高度的索引
                    let position = {}
                    position.top = minHeight + 10 + "px"
                    position.left = positions[minIndex].left
                    positions[i] = position
                    heights[minIndex] += item.clientHeight + 10
                }
            })
            listPosition.value = positions
        })
    }, 800)

    // 重新布局，以适应窗口变化
    window.addEventListener('resize', () => waterfall())
</script>

<style lang="scss" scoped>
</style>
