<template>
  <el-dialog
    v-model="visible"
    :title="dialogTitle"
    :width="dialogWidth"
    :fullscreen="isFullscreen"
    :class="getDialogClass()"
    append-to-body
    height="100vh"
    top="0vh"
    :destroy-on-close="true"
    :close-on-click-modal="false"
    :close-on-press-escape="true"
    @close="handleClose"
  >
    <template #header="{ titleId, titleClass }">
      <div class="preview-header">
        <div class="preview-title-section">
          <h4 :id="titleId" :class="titleClass">
            <el-icon class="title-icon">
              <component :is="getFileIcon(fileInfo.type)" />
            </el-icon>
            {{ fileInfo.name }}
          </h4>
          <span class="file-size-info">{{ fileInfo.size }}</span>
        </div>
        <div class="preview-controls">
          <el-tooltip :content="isFullscreen ? '退出全屏' : '全屏显示'" placement="bottom">
            <el-button
              size="small"
              :icon="isFullscreen ? Minus : FullScreen"
              @click="toggleFullscreen"
              circle
              type="primary"
            />
          </el-tooltip>
          <el-tooltip content="刷新预览" placement="bottom">
            <el-button 
              size="small" 
              :icon="RefreshRight" 
              @click="refreshPreview" 
              circle 
            />
          </el-tooltip>
        </div>
      </div>
    </template>

    <div class="preview-container" v-loading="loading" :element-loading-text="getLoadingText()">
      <!-- PDF预览 -->
      <div 
        class="preview-content pdf-content" 
        v-if="!loading && !error && pdfBlobUrl"
        v-show="pdfLoaded"
      >
        <div class="pdf-embed-container">
          <transition name="pdf-fade" mode="out-in">
            <div :key="currentPage" class="pdf-page-wrapper">
              <VuePdfEmbed
                :source="pdfBlobUrl"
                :page="currentPage"
                :width="Math.floor(600 * scale)"
                class="pdf-embed"
                @loaded="handlePdfLoaded"
                @loading-failed="handlePdfError"
                @progress="handlePdfProgress"
                @rendered="handlePageRendered"
              />
            </div>
          </transition>
          
          <!-- PDF控制栏 - 集成所有按钮 -->
          <div class="pdf-controls" v-if="totalPages > 0">
            <!-- 翻页控制 -->
            <el-button-group>
              <el-button 
                size="small" 
                :disabled="currentPage <= 1"
                @click="goToPage(currentPage - 1)"
                :icon="ArrowLeft"
              >
                上一页
              </el-button>
              <el-input
                v-model.number="pageInput"
                size="small"
                class="page-input"
                @keyup.enter="goToInputPage"
                @blur="goToInputPage"
              />
              <span class="page-separator">/</span>
              <span class="total-pages">{{ totalPages }}</span>
              <el-button 
                size="small" 
                :disabled="currentPage >= totalPages"
                @click="goToPage(currentPage + 1)"
                :icon="ArrowRight"
              >
                下一页
              </el-button>
            </el-button-group>
            
            <!-- 缩放控制 -->
            <el-button-group class="zoom-controls">
              <el-button 
                size="small" 
                @click="zoomOut"
                :disabled="scale <= 0.5"
                :icon="ZoomOut"
              >
                缩小
              </el-button>
              <span class="zoom-display">{{ Math.round(scale * 100) }}%</span>
              <el-button 
                size="small" 
                @click="zoomIn"
                :disabled="scale >= 3"
                :icon="ZoomIn"
              >
                放大
              </el-button>
              <el-button 
                size="small" 
                @click="resetZoom"
                :icon="RefreshRight"
              >
                重置
              </el-button>
            </el-button-group>

            <!-- 操作按钮 -->
            <el-button-group class="action-controls">
              <el-button 
                size="small"
                :icon="Download" 
                @click="downloadFile"
                :disabled="!pdfBlobUrl"
              > 
                下载
              </el-button>
              <el-button 
                size="small"
                :icon="Share" 
                @click="openPdfInNewWindow"
                :disabled="!pdfBlobUrl"
              > 
                浏览器打开
              </el-button>
              <el-button 
                size="small"
                @click="handleClose"
              >
                关闭
              </el-button>
            </el-button-group>
          </div>
        </div>
      </div>
      
      <!-- 预览错误状态 -->
      <div v-else-if="error || (!loading && !pdfBlobUrl)" class="preview-error">
        <el-icon size="64" color="#f56c6c">
          <WarningFilled />
        </el-icon>
        <p class="error-title">无法预览此PDF文档</p>
        <p class="error-tip">可能的原因：</p>
        <ul class="error-reasons">
          <li>网络连接问题</li>
          <li>文件获取失败</li>
          <li>PDF文件损坏或格式不正确</li>
          <li>服务器返回错误</li>
          <li>PDF文件过大</li>
          <li>PDF文件受密码保护</li>
        </ul>
        <div class="error-actions">
          <el-button type="primary" @click="openPdfInNewWindow">
            浏览器中打开
          </el-button>
          <el-button @click="refreshPreview">重试</el-button>
        </div>
      </div>
    </div>
  </el-dialog>
