<template>
  <div class="pdf-viewer w-full h-full bg-gray-100 dark:bg-gray-900 relative overflow-hidden">
    <!-- PDF Canvas Container -->
    <div 
      ref="canvasContainer"
      class="pdf-canvas-container w-full h-full overflow-auto scroll-smooth"
      @wheel="handleWheel"
      @mousedown="handleMouseDown"
      @mousemove="handleMouseMove"
      @mouseup="handleMouseUp"
    >
      <div class="flex flex-col items-center py-8 space-y-4">
        <!-- Page Canvas -->
        <div
          v-for="pageNum in totalPages"
          :key="pageNum"
          :ref="el => setPageRef(el, pageNum)"
          class="page-container bg-white shadow-lg relative"
          :style="{ 
            transform: `scale(${zoom / 100})`,
            transformOrigin: 'top center'
          }"
        >
          <canvas
            :id="`pdf-page-${pageNum}`"
            class="pdf-page border border-gray-300"
            @contextmenu.prevent
          ></canvas>
          
          <!-- Annotation Layer -->
          <div 
            class="annotation-layer absolute inset-0 pointer-events-none"
            :style="{ transform: `scale(${zoom / 100})` }"
          >
            <!-- Highlights -->
            <div
              v-for="highlight in getPageAnnotations(pageNum, 'highlight')"
              :key="highlight.id"
              class="absolute pointer-events-auto cursor-pointer"
              :style="{
                left: highlight.x + 'px',
                top: highlight.y + 'px',
                width: highlight.width + 'px',
                height: highlight.height + 'px',
                backgroundColor: highlight.color + '40',
                border: `2px solid ${highlight.color}`
              }"
              @click="editAnnotation(highlight)"
              @contextmenu.prevent="deleteAnnotation(highlight.id)"
              :title="`${highlight.text} - ${highlight.author}`"
            ></div>
            
            <!-- Comments -->
            <div
              v-for="comment in getPageAnnotations(pageNum, 'comment')"
              :key="comment.id"
              class="absolute pointer-events-auto"
              :style="{
                left: comment.x + 'px',
                top: comment.y + 'px'
              }"
            >
              <button
                @click="showCommentDialog(comment)"
                class="w-6 h-6 bg-blue-500 text-white rounded-full flex items-center justify-center text-xs font-bold shadow-lg hover:bg-blue-600 transition-colors"
                :title="comment.text"
              >
                <Icon name="mdi:comment" class="w-3 h-3" />
              </button>
            </div>
            
            <!-- Drawings -->
            <svg
              v-for="drawing in getPageAnnotations(pageNum, 'draw')"
              :key="drawing.id"
              class="absolute pointer-events-auto"
              :style="{
                left: '0px',
                top: '0px',
                width: '100%',
                height: '100%'
              }"
              @contextmenu.prevent="deleteAnnotation(drawing.id)"
            >
              <path
                :d="drawing.path"
                :stroke="drawing.color"
                :stroke-width="drawing.strokeWidth || 2"
                fill="none"
                stroke-linecap="round"
                stroke-linejoin="round"
              />
            </svg>
          </div>
          
          <!-- Page Number -->
          <div class="absolute bottom-2 right-2 bg-black bg-opacity-50 text-white px-2 py-1 rounded text-xs">
            {{ pageNum }}
          </div>
        </div>
      </div>
    </div>
    
    <!-- Drawing Canvas Overlay (for annotation mode) -->
    <canvas
      v-if="annotationMode === 'draw'"
      ref="drawingCanvas"
      class="absolute inset-0 cursor-crosshair pointer-events-auto"
      @mousedown="startDrawing"
      @mousemove="draw"
      @mouseup="endDrawing"
      @mouseleave="endDrawing"
    ></canvas>
    
    <!-- Loading Overlay -->
    <div 
      v-if="isLoading"
      class="absolute inset-0 bg-white bg-opacity-90 flex items-center justify-center z-10"
    >
      <div class="text-center">
        <Icon name="mdi:loading" class="w-8 h-8 animate-spin text-blue-600 mx-auto mb-2" />
        <p class="text-gray-600">Loading PDF...</p>
        <div class="w-48 bg-gray-200 rounded-full h-2 mt-2">
          <div 
            class="bg-blue-600 h-2 rounded-full transition-all duration-300"
            :style="{ width: `${loadingProgress}%` }"
          ></div>
        </div>
        <p class="text-xs text-gray-500 mt-1">Page {{ currentLoadingPage }} of {{ totalPages }}</p>
      </div>
    </div>

    <!-- Comment Dialog -->
    <div
      v-if="showingComment"
      class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
      @click="closeCommentDialog"
    >
      <div 
        class="bg-white dark:bg-gray-800 rounded-lg p-6 max-w-md w-full mx-4"
        @click.stop
      >
        <div class="flex items-center justify-between mb-4">
          <h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100">Comment</h3>
          <button
            @click="closeCommentDialog"
            class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300"
          >
            <Icon name="mdi:close" class="w-5 h-5" />
          </button>
        </div>
        
        <div class="space-y-4">
          <div>
            <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
              Comment Text
            </label>
            <textarea
              v-model="commentText"
              class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md 
                     bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100
                     focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
              rows="3"
              placeholder="Enter your comment..."
            ></textarea>
          </div>
          
          <div class="flex justify-end space-x-2">
            <button
              @click="closeCommentDialog"
              class="px-4 py-2 text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200"
            >
              Cancel
            </button>
            <button
              @click="saveComment"
              class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700"
            >
              {{ editingComment ? 'Update' : 'Save' }}
            </button>
          </div>
        </div>
      </div>
    </div>

    <!-- Page Navigation Thumbnail Strip -->
    <div 
      v-if="totalPages > 1 && showThumbnails"
      class="absolute left-4 top-1/2 transform -translate-y-1/2 bg-white dark:bg-gray-800 rounded-lg shadow-lg p-2 max-h-80 overflow-y-auto"
    >
      <div class="space-y-2">
        <div
          v-for="pageNum in totalPages"
          :key="`thumb-${pageNum}`"
          @click="scrollToPage(pageNum)"
          :class="[
            'thumbnail-page cursor-pointer border-2 transition-all',
            currentVisiblePage === pageNum 
              ? 'border-blue-500 shadow-md' 
              : 'border-gray-300 dark:border-gray-600 hover:border-blue-300'
          ]"
        >
          <canvas
            :id="`pdf-thumbnail-${pageNum}`"
            class="thumbnail-canvas"
            :width="60"
            :height="80"
          ></canvas>
          <div class="text-xs text-center py-1">{{ pageNum }}</div>
        </div>
      </div>
    </div>

    <!-- Zoom Level Indicator -->
    <div 
      v-if="showZoomIndicator"
      class="absolute top-4 left-1/2 transform -translate-x-1/2 bg-black bg-opacity-70 text-white px-3 py-1 rounded-full text-sm"
    >
      {{ Math.round(zoom) }}%
    </div>
  </div>
