<template>
  <v-dialog
    v-model="isOpen"
    max-width="90vw"
    max-height="90vh"
    scrollable
  >
    <v-card v-if="file">
      <v-card-title class="d-flex align-center justify-space-between">
        <div class="d-flex align-center">
          <v-icon class="mr-2">{{ file.icon }}</v-icon>
          <span>{{ file.displayName }}</span>
        </div>
        <v-btn
          icon
          variant="text"
          @click="closeModal"
        >
          <v-icon>mdi-close</v-icon>
        </v-btn>
      </v-card-title>
      
      <v-card-text class="pa-0">
        <!-- Loading State -->
        <div v-if="loading" class="text-center pa-10">
          <v-progress-circular
            indeterminate
            color="primary"
            size="64"
          />
          <p class="mt-4">Loading preview...</p>
        </div>
        
        <!-- Error State -->
        <div v-else-if="error" class="text-center pa-10">
          <v-icon size="64" color="error">mdi-alert-circle</v-icon>
          <p class="mt-4">{{ error }}</p>
        </div>
        
        <!-- Image Preview -->
        <div v-else-if="isImage" class="image-preview-container">
          <img 
            :src="previewUrl" 
            :alt="file.displayName"
            class="image-preview"
            @load="loading = false"
            @error="handlePreviewError"
          />
        </div>
        
        <!-- PDF Preview -->
        <div v-else-if="isPdf" class="pdf-preview-container">
          <embed
            :src="previewUrl"
            type="application/pdf"
            width="100%"
            height="100%"
          />
        </div>
      </v-card-text>
      
      <v-card-actions>
        <v-spacer />
        <v-btn
          color="primary"
          variant="outlined"
          @click="downloadFile"
          prepend-icon="mdi-download"
        >
          Download
        </v-btn>
        <v-btn
          color="primary"
          variant="flat"
          @click="closeModal"
        >
          Close
        </v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>

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

interface FileItem {
  name: string;
  size: number;
  sizeFormatted: string;
  lastModified: string;
  extension: string;
  icon: string;
  displayName: string;
  isFolder: boolean;
}

interface Props {
  modelValue: boolean;
  file: FileItem | null;
}

interface Emits {
  (e: 'update:modelValue', value: boolean): void;
}

const props = defineProps<Props>();
const emit = defineEmits<Emits>();

const loading = ref(false);
const error = ref('');
const previewUrl = ref('');
const objectUrl = ref('');

// Computed property for v-model binding
const isOpen = computed({
  get: () => props.modelValue,
  set: (value: boolean) => emit('update:modelValue', value),
});

// Check if file is an image
const isImage = computed(() => {
  if (!props.file) return false;
  const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'svg', 'webp'];
  return imageExtensions.includes(props.file.extension.toLowerCase());
});

// Check if file is a PDF
const isPdf = computed(() => {
  if (!props.file) return false;
  return props.file.extension.toLowerCase() === 'pdf';
});

// Watch for file changes and load preview
watch(() => props.file, async (newFile) => {
  if (newFile && props.modelValue) {
    await loadPreview();
  }
});

// Watch for dialog open and load preview
watch(() => props.modelValue, async (isOpen) => {
  if (isOpen && props.file) {
    await loadPreview();
  }
});

// Load preview URL
const loadPreview = async () => {
  if (!props.file) return;
  
  loading.value = true;
  error.value = '';
  previewUrl.value = '';
  
  // Clean up previous object URL if exists
  if (objectUrl.value) {
    URL.revokeObjectURL(objectUrl.value);
    objectUrl.value = '';
  }
  
  try {
    // For images and PDFs, fetch as blob and create object URL
    if (isImage.value || isPdf.value) {
      // Fetch the file as a blob
      const response = await fetch(`/api/files/proxy-preview?fileName=${encodeURIComponent(props.file.name)}`);
      
      if (!response.ok) {
        throw new Error('Failed to fetch file');
      }
      
      const blob = await response.blob();
      
      // Create object URL from blob
      objectUrl.value = URL.createObjectURL(blob);
      previewUrl.value = objectUrl.value;
      
      console.log('Created object URL for preview:', objectUrl.value);
      
      // Set loading to false after a short delay to allow the component to render
      setTimeout(() => {
        loading.value = false;
      }, 100);
    } else {
      throw new Error('File type does not support preview');
    }
  } catch (err: any) {
    error.value = err.message || 'Failed to load preview';
    loading.value = false;
  }
};

// Handle preview load error
const handlePreviewError = (event: any) => {
  console.error('Preview load error:', event);
  console.error('Current preview URL:', previewUrl.value);
  error.value = 'Failed to load preview';
  loading.value = false;
};

// Download file
const downloadFile = async () => {
  if (!props.file) return;
  
  try {
    const response = await $fetch('/api/files/download', {
      params: { fileName: props.file.name },
    });
    
    window.open(response.url, '_blank');
  } catch (err) {
    console.error('Failed to download file:', err);
  }
};

// Close modal
const closeModal = () => {
  isOpen.value = false;
  previewUrl.value = '';
  error.value = '';
  
  // Clean up object URL
  if (objectUrl.value) {
    URL.revokeObjectURL(objectUrl.value);
    objectUrl.value = '';
  }
};

// Clean up on unmount
onUnmounted(() => {
  if (objectUrl.value) {
    URL.revokeObjectURL(objectUrl.value);
  }
});
</script>

<style scoped>
.image-preview-container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 400px;
  max-height: 70vh;
  overflow: auto;
  background-color: #f5f5f5;
}

.image-preview {
  max-width: 100%;
  max-height: 70vh;
  object-fit: contain;
}

.pdf-preview-container {
  width: 100%;
  height: 70vh;
  overflow: hidden;
}
</style>