</template>
<script setup>
import {
  Download,
  FullScreen,
  Minus,
  WarningFilled,
  RefreshRight,
  Share,
  Document,
  ArrowLeft,
  ArrowRight,
  ZoomIn,
  ZoomOut
} from '@element-plus/icons-vue'
import { ref, computed, watch, onMounted, onUnmounted, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import VuePdfEmbed from 'vue-pdf-embed'
import 'vue-pdf-embed/dist/styles/annotationLayer.css'
import 'vue-pdf-embed/dist/styles/textLayer.css'
import { previewPrepareReport } from '@/api/laboratory/functional/report'
import { PipeTaskOrderApi } from '@/api/pressure2/pipetaskorder'

const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false
  },
  id: {
    type: String,
    required: true
  },
  isEditOtherFileFlag: {
    type: Boolean,
    default: false
  },
  filename: {
    type: String,
    default: ''
  },
  title: {
    type: String,
    default: '文件预览'
  }
})

const emit = defineEmits(['update:modelValue', 'close'])

// 响应式数据
const visible = ref(false)
const loading = ref(false)
const error = ref(false)
const isFullscreen = ref(false)
const pdfBlobUrl = ref('')
const actualFileSize = ref(0)
const pdfLoaded = ref(false) // 新增：标记PDF是否已加载完成

// PDF 相关状态
const currentPage = ref(1)
const totalPages = ref(0)
const scale = ref(2.0)
const pageInput = ref(1)
const isPageChanging = ref(false) // 新增：标记页面切换状态

// 文件信息
const fileInfo = computed(() => {
  const filename = props.filename || 'report.pdf'
  const filesize = formatFileSize(actualFileSize.value)
  
  return {
    name: filename,
    size: filesize || '计算中...',
    type: 'application/pdf',
    id: props.id
  }
})

// 计算属性
const dialogTitle = computed(() => {
  return `PDF预览${fileInfo.value.name ? ' - ' + fileInfo.value.name : ''}`
})

const dialogWidth = computed(() => {
  if (isFullscreen.value) return '100%'
  return window.innerWidth > 1400 ? '85%' : window.innerWidth > 1200 ? '90%' : '95%'
})

// 获取文件图标
const getFileIcon = (type) => {
  return Document
}

// 获取对话框样式类
const getDialogClass = () => {
  return 'pdf-preview-dialog'
}

// 获取加载文本
const getLoadingText = () => {
  return '正在加载PDF文档...'
}

