<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图片上传 | Laravel相册 - 暗色主题</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <style>
        .fade-enter-active, .fade-leave-active {
            transition: opacity 0.3s ease;
        }
        .fade-enter-from, .fade-leave-to {
            opacity: 0;
        }
        .dropzone {
            border: 2px dashed #4b5563;
            border-radius: 0.5rem;
            transition: all 0.3s ease;
        }
        .dropzone.active {
            border-color: #818cf8;
            background-color: #1e293b;
        }
        .sort-handle {
            cursor: move;
            transition: transform 0.2s;
        }
        .sort-handle:hover {
            transform: scale(1.1);
        }
        .sortable-ghost {
            opacity: 0.5;
            background: #4f46e5;
        }
    </style>
</head>
<body class="bg-gray-900 min-h-screen text-gray-200">
<div id="app" class="max-w-4xl mx-auto p-4 sm:p-6">
    <!-- 顶部导航 -->
    <nav class="flex justify-between items-center mb-8">
        <h1 class="text-2xl font-bold text-indigo-400">
            <i class="fas fa-images mr-2"></i>图片上传
        </h1>
        <div>
            <a href="#" class="bg-indigo-700 hover:bg-indigo-600 text-white px-4 py-2 rounded-lg transition">
                返回相册
            </a>
        </div>
    </nav>

    <!-- 主卡片 -->
    <div class="bg-gray-800 rounded-xl shadow-lg overflow-hidden border border-gray-700">
        <!-- 标题区域 -->
        <div class="bg-gradient-to-r from-indigo-800 to-purple-800 p-6 text-white">
            <h2 class="text-xl font-bold">上传新图片</h2>
            <p class="mt-1 opacity-90">选择相册并上传图片（支持拖拽排序）</p>
        </div>

        <!-- 表单区域 -->
        <div class="p-6">
            <!-- 全局加载指示器 -->
            <div v-if="isLoading" class="fixed inset-0 bg-black bg-opacity-70 z-50 flex items-center justify-center">
                <div class="text-center bg-gray-800 rounded-xl p-8 shadow-xl border border-gray-700">
                    <div class="animate-spin rounded-full h-16 w-16 border-b-2 border-indigo-600 mx-auto mb-4"></div>
                    <h3 class="text-xl font-medium text-gray-200"> @{{ current }} / @{{ totalUpload }}上传中...</h3>
                    <p class="mt-2 text-gray-400">请稍候，正在上传图片</p>
                </div>
            </div>

            <!-- 相册选择 -->
            <div class="mb-6">
                <label class="block text-sm font-medium text-gray-300 mb-2">选择相册</label>
                <select v-model="selectedAlbum" class="w-full p-3 bg-gray-700 border border-gray-600 rounded-lg focus:ring-indigo-500 focus:border-indigo-500">
                    <option value="" disabled selected>请选择相册</option>
                    <option v-for="album in albums" :value="album.id">@{{ album.title }}</option>
                </select>
            </div>

            <!-- 文件上传区域 -->
            <div class="mb-6">
                <div
                    @dragover.prevent="dragActive = true"
                    @dragleave="dragActive = false"
                    @drop.prevent="handleDrop"
                    :class="{'active': dragActive}"
                    class="dropzone p-8 text-center cursor-pointer transition">
                    <input
                        type="file"
                        accept="image/*"
                        multiple
                        @change="handleFileSelect"
                        class="hidden"
                        ref="fileInput"
                    >

                    <div v-if="!images.length">
                        <i class="fas fa-cloud-upload-alt text-5xl text-indigo-500 mb-4"></i>
                        <h3 class="text-lg font-medium text-gray-300 mb-2">拖放图片到这里</h3>
                        <p class="text-gray-500 mb-4">或</p>
                        <button @click="$refs.fileInput.click()" class="bg-indigo-700 text-white px-6 py-2 rounded-lg hover:bg-indigo-600 transition">
                            选择图片
                        </button>
                        <p class="mt-3 text-gray-500 text-sm">支持 JPG, PNG 格式，最大 10MB</p>
                    </div>
                    <div v-else>
                        <button @click="$refs.fileInput.click()" class="bg-indigo-700 text-white px-6 py-2 rounded-lg hover:bg-indigo-600 transition mb-4">
                            <i class="fas fa-plus mr-2"></i>添加更多图片
                        </button>
                    </div>
                </div>
            </div>

            <!-- 图片预览区域 -->
            <div v-if="images.length" class="mb-6 transition-all">
                <div class="flex justify-between items-center mb-4">
                    <h3 class="font-medium text-gray-300">已选图片 <span class="text-indigo-400">@{{ images.length }}</span> 张</h3>
                    <div>
                        <button @click="clearAll" class="text-red-400 hover:text-red-300 mr-3">
                            <i class="fas fa-trash mr-1"></i>清空
                        </button>
                    </div>
                </div>

                <div class="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-5 gap-3" ref="gridContainer">
                    <div
                        v-for="(image, index) in images"
                        :key="image.id"
                        class="relative group overflow-hidden rounded-lg border border-gray-700 bg-gray-700 shadow-sm transition-transform duration-300 hover:shadow-md hover:-translate-y-0.5">

                        <!-- 排序手柄 -->
                        <div class="absolute top-2 left-2 text-indigo-400 sort-handle">
                            <i class="fas fa-arrows-alt"></i>
                        </div>

                        <!-- 删除按钮 -->
                        <button @click="removeImage(index)" class="absolute top-2 right-2 bg-gray-800 text-red-400 rounded-full w-6 h-6 flex items-center justify-center opacity-0 group-hover:opacity-100 transition">
                            <i class="fas fa-times"></i>
                        </button>

                        <!-- 缩略图 -->

                        <img :src="image.preview" class="w-full h-full object-cover">

                        <!-- 图片信息 -->
                        <div class="p-2 text-center">
                            <p class="text-xs truncate text-gray-300">@{{ image.file.name }}</p>
                            <p class="text-xs text-gray-500">@{{ formatFileSize(image.file.size) }}</p>
                        </div>

                        <!-- 图片编号 -->
                        <div class="absolute bottom-10 right-2 bg-indigo-600 text-white rounded-full w-6 h-6 flex items-center justify-center text-xs">
                            @{{ index + 1 }}
                        </div>
                    </div>
                </div>

                <div class="mt-4 flex justify-between">
                    <div class="text-sm text-gray-500">
                        提示：拖拽图片左上角的 <i class="fas fa-arrows-alt text-indigo-400 mx-1"></i> 可以调整顺序
                    </div>
                    <button
                        @click="uploadImages"
                        :disabled="!selectedAlbum || !images.length || isLoading"
                        :class="{'opacity-70 cursor-not-allowed': !selectedAlbum || !images.length || isLoading, 'hover:bg-indigo-600': selectedAlbum && images.length}"
                        class="bg-indigo-700 text-white px-6 py-2 rounded-lg transition flex items-center">
                        <template v-if="isLoading">
                            <i class="fas fa-spinner animate-spin mr-2"></i>
                            上传中...
                        </template>
                        <template v-else>
                            <i class="fas fa-cloud-upload-alt mr-2"></i>
                            开始上传
                        </template>
                    </button>
                </div>
            </div>
        </div>
    </div>

    <!-- 上传成功提示 -->
    <transition name="fade">
        <div v-if="showSuccess" class="fixed bottom-6 right-6 bg-green-700 text-white py-3 px-6 rounded-lg shadow-lg flex items-center z-50">
            <i class="fas fa-check-circle text-xl mr-3"></i>
            <div>
                <div class="font-medium">上传成功！</div>
                <div class="text-sm">成功上传 @{{ uploadedCount }} 张图片</div>
            </div>
            <button @click="showSuccess = false" class="ml-6 text-green-300 hover:text-white">
                <i class="fas fa-times"></i>
            </button>
        </div>
    </transition>

    <!-- 页脚 -->
    <footer class="mt-12 text-center text-gray-500 text-sm">
        <p>Laravel 12.x 图片上传系统 &copy; 2023 | 暗色主题</p>
    </footer>
