<script setup>
import { ref, computed, watch, onMounted } from 'vue';
import { useDmsStore } from '~/stores/dms';

const props = defineProps({
  currentPath: {
    type: String,
    default: '/'
  },
  allowMultiple: {
    type: Boolean,
    default: true
  },
  maxFileSize: {
    type: Number,
    default: 100 * 1024 * 1024 // 100MB
  },
  allowedTypes: {
    type: Array,
    default: () => ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'jpg', 'png']
  }
});

const emit = defineEmits(['upload-complete', 'upload-error', 'upload-progress']);

// Store
const dmsStore = useDmsStore();

// Upload state
const uploadQueue = ref([]);
const isUploading = ref(false);
const dragCounter = ref(0);
const isDragOver = ref(false);
const fileInput = ref(null);

// Upload progress tracking
const uploadProgress = ref({});
const overallProgress = computed(() => {
  const files = Object.keys(uploadProgress.value);
  if (files.length === 0) return 0;
  
  const total = files.reduce((sum, fileId) => sum + uploadProgress.value[fileId], 0);
  return Math.round(total / files.length);
});

// File validation
const validateFile = (file) => {
  const errors = [];
  
  // Check file size
  if (file.size > props.maxFileSize) {
    errors.push(`File size exceeds limit of ${formatFileSize(props.maxFileSize)}`);
  }
  
  // Check file type
  const extension = file.name.split('.').pop().toLowerCase();
  if (!props.allowedTypes.includes(extension)) {
    errors.push(`File type .${extension} is not allowed`);
  }
  
  // Check user quota
  if (dmsStore.userQuotas.used + file.size > dmsStore.userQuotas.limit) {
    errors.push('Upload would exceed user storage quota');
  }
  
  return {
    isValid: errors.length === 0,
    errors
  };
};

// Format file size
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];
};