// 工具函数
const formatFileSize = (size) => {
  if (!size || size === 0) return ''
  
  const bytes = Number(size)
  if (isNaN(bytes) || bytes === 0) return ''
  
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

// 优化后的加载预览函数
const loadPreview = async () => {
  if (!props.id) {
    error.value = true
    return
  }
  
  // 只在真正需要重新加载时才清理blob URL
  const shouldReload = !pdfBlobUrl.value
  
  if (shouldReload && pdfBlobUrl.value) {
    URL.revokeObjectURL(pdfBlobUrl.value)
    pdfBlobUrl.value = ''
  }
  
  // 重置状态
  error.value = false
  if (shouldReload) {
    currentPage.value = 1
    totalPages.value = 0
    pageInput.value = 1
    scale.value = 2.0
    actualFileSize.value = 0
    pdfLoaded.value = false
  }
  loading.value = true
  
  try {
    console.log('开始获取PDF文件流...')
    
    const data = {
      id: props.id,
      // type: '1'
    }
    // if (props.isEditOtherFileFlag == false) {
    //   delete data.type
    // }
    const response = await PipeTaskOrderApi.getIssueReportUseLogoPreviewApi(data, {
      responseType: 'blob',
      headers: {
        'Accept': 'application/pdf, application/octet-stream, */*'
      }
    })
    
    console.log('获取到文件流响应:', response)
    
    let blob
    
    if (response instanceof Blob) {
      blob = response
      if (!blob.type.includes('pdf') && !blob.type.includes('octet-stream') && blob.type !== '') {
        if (blob.type.includes('text') || blob.type.includes('xml') || blob.type.includes('html')) {
          const text = await blob.text()
          console.error('API返回非PDF数据:', text)
          throw new Error('服务器返回的不是PDF文件，可能是错误信息')
        }
      }
      if (!blob.type.includes('pdf')) {
        blob = new Blob([blob], { type: 'application/pdf' })
      }
    } else if (response instanceof ArrayBuffer) {
      blob = new Blob([response], { type: 'application/pdf' })
    } else if (response.data) {
      if (response.data instanceof Blob) {
        blob = response.data
        if (!blob.type.includes('pdf')) {
          blob = new Blob([blob], { type: 'application/pdf' })
        }
      } else if (response.data instanceof ArrayBuffer) {
        blob = new Blob([response.data], { type: 'application/pdf' })
      } else {
        if (typeof response.data === 'string') {
          console.error('API返回字符串数据:', response.data)
          throw new Error('服务器返回的不是PDF文件数据')
        }
        blob = new Blob([response.data], { type: 'application/pdf' })
      }
    }
     else {
      if (typeof response === 'string') {
        console.error('API返回字符串数据:', response)
        throw new Error('服务器返回的不是PDF文件数据')
      }
      blob = new Blob([response], { type: 'application/pdf' })
    }
    
    console.log('创建的Blob:', blob, 'size:', blob.size, 'type:', blob.type)
    
    if (!blob || blob.size === 0) {
      throw new Error('获取到的文件为空')
    }
    
    await validatePdfBlob(blob)
    
    actualFileSize.value = blob.size
    console.log('自动获取的文件大小:', formatFileSize(blob.size))
    
    const blobUrl = URL.createObjectURL(blob)
    pdfBlobUrl.value = blobUrl
    
    console.log('创建的Blob URL:', blobUrl)
    
    await nextTick()
    
  } catch (error) {
    console.error('PDF加载失败:', error)
    handlePdfError(error)
    ElMessage.error('PDF文件加载失败: ' + (error.message || '未知错误'))
  } finally {
    loading.value = false
  }
}

const validatePdfBlob = async (blob) => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    
    reader.onload = function(e) {
      const arrayBuffer = e.target.result
      const uint8Array = new Uint8Array(arrayBuffer.slice(0, 10))
      
      const pdfHeader = [0x25, 0x50, 0x44, 0x46, 0x2D]
      const headerMatch = pdfHeader.every((byte, index) => uint8Array[index] === byte)
      
      if (!headerMatch) {
        const text = new TextDecoder().decode(uint8Array)
        if (text.includes('<') || text.includes('<?xml')) {
          reject(new Error('服务器返回的是XML/HTML错误响应，不是PDF文件'))
          return
        }
        reject(new Error('文件格式不正确，不是有效的PDF文件'))
        return
      }
      
      resolve()
    }
    
    reader.onerror = function() {
      reject(new Error('文件读取失败'))
    }
    
    reader.readAsArrayBuffer(blob.slice(0, 1024))
  })
}

