<template>
  <div
    class="dropzone-container"
    :class="{ 'is-dragging': isDragging, 'has-error': !!error }"
    @dragenter.prevent="isDragging = true"
    @dragover.prevent="isDragging = true"
    @dragleave.prevent="isDragging = false"
    @drop.prevent="onDrop"
  >
    <div v-if="files.length === 0" class="dropzone-placeholder" @click="triggerFileInput">
      <div class="icon-wrapper">
        <img src="https://cdn.jsdelivr.net/gh/telemagnadon/obj-vault-3a@v2026.05.14-vendor-2/a/b1ef4a83a864.svg" class="cloud-icon" style="width: 48px; height: 48px; opacity: 0.5;" />
      </div>
      <p class="main-text">Click to upload or drag and drop</p>
      <p class="sub-text">SVG, PNG, JPG or GIF (max. {{ maxSizeMB }}MB)</p>
    </div>

    <div v-else class="previews-grid">
      <div v-for="(file, index) in files" :key="index" class="preview-card" :class="{ 'is-main': index === 0 }">
        <label v-if="index === 0" class="main-photo-badge">Main Photo</label>
        <img :src="file.preview" :alt="file.name" class="preview-img" />
        <div class="preview-overlay">
          <button v-if="index !== 0" @click.stop="setAsMain(index)" class="set-main-btn" title="Set as main photo">
            <img src="https://cdn.jsdelivr.net/gh/telemagnadon/obj-vault-3a@v2026.05.14-vendor-2/a/8fad7e49d466.svg" style="width: 18px; height: 18px; filter: brightness(0) invert(1);" />
          </button>
          <button @click.stop="removeFile(index)" class="remove-btn" title="Remove image">
            <img src="https://cdn.jsdelivr.net/gh/telemagnadon/obj-vault-3a@v2026.05.14-vendor-2/a/b6dc254166b4.bin" style="width: 16px; height: 16px; filter: brightness(0) invert(1);" />
          </button>
        </div>
        <div v-if="file.uploading" class="progress-bar">
          <div class="progress-fill" :style="{ width: file.progress + '%' }"></div>
        </div>
        <div v-if="file.error" class="error-badge" :title="file.error">!</div>
      </div>
      
      <div class="add-more-card" @click="triggerFileInput" title="Add more images">
        <img src="https://cdn.jsdelivr.net/gh/telemagnadon/obj-vault-3a@v2026.05.14-vendor-2/a/8d3954387e14.svg" style="width: 24px; height: 24px; opacity: 0.6;" />
      </div>
    </div>

    <input
      ref="fileInput"
      type="file"
      multiple
      class="hidden-input"
      :accept="accept"
      @change="onFileChange"
    />

    <transition name="fade">
      <div v-if="error" class="error-message">{{ error }}</div>
    </transition>
  </div>
</template>

<script setup>
import { ref, onUnmounted, watch } from 'vue';

const props = defineProps({
  files: {
    type: Array,
    default: () => []
  },
  accept: {
    type: String,
    default: 'image/*'
  },
  maxSizeMB: {
    type: Number,
    default: 10
  }
});

const emit = defineEmits(['update:files', 'removed']);

const isDragging = ref(false);
const fileInput = ref(null);
const files = ref([]);
const error = ref(null);

// Initialize internal files with prop on mount
files.value = [...props.files];

// Sync internal files with prop when it explicitly changes reference or length
watch(() => props.files, (newFiles) => {
  if (newFiles !== files.value) {
    // Preserve internal hashes if they are not in the new prop yet
    // This allows the child to keep the 'hashkey' it just received while the parent is still updating
    files.value = newFiles.map((newF, index) => {
      const existingF = files.value[index];
      if (existingF && existingF.file === newF.file && !newF.hashkey && existingF.hashkey) {
        return { ...newF, hashkey: existingF.hashkey };
      }
      return { ...newF };
    });
  }
}, { deep: false });

const triggerFileInput = () => {
  fileInput.value.click();
};

const validateFile = (file) => {
  if (file.size > props.maxSizeMB * 1024 * 1024) {
    return { valid: false, error: `File ${file.name} is too large. Max ${props.maxSizeMB}MB.` };
  }
  
  const acceptedTypes = props.accept.split(',').map(t => t.trim());
  const isAccepted = acceptedTypes.some(type => {
    if (type.endsWith('/*')) {
      return file.type.startsWith(type.replace('*', ''));
    }
    return file.type === type;
  });

  if (!isAccepted && props.accept !== '*/*') {
    return { valid: false, error: `File ${file.name} has invalid type.` };
  }

  return { valid: true };
};

const addFiles = (newFiles) => {
  error.value = null;
  const filteredFiles = Array.from(newFiles).map(file => {
    const validation = validateFile(file);
    if (!validation.valid) {
      error.value = validation.error;
      return null;
    }

    return {
      file,
      name: file.name,
      preview: URL.createObjectURL(file),
      uploading: false,
      progress: 0,
      error: null,
      hashkey: null
    };
  }).filter(f => f !== null);

  files.value = [...files.value, ...filteredFiles];
  emit('update:files', files.value);
};