</template>

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

// PDF.js imports (in real implementation)
// import * as pdfjsLib from 'pdfjs-dist';

const props = defineProps({
  document: {
    type: Object,
    required: true
  },
  mode: {
    type: String,
    default: 'view' // 'view' | 'edit'
  },
  annotations: {
    type: Array,
    default: () => []
  },
  zoom: {
    type: Number,
    default: 100
  },
  annotationMode: {
    type: String,
    default: null // 'highlight' | 'comment' | 'draw' | null
  }
});

const emit = defineEmits([
  'annotation-added',
  'annotation-updated',
  'annotation-deleted',
  'page-changed',
  'zoom-changed'
]);

// State
const isLoading = ref(true);
const loadingProgress = ref(0);
const currentLoadingPage = ref(0);
const totalPages = ref(1);
const currentVisiblePage = ref(1);
const zoom = ref(props.zoom);
const showThumbnails = ref(false);
const showZoomIndicator = ref(false);

// PDF.js state
const pdfDocument = ref(null);
const pageRefs = ref(new Map());
const renderedPages = ref(new Set());

// Annotation state
const isAnnotating = ref(false);
const currentAnnotation = ref(null);
const showingComment = ref(false);
const commentText = ref('');
const editingComment = ref(null);

// Drawing state
const isDrawing = ref(false);
const drawingPath = ref('');
const drawingStartPoint = ref(null);

// Container refs
const canvasContainer = ref(null);
const drawingCanvas = ref(null);

// Computed
const annotationMode = computed(() => props.annotationMode);

// Methods
const setPageRef = (el, pageNum) => {
  if (el) {
    pageRefs.value.set(pageNum, el);
  }
};

const loadPDF = async () => {
  isLoading.value = true;
  loadingProgress.value = 0;
  
  try {
    // Mock PDF loading - in real implementation, use PDF.js
    // const loadingTask = pdfjsLib.getDocument(props.document.url);
    // pdfDocument.value = await loadingTask.promise;
    
    // Mock implementation
    await simulatePDFLoading();
    
    // Render initial pages
    await renderVisiblePages();
    await generateThumbnails();
    
  } catch (error) {
    console.error('Failed to load PDF:', error);
  } finally {
    isLoading.value = false;
  }
};