// PDF事件处理
const handlePdfLoaded = (pdf) => {
  console.log('PDF加载成功:', pdf)
  loading.value = false
  error.value = false
  totalPages.value = pdf.numPages
  pdfLoaded.value = true
  
  if (currentPage.value === 0 || currentPage.value > pdf.numPages) {
    currentPage.value = 1
    pageInput.value = 1
  }
  
  // ElMessage.success('PDF加载成功')
}

// 新增：处理页面渲染完成
const handlePageRendered = () => {
  isPageChanging.value = false
}

const handlePdfError = (errorInfo) => {
  console.error('PDF渲染错误:', errorInfo)
  loading.value = false
  error.value = true
  pdfLoaded.value = false
  isPageChanging.value = false
  ElMessage.error('PDF渲染失败，请尝试刷新或在浏览器中直接打开')
}

const handlePdfProgress = (progressParams) => {
  console.log('PDF加载进度:', progressParams)
}

// 优化页面导航 - 防止闪烁
const goToPage = (page) => {
  if (page >= 1 && page <= totalPages.value && !isPageChanging.value) {
    isPageChanging.value = true
    currentPage.value = page
    pageInput.value = page
    
    // 给一个小延迟让过渡动画更平滑
    setTimeout(() => {
      if (isPageChanging.value) {
        isPageChanging.value = false
      }
    }, 300)
  }
}

const goToInputPage = () => {
  const page = parseInt(pageInput.value)
  if (isNaN(page) || page < 1 || page > totalPages.value) {
    pageInput.value = currentPage.value
    ElMessage.warning('请输入有效的页码')
    return
  }
  goToPage(page)
}

// 其他事件处理函数
const refreshPreview = () => {
  pdfLoaded.value = false
  loadPreview()
}

const toggleFullscreen = () => {
  isFullscreen.value = !isFullscreen.value
}

const openPdfInNewWindow = () => {
  if (!pdfBlobUrl.value) return
  try {
    window.open(pdfBlobUrl.value, '_blank', 'noopener,noreferrer')
    ElMessage.success('已在新窗口打开PDF文件')
  } catch (error) {
    ElMessage.error('新窗口打开失败，请检查浏览器设置')
  }
}

const downloadFile = () => {
  if (!pdfBlobUrl.value) {
    ElMessage.warning('文件尚未加载完成')
    return
  }
  
  try {
    const link = document.createElement('a')
    link.href = pdfBlobUrl.value
    
    let filename = fileInfo.value.name
    if (!filename.toLowerCase().endsWith('.pdf')) {
      filename += '.pdf'
    }
    
    link.download = filename
    link.target = '_blank'
    link.rel = 'noopener noreferrer'
    
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    
    ElMessage.success('文件下载已开始')
  } catch (error) {
    console.error('下载失败:', error)
    ElMessage.error('下载失败，请重试')
  }
}

// 缩放控制
const zoomIn = () => {
  if (scale.value < 3) {
    scale.value = Math.min(Math.round((scale.value * 1.2) * 10) / 10, 3)
  }
}

const zoomOut = () => {
  if (scale.value > 0.5) {
    scale.value = Math.max(Math.round((scale.value / 1.2) * 10) / 10, 0.5)
  }
}

const resetZoom = () => {
  scale.value = 2.0
}

// 键盘快捷键支持
const handleKeydown = (event) => {
  if (!visible.value) return
  
  if (event.ctrlKey || event.metaKey) {
    if (event.key === '=' || event.key === '+') {
      event.preventDefault()
      zoomIn()
    } else if (event.key === '-') {
      event.preventDefault()
      zoomOut()
    } else if (event.key === '0') {
      event.preventDefault()
      resetZoom()
    }
  }
  
  // 支持方向键翻页
  if (event.key === 'ArrowLeft' && currentPage.value > 1) {
    event.preventDefault()
    goToPage(currentPage.value - 1)
  } else if (event.key === 'ArrowRight' && currentPage.value < totalPages.value) {
    event.preventDefault()
    goToPage(currentPage.value + 1)
  }
}

