<!--
 - MineAdmin is committed to providing solutions for quickly building web applications
 - Please view the LICENSE file that was distributed with this source code,
 - For the full copyright and license information.
 - Thank you very much for using MineAdmin.
 -
 - @Author X.Mo<root@imoi.cn>
 - @Link   https://gitee.com/xmo/mineadmin-vue
-->
<template>
    <div class="w-full p-2 resource-container h-full lg:flex lg:justify-between rounded-sm">
        <a-modal v-model:visible="openNetworkModal" :ok-text="$t('sys.save')" :on-before-ok="saveNetworkImg" draggable>
            <template #title>{{ $t("maResource.saveNetworkImage") }}</template>
            <a-input v-model="networkImg" class="mb-3" :placeholder="$t('maResource.networkImageNotice')" allow-clear />
            <a-image :src="networkImg" width="100%" style="min-height: 150px" />
        </a-modal>
        <div class="lg:w-1/5 w-full p-2 shadow">
            <ma-tree-slider
                v-model="sliderData"
                :search-placeholder="$t('maResource.searchResource')"
                :field-names="{ title: 'title', key: 'key' }"
                @click="handlerClick"
                icon="icon-folder"
                :selected-keys="['all']"
            />
        </div>
        <div class="w-full lg:ml-3 mt-3 lg:mt-2 flex flex-col">
            <div class="lg:flex lg:justify-between">
                <div class="flex">
                    <ma-upload v-model="uploadFile" multiple :show-list="false" type="chunk" :resource="false" />
                    <a-button class="ml-3" @click="openNetworkModal = true">
                        <icon-image /> {{ $t("maResource.saveNetworkImage") }}
                    </a-button>
                </div>
                <a-input
                    v-model="filename"
                    class="input-search lg:mt-0 mt-2"
                    :placeholder="$t('maResource.searchFileNotice')"
                    @press-enter="searchFile"
                />
            </div>
            <a-spin :loading="resourceLoading" :tip="$t('maResource.loadingText')" class="h-full">
                <div class="resource-list mt-2" ref="rl" v-if="attachmentList && attachmentList.length > 0">
                    <div
                        class="item rounded-sm"
                        v-for="(item, index) in attachmentList"
                        :key="item.hash"
                        @click="selectFile(item, index)"
                    >
                        <img
                            :src="
                                !/^(http|https)/g.test(item.url)
                                    ? $tool.attachUrl(item.url, getStoreMode(item.storage_mode))
                                    : item.url
                            "
                            v-if="item.mime_type.indexOf('image') !== -1"
                        />
                        <div v-else class="text-3xl w-full h-full flex items-center justify-center">
                            {{ `.${item.suffix}` }}
                        </div>
                        <a-tooltip position="bottom">
                            <div class="file-name">
                                {{ item.origin_name }}
                            </div>
                            <template #content>
                                <div>存储名称：{{ item.object_name }}</div>
                                <div>存储目录：{{ item.storage_path }}</div>
                                <div>上传时间：{{ item.created_at }}</div>
                                <div>文件大小：{{ item.size_info }}</div>
                                <div>存储模式：{{ getStoreMode(item.storage_mode) }}</div>
                            </template>
                        </a-tooltip>
                    </div>
                </div>
                <a-empty v-else class="mt-10" />
            </a-spin>
            <div class="lg:flex lg:justify-between">
                <a-pagination
                    :total="pageInfo.total"
                    v-model:current="pageInfo.currentPage"
                    v-model:page-size="pageSize"
                    @change="changePage"
                />
                <a-button type="primary" @click="selectComplete" class="mt-3 lg:mt-0">{{
                    $t("maResource.ok")
                }}</a-button>
            </div>
        </div>
    </div>
</template>

<script setup>
import { ref, onMounted, watch } from "vue"
import MaUpload from "@cps/ma-upload/index.vue"
import uploadConfig from "@/config/upload"
import MaTreeSlider from "@cps/ma-treeSlider/index.vue"
import commonApi from "@/api/common"
import tool from "@/utils/tool"
import { useI18n } from "vue-i18n"
import { Message } from "@arco-design/web-vue"

const { t } = useI18n()
const sliderData = ref([])
const uploadFile = ref()
const attachmentList = ref([])
const openNetworkModal = ref(false)
const networkImg = ref()
const pageInfo = ref({
    total: 1,
    currentPage: 1
})
const resourceLoading = ref(true)
const pageSize = ref(30)
const filename = ref()
const selecteds = ref()
const rl = ref()

const emit = defineEmits(["update:modelValue"])

