<template>
  <transition name="overlay-fade">
    <div v-if="open" class="image-picker-backdrop" @click.self="close">
      <div class="image-picker-panel">
        <div class="header">
          <div class="title">选择图片（最多9张）</div>
          <button class="close-btn" @click="close">×</button>
        </div>
        <div class="body">
        <div v-if="loading" class="loading">加载中...</div>
        <div v-else-if="!images.length" class="empty">未找到图片文件</div>
        <div v-else class="grid">
          <div
            v-for="item in images"
            :key="item.path"
            class="card"
            :class="{ selected: selectedSet.has(item.path) }"
            @click="toggle(item.path)"
            :title="item.path"
          >
            <img :src="previewUrl(item.path)" :alt="item.name" />
            <div class="name">{{ item.name }}</div>
          </div>
        </div>
      </div>
      <div class="footer">
        <div class="count">已选 {{ selectedSet.size }} / 9</div>
        <div class="actions">
          <button type="button" class="btn secondary" @click="close">取消</button>
          <button type="button" class="btn primary" :disabled="!selectedSet.size" @click="confirm">确认</button>
        </div>
      </div>
    </div>
    </div>
  </transition>
</template>

<script setup lang="ts">
import { computed, ref, watch, onMounted } from 'vue';

interface ImageEntry {
  name: string;
  path: string;
}

const props = defineProps<{
  open: boolean;
  entries: ImageEntry[];
  initialSelected: string[];
  loading: boolean;
}>();

const emit = defineEmits<{
  (e: 'close'): void;
  (e: 'confirm', list: string[]): void;
}>();

const selectedSet = ref<Set<string>>(new Set(props.initialSelected || []));

watch(
  () => props.initialSelected,
  (val) => {
    selectedSet.value = new Set(val || []);
  }
);

const images = computed(() => props.entries || []);

const toggle = (path: string) => {
  if (!path) return;
  const set = new Set(selectedSet.value);
  if (set.has(path)) {
    set.delete(path);
  } else {
    if (set.size >= 9) return;
    set.add(path);
  }
  selectedSet.value = set;
};

const close = () => emit('close');

const confirm = () => emit('confirm', Array.from(selectedSet.value));

const previewUrl = (path: string) => `/api/gui/files/download?path=${encodeURIComponent(path)}`;

onMounted(() => {
  selectedSet.value = new Set(props.initialSelected || []);
});
</script>

<style scoped>
.image-picker-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1200;
}
.image-picker-panel {
  width: min(980px, 92vw);
  max-height: 88vh;
  background: #0f1116;
  color: #e8ecf2;
  border: 1px solid #2a2f3a;
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.4);
}
.header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  border-bottom: 1px solid #1f2430;
}
.title {
  font-weight: 600;
}
.close-btn {
  background: transparent;
  color: #9aa3b5;
  border: none;
  font-size: 20px;
  cursor: pointer;
}
.body {
  padding: 12px 16px;
  overflow: auto;
  flex: 1;
}
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 12px;
}
.card {
  border: 1px solid #1f2430;
  border-radius: 10px;
  background: #151922;
  cursor: pointer;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.card img {
  width: 100%;
  height: 120px;
  object-fit: cover;
  background: #0c0f14;
}
.card .name {
  padding: 8px 10px;
  font-size: 12px;
  color: #c5ccda;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.card.selected {
  border-color: #4ca6ff;
  box-shadow: 0 0 0 2px rgba(76, 166, 255, 0.2);
}
.loading,
.empty {
  padding: 40px 0;
  text-align: center;
  color: #9aa3b5;
}
.footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  border-top: 1px solid #1f2430;
}
.actions {
  display: flex;
  gap: 10px;
}
.btn {
  border: 1px solid #2f3645;
  padding: 8px 14px;
  border-radius: 8px;
  background: #1b202c;
  color: #e8ecf2;
  cursor: pointer;
}
.btn.primary {
  background: #4ca6ff;
  border-color: #4ca6ff;
  color: #0d1117;
}
.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.count {
  font-size: 13px;
  color: #9aa3b5;
}
@media (max-width: 640px) {
  .grid {
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  }
  .card img {
    height: 90px;
  }
}
</style>
