<template>
  <Teleport to="body">
    <div
      v-if="show"
      class="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm p-4"
      @click.self="handleClose"
    >
      <div class="admin-card max-w-3xl w-full mx-4 max-h-[92vh] overflow-hidden flex flex-col border border-white/10 shadow-2xl">
        <!-- Header -->
        <div class="flex items-start justify-between gap-4 px-6 py-4 border-b border-white/10 shrink-0">
          <div class="min-w-0">
            <h2 class="text-xl font-serif italic text-white">附件详情</h2>
            <p v-if="attachment" class="text-sm text-art-muted mt-1 truncate" :title="attachment.originalName">
              {{ attachment.originalName }}
            </p>
          </div>
          <button @click="handleClose" class="text-white/40 hover:text-white transition-colors shrink-0 p-1">
            <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
              <line x1="18" y1="6" x2="6" y2="18"></line>
              <line x1="6" y1="6" x2="18" y2="18"></line>
            </svg>
          </button>
        </div>

        <div v-if="attachment" class="overflow-y-auto custom-scrollbar flex-1">
          <!-- Media preview -->
          <div class="px-6 pt-6">
            <div class="rounded-xl overflow-hidden bg-black/40 border border-white/10 min-h-[200px] flex items-center justify-center">
              <img
                v-if="attachment.fileType === 'image'"
                :src="attachment.fileUrl"
                :alt="attachment.originalName"
                class="w-full max-h-[420px] object-contain"
              />
              <video
                v-else-if="attachment.fileType === 'video'"
                :src="attachment.fileUrl"
                controls
                preload="metadata"
                class="w-full max-h-[420px] bg-black"
              />
              <div v-else class="flex flex-col items-center justify-center py-16 px-6 text-center">
                <div class="w-20 h-20 rounded-2xl bg-white/5 border border-white/10 flex items-center justify-center mb-4">
                  <svg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" class="text-art-muted">
                    <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
                    <polyline points="14 2 14 8 20 8"></polyline>
                  </svg>
                </div>
                <p class="text-white font-medium mb-1">{{ attachment.originalName }}</p>
                <p class="text-sm text-art-muted">此文件类型暂不支持预览</p>
              </div>
            </div>
          </div>

          <!-- Badges -->
          <div class="px-6 pt-4 flex flex-wrap gap-2">
            <span class="px-3 py-1 rounded-full text-xs font-medium border" :class="typeBadgeClass">
              {{ getFileTypeLabel(attachment.fileType) }}
            </span>
            <span class="px-3 py-1 rounded-full text-xs bg-white/5 text-art-muted border border-white/10">
              {{ formatFileSize(attachment.fileSize) }}
            </span>
            <span class="px-3 py-1 rounded-full text-xs bg-white/5 text-art-muted border border-white/10">
              {{ getStorageTypeLabel(attachment.storageType) }}
            </span>
          </div>

          <!-- Meta grid -->
          <div class="px-6 py-5 grid sm:grid-cols-2 gap-4">
            <div class="rounded-lg bg-white/[0.03] border border-white/5 p-4">
              <label class="block text-xs font-medium text-art-muted uppercase tracking-wider mb-2">MIME 类型</label>
              <p class="text-white font-mono text-sm break-all">{{ attachment.mimeType || '—' }}</p>
            </div>
            <div class="rounded-lg bg-white/[0.03] border border-white/5 p-4">
              <label class="block text-xs font-medium text-art-muted uppercase tracking-wider mb-2">创建时间</label>
              <p class="text-white text-sm">{{ attachment.createdAt ? formatDate(attachment.createdAt) : '—' }}</p>
            </div>
            <div class="sm:col-span-2 rounded-lg bg-white/[0.03] border border-white/5 p-4">
              <label class="block text-xs font-medium text-art-muted uppercase tracking-wider mb-2">分类</label>
              <CustomSelect
                v-model="localCategoryId"
                :options="categoryOptions"
                placeholder="无分类"
              />
            </div>
            <div class="sm:col-span-2 rounded-lg bg-white/[0.03] border border-white/5 p-4">
              <label class="block text-xs font-medium text-art-muted uppercase tracking-wider mb-2">文件 URL</label>
              <div class="flex gap-2">
                <input
                  type="text"
                  :value="attachment.fileUrl"
                  readonly
                  class="admin-input flex-1 font-mono text-sm"
                />
                <button @click="handleCopyUrl" class="admin-btn-secondary px-4 whitespace-nowrap">
                  复制
                </button>
              </div>
            </div>
          </div>
        </div>

        <!-- Footer -->
        <div class="flex gap-3 px-6 py-4 border-t border-white/10 shrink-0">
          <button @click="handleClose" class="admin-btn-secondary flex-1">
            取消
          </button>
          <button @click="handleSave" :disabled="saving" class="admin-btn-primary flex-1">
            {{ saving ? '保存中...' : '保存' }}
          </button>
        </div>
      </div>
    </div>
  </Teleport>