</div>

<script>
    const { createApp, ref, onMounted, nextTick } = Vue;

    createApp({
        setup() {
            // 基础变量
            const images = ref([]);
            const fileInput = ref(null);
            const dragActive = ref(false);
            const isLoading = ref(false);
            const selectedAlbum = ref('');
            const showSuccess = ref(false);
            const uploadedCount = ref(0);
            const gridContainer = ref(null);
            let sortableInstance = null;
            const totalUpload = ref(0);
            const current = ref(0);

            // 相册数据（模拟）
            const albums = <?php echo json_encode($photo_album); ?>;

            // 处理文件选择
            const handleFileSelect = (e) => {
                addFiles(e.target.files);
                // 重置文件输入以允许重复选择相同文件
                e.target.value = null;
            };

            // 处理拖放文件
            const handleDrop = (e) => {
                dragActive.value = false;
                if (e.dataTransfer.files.length) {
                    addFiles(e.dataTransfer.files);
                }
            };

            // 添加文件到列表
            const addFiles = (files) => {
                for (let i = 0; i < files.length; i++) {
                    const file = files[i];
                    // 限制为图片格式
                    if (file && file.type.includes('image/')) {
                        images.value.push({
                            id: Date.now() + Math.random(),
                            file: file,
                            preview: URL.createObjectURL(file)
                        });
                    }
                }
                // 添加图片后重新初始化Sortable
                initSortable();
            };

            // 移除图片
            const removeImage = (index) => {
                URL.revokeObjectURL(images.value[index].preview);
                images.value.splice(index, 1);
                // 移除图片后重新初始化Sortable
                initSortable();
            };

            // 清空所有图片
            const clearAll = () => {
                images.value.forEach(img => URL.revokeObjectURL(img.preview));
                images.value = [];
                // 清空后销毁Sortable实例
                destroySortable();
            };

            // 格式化文件大小
            const formatFileSize = (bytes) => {
                if (bytes === 0) return '0 Bytes';
                const k = 1024;
                const sizes = ['Bytes', 'KB', 'MB', 'GB'];
                const i = Math.floor(Math.log(bytes) / Math.log(k));
                return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
            };

            // 图片上传
            const uploadImages = async () => {
                // 调试代码可以保留，但正式使用时建议注释掉
                console.log(images.value, '上传前的图片列表');

                totalUpload.value = images.value.length;
                // 检查条件：相册未选择、无图片、或正在上传中
                if (!selectedAlbum.value || !images.value.length || isLoading.value) return;

                isLoading.value = true;
                let successCount = 0;

                try {
                    // 使用 for...of 循环逐个上传
                    for (const image of images.value) {
                        successCount++;
                        current.value = successCount;
                        const formData = new FormData();
                        formData.append('pid', selectedAlbum.value);
                        formData.append('image', image.file);

                        // 等待当前图片上传完成
                        await axios.post('/api/upload', formData, {
                            headers: {
                                'Content-Type': 'multipart/form-data'
                            }
                        });

                        console.log(`成功上传第 ${successCount} 张图片`);
                    }

                    // 全部上传完成后清空列表并显示成功消息
                    clearAll();
                    uploadedCount.value = successCount;
                    showSuccess.value = true;

                    // 5秒后自动隐藏成功消息
                    setTimeout(() => {
                        showSuccess.value = false;
                    }, 5000);

                } catch (error) {
                    console.error('上传过程中出错:', error);
                    // 出错时不清空列表，允许用户重试
                } finally {
                    isLoading.value = false; // 无论成功或失败，最终关闭加载状态
                }
            };

            // 初始化Sortable拖拽功能
            const initSortable = () => {
                // 确保DOM已经更新
                nextTick(() => {
                    // 销毁旧的Sortable实例
                    if (sortableInstance) {
                        sortableInstance.destroy();
                        sortableInstance = null;
                    }

                    // 确保容器存在且有图片
                    if (gridContainer.value && images.value.length > 0) {
                        sortableInstance = new Sortable(gridContainer.value, {
                            handle: '.sort-handle',
                            animation: 150,
                            ghostClass: 'sortable-ghost',
                            onEnd: (e) => {
                                // 更新数组顺序
                                const movedItem = images.value.splice(e.oldIndex, 1)[0];
                                images.value.splice(e.newIndex, 0, movedItem);
                            }
                        });
                    }
                });
            };

            // 销毁Sortable实例
            const destroySortable = () => {
                if (sortableInstance) {
                    sortableInstance.destroy();
                    sortableInstance = null;
                }
            };

            onMounted(() => {
                // 初始加载完成后初始化Sortable
                initSortable();
            });

            return {
                images,
                albums,
                selectedAlbum,
                fileInput,
                dragActive,
                isLoading,
                showSuccess,
                uploadedCount,
                gridContainer,
                handleFileSelect,
                handleDrop,
                removeImage,
                clearAll,
                formatFileSize,
                uploadImages
            };
        }
    }).mount('#app');
</script>
</body>
</html>