const handleClose = () => {
  visible.value = false
  emit('update:modelValue', false)
  emit('close')
  
  // 清理时保留blob URL，因为对话框可能会再次打开
  // 只在组件销毁时清理
}

// 监听器
watch(
  () => props.modelValue,
  (newVal) => {
    visible.value = newVal
    if (newVal && !pdfBlobUrl.value) {
      loadPreview()
    }
  },
  { immediate: true }
)

onMounted(() => {
  document.addEventListener('keydown', handleKeydown)
})

// 清理
onUnmounted(() => {
  document.removeEventListener('keydown', handleKeydown)
  if (pdfBlobUrl.value) {
    URL.revokeObjectURL(pdfBlobUrl.value)
  }
})
</script>
<style scoped lang="scss">
$a4-width: 210mm;
$a4-height: 297mm;
$a4-ratio: 1.414;
$page-shadow: 0 4px 12px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.05);
$page-shadow-hover: 0 8px 25px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.1);

.pdf-wrapper {
  transition: transform 0.3s ease;
  display: flex;
  justify-content: center;
  padding: 20px 0;
}

.pdf-embed {
  border-radius: 4px;
  box-shadow: $page-shadow;
  background: #fff;
  transition: all 0.3s ease;
  
  &:hover {
    box-shadow: $page-shadow-hover;
  }
}

.preview-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0;
  background: #f8f9fa;
  border-radius: 8px 8px 0 0;
  margin: -20px -20px 20px -20px;
  padding: 16px 20px;
  border-bottom: 1px solid #e4e7ed;
}

.preview-title-section {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1;
}