</template>

<script setup lang="ts">
import { ref, watch, computed } from 'vue'
import CustomSelect from '../CustomSelect.vue'

interface Attachment {
  id: number
  originalName: string
  fileUrl: string
  fileSize: number
  fileType: string
  categoryId?: number
  mimeType?: string
  storageType?: string
  createdAt?: string
}

interface Category {
  id: number
  name: string
}

interface Props {
  show: boolean
  attachment: Attachment | null
  categories: Category[]
}

const props = defineProps<Props>()

const emit = defineEmits<{
  'update:show': [value: boolean]
  'save': [data: { categoryId: number | null }]
  'copy-url': [url: string]
}>()

const localCategoryId = ref<number>(0)
const saving = ref(false)

const categoryOptions = computed(() => {
  return [
    { value: 0, label: '无分类' },
    ...props.categories.map(cat => ({ value: cat.id, label: cat.name }))
  ]
})

const typeBadgeClass = computed(() => {
  const map: Record<string, string> = {
    image: 'bg-emerald-500/10 text-emerald-300 border-emerald-500/30',
    video: 'bg-violet-500/10 text-violet-300 border-violet-500/30',
    document: 'bg-blue-500/10 text-blue-300 border-blue-500/30',
    other: 'bg-white/5 text-art-muted border-white/10'
  }
  return map[props.attachment?.fileType || 'other'] || map.other
})

watch(() => props.attachment, (newAttachment) => {
  if (newAttachment) {
    localCategoryId.value = newAttachment.categoryId || 0
  }
}, { immediate: true })

const handleClose = () => {
  emit('update:show', false)
}

const handleSave = () => {
  saving.value = true
  const categoryId = localCategoryId.value === 0 ? null : localCategoryId.value
  emit('save', { categoryId })
}

const handleCopyUrl = () => {
  if (props.attachment) {
    emit('copy-url', props.attachment.fileUrl)
  }
}

const formatFileSize = (bytes: number): string => {
  if (bytes < 1024) return bytes + ' B'
  if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'
  return (bytes / (1024 * 1024)).toFixed(1) + ' MB'
}

const getFileTypeLabel = (fileType: string): string => {
  const labels: Record<string, string> = {
    image: '图片',
    video: '视频',
    document: '文档',
    other: '其他'
  }
  return labels[fileType] || fileType
}

const getStorageTypeLabel = (storageType?: string): string => {
  const labels: Record<string, string> = {
    local: '本地存储',
    qcloud: '腾讯云 COS',
    aliyun: '阿里云 OSS',
    qiniu: '七牛云'
  }
  return labels[storageType || 'local'] || storageType || '本地存储'
}

const formatDate = (timestamp: string | number): string => {
  const date = new Date(typeof timestamp === 'string' ? parseInt(timestamp) * 1000 : timestamp * 1000)
  return date.toLocaleString('zh-CN')
}

defineExpose({ saving })
</script>

<style scoped>
.custom-scrollbar::-webkit-scrollbar {
  width: 4px;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 2px;
}
</style>
