<template>
  <div class="file-uploader">
    <input 
      type="file" 
      ref="fileInputRef"
      :accept="acceptString"
      :multiple="multiple"
      @change="handleFileSelect"
      style="display: none"
    >

    <!-- Пустая зона drag & drop (скрываем в readOnly если нет файлов) -->
    <div 
      v-if="files.length === 0 && !readOnly"
      class="file-dropzone"
      :class="{ 'dragover': isDragging }"
      @dragover.prevent="isDragging = true"
      @dragleave.prevent="isDragging = false"
      @drop.prevent="handleFileDrop"
      @click="triggerFileInput"
    >
      <i data-lucide="image-plus" class="dropzone-icon"></i>
      <span class="dropzone-text">{{ dropzoneText }}</span>
      <span class="dropzone-subtext">{{ dropzoneSubtext }}</span>
    </div>

    <!-- Сетка с файлами -->
    <div 
      v-else 
      class="files-container"
      :class="{ 'dragover': isDragging && !readOnly }"
      @dragover.prevent="!readOnly && (isDragging = true)"
      @dragleave.prevent="isDragging = false"
      @drop.prevent="!readOnly && handleFileDrop($event)"
    >
      <!-- Превью файлов -->
      <div 
        v-for="(file, index) in visibleFiles" 
        :key="file.name + '-' + file.size"
        class="file-preview-item"
      >
        <div v-if="!readOnly" class="file-actions">
          <button class="btn-download-file" @click.stop="downloadFile(file)" title="Скачать">
            <i data-lucide="download"></i>
          </button>
          <button class="btn-remove-file" @click.stop="$emit('remove', index)" title="Удалить">
            <i data-lucide="x"></i>
          </button>
        </div>
        <div class="file-thumbnail" @click="!isArchive(file) && $emit('preview', file)">
          <template v-if="isArchive(file)">
            <div class="archive-icon">
              <i data-lucide="archive"></i>
              <span class="archive-ext">.{{ getFileExt(file) }}</span>
            </div>
          </template>
          <img v-else :src="getPreviewUrl(file)" :alt="file.name">
        </div>
      </div>

      <!-- Кнопка добавить ещё (скрываем в readOnly) -->
      <div v-if="!readOnly" class="file-add-btn" @click="triggerFileInput">
        <i data-lucide="plus"></i>
        <span>Добавить</span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'
import { useLucideIcons } from '../../composables/useLucideIcons'

const props = defineProps({
  files: {
    type: Array,
    default: () => []
    // Формат: [{ name, size, type, preview, isNew, toDelete }]
  },
  allowedExtensions: {
    type: Array,
    default: () => ['png', 'jpg', 'jpeg', 'zip', 'rar']
  },
  archiveExtensions: {
    type: Array,
    default: () => ['zip', 'rar']
  },
  maxFileSize: {
    type: Number,
    default: 10 * 1024 * 1024 // 10 MB
  },
  multiple: {
    type: Boolean,
    default: true
  },
  dropzoneText: {
    type: String,
    default: 'Перетащите файлы сюда'
  },
  dropzoneSubtext: {
    type: String,
    default: 'или нажмите для выбора'
  },
  readOnly: {
    type: Boolean,
    default: false
  },
  getFullUrl: {
    type: Function,
    default: (url) => url
  }
})

const emit = defineEmits(['add', 'remove', 'preview', 'error'])

useLucideIcons()

const fileInputRef = ref(null)
const isDragging = ref(false)

// Видимые файлы (без помеченных на удаление)
const visibleFiles = computed(() => props.files.filter(f => !f.toDelete))

// Accept строка для input
const acceptString = computed(() => {
  const mimeTypes = {
    'png': 'image/png',
    'jpg': 'image/jpeg',
    'jpeg': 'image/jpeg',
    'zip': 'application/zip',
    'rar': 'application/x-rar-compressed'
  }
  const exts = props.allowedExtensions.map(e => `.${e}`)
  const mimes = props.allowedExtensions.map(e => mimeTypes[e]).filter(Boolean)
  return [...exts, ...mimes].join(',')
})

// Получить расширение файла
const getFileExt = (file) => {
  return file.name?.split('.').pop()?.toLowerCase() || ''
}

// Проверка разрешён ли файл
const isAllowedFile = (file) => {
  return props.allowedExtensions.includes(getFileExt(file))
}

// Проверка является ли файл архивом
const isArchive = (file) => {
  return props.archiveExtensions.includes(getFileExt(file))
}

// Получить URL превью
const getPreviewUrl = (file) => {
  return props.getFullUrl(file.preview)
}

// Открыть диалог выбора файлов
const triggerFileInput = () => {
  fileInputRef.value?.click()
}

// Обработка выбора файлов
const handleFileSelect = (event) => {
  const files = event.target.files
  if (files) {
    processFiles(Array.from(files))
  }
  event.target.value = ''
}