.preview-title-section h4 {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

.title-icon {
  color: #e74c3c;
  font-size: 18px;
}

.file-size-info {
  color: #909399;
  font-size: 12px;
  background: rgba(64, 158, 255, 0.1);
  color: #409eff;
  padding: 4px 8px;
  border-radius: 12px;
  font-weight: 500;
}

.preview-controls {
  display: flex;
  gap: 8px;
}

.preview-container {
  position: relative;
  min-height: 600px;
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
  border-radius: 12px;
  padding: 20px;
  margin: 0 -20px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.preview-content {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: flex-start;
}

.pdf-content {
  flex-direction: column;
  align-items: center;
  gap: 20px;
  width: 100%;
  max-width: 900px;
}

.pdf-embed-container {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 20px;
  align-items: center;
}

:deep(.vue-pdf-embed) {
  background: transparent !important;
  
  .vue-pdf-embed__page {
    margin: 0 auto 20px;
    background: #ffffff;
    box-shadow: $page-shadow;
    border-radius: 8px;
    padding: 0;
    transition: all 0.3s ease;
    position: relative;
    overflow: hidden;
    
    &::before {
      content: '';
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: linear-gradient(
        45deg,
        transparent 49%,
        rgba(255, 255, 255, 0.03) 49%,
        rgba(255, 255, 255, 0.03) 51%,
        transparent 51%
      );
      pointer-events: none;
      z-index: 1;
    }
    
    &:hover {
      box-shadow: $page-shadow-hover;
      transform: translateY(-2px);
    }
    
    canvas {
      display: block;
      border-radius: 8px;
      position: relative;
      z-index: 0;
    }
  }
  
  .vue-pdf-embed__container {
    background: transparent !important;
  }
}

.pdf-controls {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  padding: 16px 20px;
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(10px);
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
  position: sticky;
  bottom: 20px;
  z-index: 100;
  margin: 0 auto;
  width: 100%;
  max-width: 900px;
}

.page-input {
  width: 60px;
  text-align: center;
  
  :deep(.el-input__inner) {
    text-align: center;
    border-radius: 6px;
    font-weight: 500;
  }
}

.page-separator {
  margin: 0 8px;
  color: #909399;
  font-weight: 500;
}

.total-pages {
  color: #606266;
  font-weight: 600;
}

.zoom-controls {
  display: flex;
  align-items: center;
  gap: 8px;
}

.action-controls {
  display: flex;
  align-items: center;
  gap: 8px;
}

.zoom-display {
  min-width: 55px;
  text-align: center;
  font-size: 14px;
  color: #606266;
  font-weight: 600;
  background: rgba(64, 158, 255, 0.1);
  padding: 4px 8px;
  border-radius: 6px;
  color: #409eff;
}

.preview-error {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px 20px;
  text-align: center;
  color: #606266;
  height: 100%;
  min-height: 400px;
  background: rgba(255, 255, 255, 0.8);
  border-radius: 12px;
  backdrop-filter: blur(10px);
}

.error-title {
  font-size: 20px;
  font-weight: 600;
  margin: 20px 0 12px;
  color: #f56c6c;
}

.error-tip {
  margin: 16px 0 12px;
  font-size: 15px;
  color: #909399;
  font-weight: 500;
}

.error-reasons {
  text-align: left;
  margin: 16px 0 24px;
  padding: 16px 20px;
  background: rgba(245, 108, 108, 0.05);
  border-radius: 8px;
  border-left: 4px solid #f56c6c;
  
  li {
    margin: 6px 0;
    font-size: 14px;
    color: #606266;
    line-height: 1.5;
  }
}

.error-actions {
  display: flex;
  gap: 12px;
  margin-top: 24px;
}

:deep(.el-loading-mask) {
  background-color: rgba(248, 249, 250, 0.95);
  backdrop-filter: blur(5px);
  border-radius: 12px;
  
  .el-loading-spinner {
    .el-loading-text {
      color: #606266;
      font-weight: 500;
      margin-top: 16px;
    }
    
    .circular {
      width: 50px;
      height: 50px;
      color: #409eff;
    }
  }
}

@media (max-width: 1200px) {
  .preview-container {
    padding: 15px;
  }
  
  .pdf-controls {
    max-width: 100%;
    margin: 0 15px;
  }
}

@media (max-width: 768px) {
  .preview-header {
    flex-direction: column;
    gap: 12px;
    align-items: stretch;
    padding: 12px 16px;
  }
  
  .preview-controls {
    justify-content: center;
  }
  
  .pdf-controls {
    flex-direction: column;
    gap: 16px;
    padding: 16px;
    position: relative;
    bottom: auto;
    margin: 20px 0 0;
    
    .el-button-group {
      width: 100%;
      justify-content: center;
    }
  }
  
  .preview-container {
    padding: 10px;
    margin: 0 -10px;
  }
}

@media (max-width: 480px) {
  .pdf-controls {
    .el-button-group {
      flex-wrap: wrap;
      gap: 8px;
    }
    
    .zoom-controls,
    .action-controls {
      flex-wrap: wrap;
      justify-content: center;
    }
  }
  
  .preview-header {
    padding: 10px 12px;
  }
  
  .preview-title-section h4 {
    font-size: 14px;
  }
}

:deep(.pdf-preview-dialog) {
  .el-dialog__body {
    background: #ffffff;
  }
  
  .el-dialog__header {
    padding: 0;
    margin: 0;
    border-bottom: none;
  }
  
  .el-dialog__headerbtn {
    top: 16px;
    right: 16px;
    width: 32px;
    height: 32px;
    background: rgba(255, 255, 255, 0.9);
    border-radius: 50%;
    transition: all 0.3s ease;
    
    &:hover {
      background: rgba(245, 108, 108, 0.1);
      
      .el-dialog__close {
        color: #f56c6c;
      }
    }
  }
  
  .el-dialog__footer {
    padding: 0;
    border-top: none;
  }
}

:deep(.is-fullscreen) {
  .preview-container {
    min-height: calc(100vh - 200px);
  }
  
  .pdf-controls {
    position: fixed;
    bottom: 30px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 1000;
  }
}
</style>