const simulatePDFLoading = async () => {
  // Simulate PDF loading with progress
  totalPages.value = Math.floor(Math.random() * 10) + 5; // 5-15 pages
  
  for (let i = 1; i <= totalPages.value; i++) {
    currentLoadingPage.value = i;
    loadingProgress.value = (i / totalPages.value) * 100;
    await new Promise(resolve => setTimeout(resolve, 200));
  }
};

const renderVisiblePages = async () => {
  // Get visible pages based on scroll position
  const container = canvasContainer.value;
  if (!container) return;
  
  const containerRect = container.getBoundingClientRect();
  const containerTop = container.scrollTop;
  const containerBottom = containerTop + containerRect.height;
  
  // Find visible pages
  for (let pageNum = 1; pageNum <= totalPages.value; pageNum++) {
    const pageElement = pageRefs.value.get(pageNum);
    if (!pageElement) continue;
    
    const pageRect = pageElement.getBoundingClientRect();
    const pageTop = pageElement.offsetTop;
    const pageBottom = pageTop + pageRect.height;
    
    // Check if page is visible with some buffer
    const buffer = 200;
    if (pageBottom >= containerTop - buffer && pageTop <= containerBottom + buffer) {
      if (!renderedPages.value.has(pageNum)) {
        await renderPage(pageNum);
        renderedPages.value.add(pageNum);
      }
    }
  }
  
  // Update current visible page
  updateCurrentVisiblePage();
};

const renderPage = async (pageNum) => {
  const canvas = document.getElementById(`pdf-page-${pageNum}`);
  if (!canvas) return;
  
  const ctx = canvas.getContext('2d');
  
  // Mock rendering - in real implementation, use PDF.js page.render()
  canvas.width = 600;
  canvas.height = 800;
  
  // Fill with white background
  ctx.fillStyle = '#ffffff';
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  
  // Add some mock content
  ctx.fillStyle = '#333333';
  ctx.font = '16px Arial';
  ctx.fillText(`Page ${pageNum} Content`, 50, 50);
  
  // Add some mock text lines
  for (let i = 0; i < 20; i++) {
    ctx.fillText(`This is line ${i + 1} of page ${pageNum}`, 50, 100 + i * 25);
  }
};

const generateThumbnails = async () => {
  for (let pageNum = 1; pageNum <= totalPages.value; pageNum++) {
    const canvas = document.getElementById(`pdf-thumbnail-${pageNum}`);
    if (!canvas) continue;
    
    const ctx = canvas.getContext('2d');
    
    // Mock thumbnail generation
    ctx.fillStyle = '#ffffff';
    ctx.fillRect(0, 0, 60, 80);
    ctx.fillStyle = '#cccccc';
    ctx.fillRect(5, 5, 50, 70);
    ctx.fillStyle = '#333333';
    ctx.font = '8px Arial';
    ctx.fillText(`P${pageNum}`, 25, 40);
  }
};

const updateCurrentVisiblePage = () => {
  const container = canvasContainer.value;
  if (!container) return;
  
  const containerTop = container.scrollTop;
  const containerCenter = containerTop + container.clientHeight / 2;
  
  let closestPage = 1;
  let closestDistance = Infinity;
  
  for (let pageNum = 1; pageNum <= totalPages.value; pageNum++) {
    const pageElement = pageRefs.value.get(pageNum);
    if (!pageElement) continue;
    
    const pageTop = pageElement.offsetTop;
    const pageCenter = pageTop + pageElement.clientHeight / 2;
    const distance = Math.abs(pageCenter - containerCenter);
    
    if (distance < closestDistance) {
      closestDistance = distance;
      closestPage = pageNum;
    }
  }
  
  if (closestPage !== currentVisiblePage.value) {
    currentVisiblePage.value = closestPage;
    emit('page-changed', closestPage);
  }
};

const scrollToPage = (pageNum) => {
  const pageElement = pageRefs.value.get(pageNum);
  if (!pageElement || !canvasContainer.value) return;
  
  const container = canvasContainer.value;
  const pageTop = pageElement.offsetTop;
  const containerHeight = container.clientHeight;
  const pageHeight = pageElement.clientHeight;
  
  // Center the page in the viewport
  const scrollTop = pageTop - (containerHeight - pageHeight) / 2;
  
  container.scrollTo({
    top: Math.max(0, scrollTop),
    behavior: 'smooth'
  });
};