// Обработка drop
const handleFileDrop = (event) => {
  isDragging.value = false
  const files = event.dataTransfer.files
  if (files) {
    processFiles(Array.from(files))
  }
}

// Обработка файлов
const processFiles = (fileList) => {
  for (const file of fileList) {
    // Проверка типа
    if (!isAllowedFile(file)) {
      emit('error', `Файл "${file.name}" не поддерживается.`)
      continue
    }
    
    // Проверка размера
    if (file.size > props.maxFileSize) {
      emit('error', `Файл "${file.name}" слишком большой.`)
      continue
    }
    
    // Проверяем дубликат
    const isDuplicate = props.files.some(
      f => f.name === file.name && f.size === file.size
    )
    if (isDuplicate) continue
    
    // Создаём превью
    const reader = new FileReader()
    reader.onload = (e) => {
      emit('add', {
        file: file,
        name: file.name,
        size: file.size,
        type: file.type,
        preview: e.target.result,
        isNew: true
      })
    }
    reader.readAsDataURL(file)
  }
}

// Скачивание файла
const downloadFile = async (file) => {
  const url = getPreviewUrl(file)
  try {
    if (file.preview?.startsWith('data:')) {
      const link = document.createElement('a')
      link.href = file.preview
      link.download = file.name
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
    } else {
      const response = await fetch(url)
      const blob = await response.blob()
      const blobUrl = window.URL.createObjectURL(blob)
      const link = document.createElement('a')
      link.href = blobUrl
      link.download = file.name
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      window.URL.revokeObjectURL(blobUrl)
    }
  } catch (error) {
    console.error('Ошибка скачивания:', error)
    window.open(url, '_blank')
  }
}

// Экспортируем методы
defineExpose({
  triggerFileInput
})
</script>

<style scoped>
.file-dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 32px 24px;
  background: rgba(255, 255, 255, 0.02);
  border: 2px dashed rgba(255, 255, 255, 0.12);
  border-radius: 12px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.file-dropzone:hover {
  border-color: rgba(255, 255, 255, 0.25);
  background: rgba(255, 255, 255, 0.04);
}

.file-dropzone.dragover {
  border-color: var(--accent);
  background: rgba(0, 212, 170, 0.08);
}

.dropzone-icon {
  width: 36px;
  height: 36px;
  color: var(--text-muted);
  opacity: 0.6;
  transition: all 0.2s;
}

.file-dropzone:hover .dropzone-icon,
.file-dropzone.dragover .dropzone-icon {
  color: var(--accent);
  opacity: 1;
}

.dropzone-text {
  font-size: 14px;
  color: var(--text-secondary);
  font-weight: 500;
}

.dropzone-subtext {
  font-size: 12px;
  color: var(--text-muted);
}

.files-container {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 12px;
  padding: 12px;
  background: rgba(255, 255, 255, 0.02);
  border: 2px dashed rgba(255, 255, 255, 0.12);
  border-radius: 12px;
  transition: all 0.2s ease;
}

.files-container.dragover {
  border-color: var(--accent);
  background: rgba(0, 212, 170, 0.08);
}

.file-preview-item {
  position: relative;
  min-width: 0;
}

.file-thumbnail {
  width: 100%;
  padding-bottom: 100%;
  position: relative;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  cursor: pointer;
  transition: opacity 0.15s;
  overflow: hidden;
}

.file-thumbnail img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.archive-icon {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.05);
  color: var(--text-secondary);
}

.archive-icon i {
  width: 32px;
  height: 32px;
  opacity: 0.7;
}

.archive-ext {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  margin-top: 4px;
  opacity: 0.6;
}

.file-preview-item:hover .file-thumbnail {
  opacity: 0.85;
}

.file-actions {
  position: absolute;
  top: 6px;
  right: 6px;
  display: flex;
  gap: 4px;
  z-index: 10;
  opacity: 0;
  transition: opacity 0.15s;
}

.file-preview-item:hover .file-actions {
  opacity: 1;
}

.btn-remove-file,
.btn-download-file {
  width: 26px;
  height: 26px;
  background: rgba(0, 0, 0, 0.7);
  border: none;
  border-radius: 6px;
  color: #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s;
}

.btn-remove-file i,
.btn-download-file i {
  width: 14px;
  height: 14px;
}

.btn-remove-file:hover {
  background: #ef4444;
}

.btn-download-file:hover {
  background: var(--accent);
  color: #000;
}

.file-add-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  aspect-ratio: 1;
  background: rgba(255, 255, 255, 0.04);
  border: 2px dashed rgba(255, 255, 255, 0.15);
  border-radius: 12px;
  cursor: pointer;
  transition: all 0.15s;
  color: var(--text-muted);
}

.file-add-btn:hover {
  border-color: var(--accent);
  background: rgba(0, 212, 170, 0.08);
  color: var(--accent);
}

.file-add-btn i {
  width: 24px;
  height: 24px;
}

.file-add-btn span {
  font-size: 11px;
  font-weight: 500;
}
</style>