const props = defineProps({
    modelValue: { type: [String, Array] },
    multiple: { type: Boolean, default: true },
    onlyData: { type: Boolean, default: true },
    returnType: { type: String, default: "url" }
})

onMounted(async () => {
    const treeData = await commonApi.getDict("attachment_type")
    treeData.data.unshift({ title: "所有", key: "all" })
    sliderData.value = treeData.data
    await getAttachmentList({ pageSize: 1 })

    if (props.multiple) {
        selecteds.value = []
    }
})

const getStoreMode = (mode) => {
    return uploadConfig.storageMode[mode.toString()]
}

const getAttachmentList = async (params = {}) => {
    const requestParams = Object.assign(params, { pageSize: pageSize.value })
    resourceLoading.value = true
    const response = await commonApi.getResourceList(requestParams)
    pageInfo.value = response?.data?.pageInfo
    attachmentList.value = response?.data?.items
    resourceLoading.value = false
}

const handlerItemClick = (e) => {
    console.log(e)
}

const handlerClick = async (item) => {
    const type = item[0] === "all" ? undefined : item[0]
    await getAttachmentList({ mime_type: type })
}

const searchFile = async () => {
    await getAttachmentList({ origin_name: filename.value })
}

const selectFile = (item, index) => {
    if (!props.multiple && selecteds.value) {
        if (props.onlyData && item.url != selecteds.value) return
        if (!props.onlyData && item.id != selecteds.value.id) return
    }

    const children = rl.value.children
    const className = "item rounded-sm"
    if (!/^(http|https)/g.test(item.url)) {
        item.url = tool.attachUrl(item.url, getStoreMode(item.storage_mode))
    }
    if (children[index].className.indexOf("active") !== -1) {
        children[index].className = className
        if (props.multiple) {
            selecteds.value.map((file, idx) => {
                if (props.onlyData && file == item.url) selecteds.value.splice(idx, 1)
                if (!props.onlyData && file.id == item.id) selecteds.value.splice(idx, 1)
            })
        } else {
            selecteds.value = ""
        }
    } else {
        children[index].className = className + " active"
        if (props.multiple) {
            selecteds.value.push(props.onlyData ? item[props.returnType] : item)
        } else {
            selecteds.value = props.onlyData ? item[props.returnType] : item
        }
    }
}

const clearSelecteds = () => {
    if (rl.value && rl.value.children) {
        const children = rl.value.children
        for (let i = 0; i < children.length; i++) {
            children[i].className = "item rounded-sm"
        }
    }
    if (props.multiple) {
        selecteds.value = []
    } else {
        selecteds.value = undefined
    }
}

const selectComplete = () => {
    const files = props.multiple ? Object.assign([], selecteds.value) : selecteds.value
    emit("update:modelValue", files)
}

const changePage = async (page) => {
    await getAttachmentList({ page })
}

const saveNetworkImg = async (done) => {
    if (!networkImg.value) {
        Message.error(t("maResource.networkImageNotice"))
        done(false)
        return
    }
    const response = await commonApi.saveNetWorkImage({ url: networkImg.value })
    if (response.success) {
        Message.success(response.message)
        await getAttachmentList()
        networkImg.value = undefined
        done(true)
    } else {
        Message.error(response.message)
        done(false)
    }
}

watch(
    () => uploadFile,
    async () => await getAttachmentList(),
    { deep: true }
)

defineExpose({ clearSelecteds })
</script>

<style scoped lang="less">
.input-search {
    width: 252px;
}
.resource-list {
    display: flex;
    width: 100%;
    flex-wrap: wrap;
    flex-direction: row;
    align-content: center;
    .item {
        width: 130px;
        height: 130px;
        border: 2px solid var(--color-fill-1);
        margin-right: 10px;
        margin-bottom: 20px;
        background-color: var(--color-fill-1);
        cursor: pointer;
        position: relative;
        .file-name {
            position: absolute;
            bottom: 0px;
            height: 23px;
            width: 100%;
            background: rgba(100, 100, 100, 0.3);
            line-height: 23px;
            font-size: 12px;
            overflow: hidden;
            padding: 0 10px;
            text-align: center;
            text-overflow: ellipsis;
            color: #fff;
        }
        img {
            width: 100%;
            height: 100%;
            object-fit: contain;
        }
    }
    .item:hover {
        border: 2px solid rgb(var(--primary-6));
    }
    .item.active {
        border: 2px solid rgb(var(--primary-6));
    }
    .item.active::after {
        content: "";
        position: absolute;
        width: 126px;
        height: 126px;
        z-index: 2;
        top: 0;
        background: rgba(var(--primary-5), 0.2);
    }
}
</style>