// Annotation methods
const getPageAnnotations = (pageNum, type) => {
  return props.annotations.filter(annotation => 
    annotation.page === pageNum && annotation.type === type
  );
};

const handleMouseDown = (event) => {
  if (!annotationMode.value) return;
  
  const rect = event.target.getBoundingClientRect();
  const x = event.clientX - rect.left;
  const y = event.clientY - rect.top;
  
  if (annotationMode.value === 'highlight') {
    startHighlight(x, y, event.target);
  } else if (annotationMode.value === 'comment') {
    addComment(x, y, event.target);
  }
};

const handleMouseMove = (event) => {
  if (!isAnnotating.value || annotationMode.value !== 'highlight') return;
  
  const rect = event.target.getBoundingClientRect();
  const x = event.clientX - rect.left;
  const y = event.clientY - rect.top;
  
  updateHighlight(x, y);
};

const handleMouseUp = () => {
  if (isAnnotating.value && annotationMode.value === 'highlight') {
    finishHighlight();
  }
};

const startHighlight = (x, y, canvas) => {
  const pageNum = getPageNumberFromCanvas(canvas);
  if (!pageNum) return;
  
  isAnnotating.value = true;
  currentAnnotation.value = {
    type: 'highlight',
    page: pageNum,
    x: x,
    y: y,
    width: 0,
    height: 20,
    color: '#ffff00',
    text: 'Highlighted text',
    author: 'Current User',
    timestamp: new Date().toISOString()
  };
};

const updateHighlight = (x, y) => {
  if (!currentAnnotation.value) return;
  
  currentAnnotation.value.width = x - currentAnnotation.value.x;
  currentAnnotation.value.height = Math.max(20, y - currentAnnotation.value.y);
};

const finishHighlight = () => {
  if (!currentAnnotation.value) return;
  
  const annotation = {
    ...currentAnnotation.value,
    id: Date.now().toString()
  };
  
  emit('annotation-added', annotation);
  
  isAnnotating.value = false;
  currentAnnotation.value = null;
};

const addComment = (x, y, canvas) => {
  const pageNum = getPageNumberFromCanvas(canvas);
  if (!pageNum) return;
  
  currentAnnotation.value = {
    type: 'comment',
    page: pageNum,
    x: x,
    y: y,
    text: '',
    author: 'Current User',
    timestamp: new Date().toISOString()
  };
  
  commentText.value = '';
  editingComment.value = null;
  showingComment.value = true;
};

const showCommentDialog = (comment) => {
  editingComment.value = comment;
  commentText.value = comment.text;
  showingComment.value = true;
};

const closeCommentDialog = () => {
  showingComment.value = false;
  commentText.value = '';
  editingComment.value = null;
  currentAnnotation.value = null;
};

const saveComment = () => {
  if (editingComment.value) {
    // Update existing comment
    const updatedComment = {
      ...editingComment.value,
      text: commentText.value,
      timestamp: new Date().toISOString()
    };
    emit('annotation-updated', updatedComment);
  } else if (currentAnnotation.value) {
    // Create new comment
    const annotation = {
      ...currentAnnotation.value,
      id: Date.now().toString(),
      text: commentText.value
    };
    emit('annotation-added', annotation);
  }
  
  closeCommentDialog();
};

const editAnnotation = (annotation) => {
  if (annotation.type === 'comment') {
    showCommentDialog(annotation);
  }
};

const deleteAnnotation = (annotationId) => {
  if (confirm('Delete this annotation?')) {
    emit('annotation-deleted', annotationId);
  }
};

// Drawing methods
const startDrawing = (event) => {
  if (annotationMode.value !== 'draw') return;
  
  isDrawing.value = true;
  const rect = drawingCanvas.value.getBoundingClientRect();
  const x = event.clientX - rect.left;
  const y = event.clientY - rect.top;
  
  drawingStartPoint.value = { x, y };
  drawingPath.value = `M ${x} ${y}`;
};

const draw = (event) => {
  if (!isDrawing.value || annotationMode.value !== 'draw') return;
  
  const rect = drawingCanvas.value.getBoundingClientRect();
  const x = event.clientX - rect.left;
  const y = event.clientY - rect.top;
  
  drawingPath.value += ` L ${x} ${y}`;
  
  // Draw on canvas for immediate feedback
  const ctx = drawingCanvas.value.getContext('2d');
  ctx.lineTo(x, y);
  ctx.stroke();
};