const onFileChange = (e) => {
  addFiles(e.target.files);
};

const onDrop = (e) => {
  isDragging.value = false;
  addFiles(e.dataTransfer.files);
};

const removeFile = (index) => {
  const removedFile = files.value[index];
  if (removedFile.preview) {
    URL.revokeObjectURL(removedFile.preview);
  }
  files.value.splice(index, 1);
  emit('update:files', files.value);
  if (removedFile.hashkey) {
    emit('removed', removedFile.hashkey);
  }
};

const setAsMain = (index) => {
  if (index === 0) return;
  const mainFile = files.value.splice(index, 1)[0];
  files.value.unshift(mainFile);
  emit('update:files', files.value);
};

onUnmounted(() => {
  files.value.forEach(file => {
    if (file.preview) URL.revokeObjectURL(file.preview);
  });
});

defineExpose({
  clear: () => {
    files.value.forEach(file => {
      if (file.preview) URL.revokeObjectURL(file.preview);
    });
    files.value = [];
    emit('update:files', []);
  },
  setFileStatus: (index, status) => {
    if (files.value[index]) {
      files.value[index] = { ...files.value[index], ...status };
      emit('update:files', [...files.value]);
    }
  }
});
</script>

<style scoped>
.dropzone-container {
  width: 100%;
  min-height: 180px;
  border: 2px dashed #e2e8f0;
  border-radius: 16px;
  background: #f8fafc;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  overflow: hidden;
  padding: 20px;
}

.dropzone-container:hover {
  border-color: #3b82f6;
  background: #eff6ff;
}

.dropzone-container.is-dragging {
  border-color: #3b82f6;
  background: #dbeafe;
  transform: scale(1.01);
}

.dropzone-container.has-error {
  border-color: #ef4444;
  background: #fef2f2;
}

.dropzone-placeholder {
  text-align: center;
  color: #64748b;
}

.icon-wrapper {
  margin-bottom: 12px;
  color: #94a3b8;
}

.cloud-icon {
  width: 48px;
  height: 48px;
}

.main-text {
  font-weight: 600;
  color: #1e293b;
  margin-bottom: 4px;
}

.sub-text {
  font-size: 0.85rem;
  color: #94a3b8;
}

.previews-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  gap: 12px;
  width: 100%;
}

.preview-card {
  position: relative;
  aspect-ratio: 1;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
  background: #fff;
}

.preview-card.is-main {
  border: 3px solid #3b82f6;
  transform: scale(1.02);
  z-index: 2;
}

.main-photo-badge {
  position: absolute;
  top: 8px;
  left: 8px;
  background: #2563eb !important;
  color: white !important;
  padding: 4px 10px;
  border-radius: 6px;
  font-size: 0.75rem;
  font-weight: 800;
  text-transform: uppercase;
  z-index: 20;
  box-shadow: 0 4px 6px rgba(37, 99, 235, 0.4);
  letter-spacing: 0.05em;
}

.preview-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.preview-overlay {
  position: absolute;
  top: 8px;
  right: 8px;
  opacity: 0;
  transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
  align-items: center;
  gap: 8px;
  z-index: 25;
}

.preview-card:hover .preview-overlay {
  opacity: 1;
  transform: translateY(2px);
}

.remove-btn, .set-main-btn {
  color: white !important;
  border: none;
  border-radius: 50%;
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.15);
}

.remove-btn {
  background: #ef4444 !important;
}

.set-main-btn {
  background: #2563eb !important;
}

.remove-btn svg, .set-main-btn svg {
  display: block;
  pointer-events: none;
}

.remove-btn:hover, .set-main-btn:hover {
  transform: scale(1.1);
  filter: brightness(1.1);
}

.add-more-card {
  aspect-ratio: 1;
  border: 2px dashed #cbd5e1;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #94a3b8;
  background: #fff;
  transition: all 0.2s;
}

.add-more-card:hover {
  border-color: #3b82f6;
  color: #3b82f6;
  background: #f1f5f9;
}

.progress-bar {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 4px;
  background: rgba(255, 255, 255, 0.3);
}

.progress-fill {
  height: 100%;
  background: #3b82f6;
  transition: width 0.3s;
}

.error-badge {
  position: absolute;
  top: 4px;
  right: 4px;
  background: #ef4444;
  color: white;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  font-size: 12px;
}

.error-message {
  position: absolute;
  bottom: 8px;
  left: 50%;
  transform: translateX(-50%);
  background: #ef4444;
  color: white;
  padding: 4px 12px;
  border-radius: 20px;
  font-size: 0.8rem;
  white-space: nowrap;
}

.hidden-input {
  display: none;
}

.fade-enter-active, .fade-leave-active {
  transition: opacity 0.3s;
}
.fade-enter-from, .fade-leave-to {
  opacity: 0;
}
</style>