// Generate unique file ID
const generateFileId = () => {
  return `upload_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
};

// Add files to upload queue
const addFilesToQueue = (files) => {
  const newFiles = [];
  
  for (const file of files) {
    const validation = validateFile(file);
    const fileId = generateFileId();
    
    const uploadFile = {
      id: fileId,
      file,
      name: file.name,
      size: file.size,
      type: file.type,
      extension: file.name.split('.').pop().toLowerCase(),
      status: validation.isValid ? 'pending' : 'error',
      errors: validation.errors,
      progress: 0,
      metadata: {
        title: file.name.split('.')[0],
        description: '',
        department: dmsStore.currentUser.department || '',
        author: dmsStore.currentUser.name || '',
        tags: [],
        priority: 'Medium',
        projectCode: '',
        accessType: 'private'
      }
    };
    
    newFiles.push(uploadFile);
    uploadProgress.value[fileId] = 0;
  }
  
  uploadQueue.value = [...uploadQueue.value, ...newFiles];
  return newFiles;
};

// Remove file from queue
const removeFromQueue = (fileId) => {
  const index = uploadQueue.value.findIndex(f => f.id === fileId);
  if (index > -1) {
    uploadQueue.value.splice(index, 1);
    delete uploadProgress.value[fileId];
  }
};

// Clear completed uploads
const clearCompleted = () => {
  uploadQueue.value = uploadQueue.value.filter(f => 
    f.status !== 'completed' && f.status !== 'error'
  );
};

// Upload single file
const uploadSingleFile = async (uploadFile) => {
  try {
    uploadFile.status = 'uploading';
    
    // Simulate chunked upload with progress
    const chunkSize = 1024 * 1024; // 1MB chunks
    const totalChunks = Math.ceil(uploadFile.file.size / chunkSize);
    
    for (let chunk = 0; chunk < totalChunks; chunk++) {
      // Simulate chunk upload delay
      await new Promise(resolve => setTimeout(resolve, 100));
      
      const progress = Math.round(((chunk + 1) / totalChunks) * 100);
      uploadProgress.value[uploadFile.id] = progress;
      uploadFile.progress = progress;
      
      emit('upload-progress', {
        fileId: uploadFile.id,
        progress,
        overall: overallProgress.value
      });
    }
    
    // Create document in store
    const document = await dmsStore.uploadFileWithMetadata(
      uploadFile.file,
      uploadFile.metadata,
      props.currentPath
    );
    
    uploadFile.status = 'completed';
    uploadFile.documentId = document.id;
    
    return document;
    
  } catch (error) {
    uploadFile.status = 'error';
    uploadFile.errors = [error.message];
    throw error;
  }
};

// Upload all files in queue
const uploadAllFiles = async () => {
  if (isUploading.value) return;
  
  isUploading.value = true;
  const pendingFiles = uploadQueue.value.filter(f => f.status === 'pending');
  
  try {
    const uploadPromises = pendingFiles.map(uploadSingleFile);
    const results = await Promise.allSettled(uploadPromises);
    
    const completed = results.filter(r => r.status === 'fulfilled').map(r => r.value);
    const failed = results.filter(r => r.status === 'rejected');
    
    emit('upload-complete', {
      completed,
      failed: failed.length,
      total: pendingFiles.length
    });
    
    if (failed.length > 0) {
      emit('upload-error', {
        message: `${failed.length} file(s) failed to upload`,
        failures: failed
      });
    }
    
  } catch (error) {
    emit('upload-error', { message: error.message });
  } finally {
    isUploading.value = false;
  }
};

// Drag and drop handlers
const handleDragEnter = (e) => {
  e.preventDefault();
  dragCounter.value++;
  isDragOver.value = true;
};

const handleDragLeave = (e) => {
  e.preventDefault();
  dragCounter.value--;
  if (dragCounter.value === 0) {
    isDragOver.value = false;
  }
};

const handleDragOver = (e) => {
  e.preventDefault();
};

const handleDrop = (e) => {
  e.preventDefault();
  dragCounter.value = 0;
  isDragOver.value = false;
  
  const files = Array.from(e.dataTransfer.files);
  if (files.length > 0) {
    addFilesToQueue(files);
  }
};

// File input handler
const handleFileInput = (e) => {
  const files = Array.from(e.target.files);
  if (files.length > 0) {
    addFilesToQueue(files);
  }
  
  // Reset input
  if (fileInput.value) {
    fileInput.value.value = '';
  }
};

// Open file dialog
const openFileDialog = () => {
  if (fileInput.value) {
    fileInput.value.click();
  }
};

// Update metadata for a file
const updateFileMetadata = (fileId, metadata) => {
  const file = uploadQueue.value.find(f => f.id === fileId);
  if (file) {
    file.metadata = { ...file.metadata, ...metadata };
  }
};

// Get status color
const getStatusColor = (status) => {
  switch (status) {
    case 'pending': return 'blue';
    case 'uploading': return 'yellow';
    case 'completed': return 'green';
    case 'error': return 'red';
    default: return 'gray';
  }
};

// Get status icon
const getStatusIcon = (status) => {
  switch (status) {
    case 'pending': return 'mdi:clock-outline';
    case 'uploading': return 'mdi:upload';
    case 'completed': return 'mdi:check-circle';
    case 'error': return 'mdi:alert-circle';
    default: return 'mdi:file';
  }
};

// Watch for auto-upload
watch(() => uploadQueue.value.length, (newLength, oldLength) => {
  if (newLength > oldLength && !isUploading.value) {
    // Auto-start upload if there are pending files
    const pendingFiles = uploadQueue.value.filter(f => f.status === 'pending');
    if (pendingFiles.length > 0) {
      uploadAllFiles();
    }
  }
});
</script>

<template>
  <div class="file-upload-manager">
    <!-- Hidden file input -->
    <input
      ref="fileInput"
      type="file"
      class="hidden"
      :multiple="allowMultiple"
      :accept="allowedTypes.map(ext => `.${ext}`).join(',')"
      @change="handleFileInput"
    />
    
    <!-- Drop zone -->
    <div
      class="drop-zone border-2 border-dashed rounded-lg p-8 text-center transition-colors"
      :class="{
        'border-blue-500 bg-blue-50 dark:bg-blue-900/10': isDragOver,
        'border-gray-300 dark:border-gray-600': !isDragOver,
        'hover:border-gray-400 dark:hover:border-gray-500': !isDragOver
      }"
      @dragenter="handleDragEnter"
      @dragleave="handleDragLeave"
      @dragover="handleDragOver"
      @drop="handleDrop"
    >
      <div class="space-y-4">
        <Icon 
          name="mdi:cloud-upload" 
          class="w-16 h-16 mx-auto text-gray-400"
          :class="{ 'text-blue-500': isDragOver }"
        />
        
        <div>
          <p class="text-lg font-medium text-gray-900 dark:text-gray-100">
            Drop files here to upload
          </p>
          <p class="text-sm text-gray-500 dark:text-gray-400 mt-1">
            or 
            <button 
              @click="openFileDialog"
              class="text-blue-600 hover:text-blue-700 underline"
            >
              browse to choose files
            </button>
          </p>
        </div>
        
        <div class="text-xs text-gray-400 dark:text-gray-500">
          <p>Supported formats: {{ allowedTypes.join(', ').toUpperCase() }}</p>
          <p>Maximum file size: {{ formatFileSize(maxFileSize) }}</p>
        </div>
      </div>
    </div>
    
    <!-- Upload queue -->
    <div v-if="uploadQueue.length > 0" class="mt-6">
      <div class="flex items-center justify-between mb-4">
        <h3 class="text-lg font-medium text-gray-900 dark:text-gray-100">
          Upload Queue ({{ uploadQueue.length }})
        </h3>
        
        <div class="flex space-x-2">
          <button
            v-if="!isUploading"
            @click="uploadAllFiles"
            class="px-3 py-1 bg-blue-600 text-white rounded hover:bg-blue-700 text-sm"
            :disabled="uploadQueue.filter(f => f.status === 'pending').length === 0"
          >
            Upload All
          </button>
          
          <button
            @click="clearCompleted"
            class="px-3 py-1 bg-gray-600 text-white rounded hover:bg-gray-700 text-sm"
          >
            Clear Completed
          </button>
        </div>
      </div>
      
      <!-- Overall progress -->
      <div v-if="isUploading" class="mb-4">
        <div class="flex items-center justify-between text-sm text-gray-600 dark:text-gray-400 mb-1">
          <span>Overall Progress</span>
          <span>{{ overallProgress }}%</span>
        </div>
        <div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2">
          <div 
            class="bg-blue-600 h-2 rounded-full transition-all duration-300"
            :style="{ width: `${overallProgress}%` }"
          ></div>
        </div>
      </div>
      
      <!-- File list -->
      <div class="space-y-3 max-h-96 overflow-y-auto">
        <div
          v-for="uploadFile in uploadQueue"
          :key="uploadFile.id"
          class="border border-gray-200 dark:border-gray-600 rounded-lg p-4"
        >
          <div class="flex items-start justify-between">
            <div class="flex items-center space-x-3 flex-1">
              <Icon 
                :name="getStatusIcon(uploadFile.status)" 
                class="w-5 h-5 flex-shrink-0"
                :class="`text-${getStatusColor(uploadFile.status)}-500`"
              />
              
              <div class="flex-1 min-w-0">
                <h4 class="text-sm font-medium text-gray-900 dark:text-gray-100 truncate">
                  {{ uploadFile.name }}
                </h4>
                <p class="text-xs text-gray-500 dark:text-gray-400">
                  {{ formatFileSize(uploadFile.size) }} • {{ uploadFile.extension.toUpperCase() }}
                </p>
                
                <!-- Progress bar -->
                <div v-if="uploadFile.status === 'uploading'" class="mt-2">
                  <div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-1">
                    <div 
                      class="bg-blue-600 h-1 rounded-full transition-all duration-300"
                      :style="{ width: `${uploadFile.progress}%` }"
                    ></div>
                  </div>
                </div>
                
                <!-- Errors -->
                <div v-if="uploadFile.errors.length > 0" class="mt-2">
                  <p class="text-xs text-red-600 dark:text-red-400">
                    {{ uploadFile.errors.join(', ') }}
                  </p>
                </div>
              </div>
            </div>
            
            <button
              v-if="uploadFile.status !== 'uploading'"
              @click="removeFromQueue(uploadFile.id)"
              class="ml-2 p-1 text-gray-400 hover:text-red-600"
            >
              <Icon name="mdi:close" class="w-4 h-4" />
            </button>
          </div>
          
          <!-- Metadata form for pending files -->
          <div v-if="uploadFile.status === 'pending'" class="mt-4 pt-4 border-t border-gray-200 dark:border-gray-600">
            <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
              <div>
                <label class="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">
                  Title
                </label>
                <input
                  v-model="uploadFile.metadata.title"
                  type="text"
                  class="w-full px-2 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700"
                />
              </div>
              
              <div>
                <label class="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">
                  Department
                </label>
                <select
                  v-model="uploadFile.metadata.department"
                  class="w-full px-2 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700"
                >
                  <option value="">Select Department</option>
                  <option value="HR">HR Department</option>
                  <option value="Finance">Finance</option>
                  <option value="IT">IT</option>
                  <option value="Legal">Legal</option>
                </select>
              </div>
              
              <div class="md:col-span-2">
                <label class="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">
                  Description
                </label>
                <textarea
                  v-model="uploadFile.metadata.description"
                  rows="2"
                  class="w-full px-2 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700"
                  placeholder="Brief description of the document..."
                ></textarea>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.drop-zone {
  min-height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
}
</style> 