const endDrawing = () => {
  if (!isDrawing.value) return;
  
  isDrawing.value = false;
  
  // Create annotation from drawing
  const annotation = {
    id: Date.now().toString(),
    type: 'draw',
    page: currentVisiblePage.value,
    path: drawingPath.value,
    color: '#ff0000',
    strokeWidth: 2,
    author: 'Current User',
    timestamp: new Date().toISOString()
  };
  
  emit('annotation-added', annotation);
  
  // Clear drawing canvas
  const ctx = drawingCanvas.value.getContext('2d');
  ctx.clearRect(0, 0, drawingCanvas.value.width, drawingCanvas.value.height);
  
  drawingPath.value = '';
  drawingStartPoint.value = null;
};

// Utility methods
const getPageNumberFromCanvas = (canvas) => {
  const id = canvas.id;
  const match = id.match(/pdf-page-(\d+)/);
  return match ? parseInt(match[1]) : null;
};

const handleWheel = (event) => {
  if (event.ctrlKey || event.metaKey) {
    // Zoom with Ctrl + wheel
    event.preventDefault();
    const delta = event.deltaY > 0 ? -10 : 10;
    const newZoom = Math.max(25, Math.min(300, zoom.value + delta));
    zoom.value = newZoom;
    emit('zoom-changed', newZoom);
    
    // Show zoom indicator
    showZoomIndicator.value = true;
    setTimeout(() => {
      showZoomIndicator.value = false;
    }, 1000);
  } else {
    // Normal scroll - update visible pages
    nextTick(() => {
      renderVisiblePages();
    });
  }
};

// Watchers
watch(() => props.zoom, (newZoom) => {
  zoom.value = newZoom;
});

watch(() => props.document, () => {
  if (props.document) {
    loadPDF();
  }
});

watch(annotationMode, (newMode) => {
  if (newMode === 'draw' && drawingCanvas.value) {
    // Setup drawing canvas
    const container = canvasContainer.value;
    const canvas = drawingCanvas.value;
    canvas.width = container.scrollWidth;
    canvas.height = container.scrollHeight;
    
    const ctx = canvas.getContext('2d');
    ctx.strokeStyle = '#ff0000';
    ctx.lineWidth = 2;
    ctx.lineCap = 'round';
    ctx.lineJoin = 'round';
  }
});

// Lifecycle
onMounted(() => {
  if (props.document) {
    loadPDF();
  }
  
  // Setup scroll listener for lazy loading
  if (canvasContainer.value) {
    canvasContainer.value.addEventListener('scroll', () => {
      nextTick(() => {
        renderVisiblePages();
      });
    }, { passive: true });
  }
});

onUnmounted(() => {
  // Cleanup
  if (canvasContainer.value) {
    canvasContainer.value.removeEventListener('scroll', renderVisiblePages);
  }
});
</script>

<style scoped>
.pdf-viewer {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
}

.pdf-canvas-container {
  scroll-behavior: smooth;
}

.pdf-canvas-container::-webkit-scrollbar {
  width: 12px;
  height: 12px;
}

.pdf-canvas-container::-webkit-scrollbar-track {
  background: #f1f1f1;
}

.pdf-canvas-container::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 6px;
}

.pdf-canvas-container::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

.page-container {
  transition: transform 0.3s ease;
  margin-bottom: 20px;
}

.pdf-page {
  display: block;
  max-width: 100%;
  height: auto;
}

.annotation-layer {
  pointer-events: none;
}

.annotation-layer > * {
  pointer-events: auto;
}

.thumbnail-page {
  width: 60px;
  border-radius: 4px;
  overflow: hidden;
}

.thumbnail-canvas {
  display: block;
  width: 100%;
  height: auto;
}

/* Selection styles for text selection in annotation mode */
.pdf-viewer ::selection {
  background: rgba(255, 255, 0, 0.3);
}

.pdf-viewer ::-moz-selection {
  background: rgba(255, 255, 0, 0.3);
}

/* Annotation cursor styles */
.annotation-mode-highlight {
  cursor: text;
}

.annotation-mode-comment {
  cursor: crosshair;
}

.annotation-mode-draw {
  cursor: crosshair;
}

/* Smooth animations */
.page-container,
.thumbnail-page {
  transition: all 0.2s ease;
}

.annotation-layer > div {
  transition: opacity 0.2s ease;
}

/* Loading animation */
@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.animate-spin {
  animation: spin 1s linear infinite;
}
</style> 