<template>
  <a-modal
    v-model:open="visible"
    :title="title"
    :width="modalWidth"
    :footer="null"
    centered
    @cancel="handleClose"
  >
    <!-- PDF 预览 -->
    <div v-if="fileType === 'pdf'" class="preview-container pdf-container">
      <iframe
        v-if="previewUrl"
        :src="previewUrl"
        class="pdf-iframe"
        frameborder="0"
      ></iframe>
      <div v-else class="preview-error">
        <FileTextOutlined style="font-size: 48px; color: #999;" />
        <p>无法预览此PDF文件</p>
        <a-button type="primary" @click="downloadFile">下载查看</a-button>
      </div>
    </div>

    <!-- 音频播放器 -->
    <div v-else-if="fileType === 'audio'" class="preview-container audio-container">
      <div class="audio-player-wrapper">
        <div class="audio-icon">
          <AudioOutlined style="font-size: 64px; color: #1890ff;" />
        </div>
        <div class="audio-info">
          <h3>{{ fileName }}</h3>
        </div>
        <audio
          ref="audioRef"
          :src="previewUrl"
          controls
          class="audio-element"
          @error="handleMediaError"
        >
          您的浏览器不支持音频播放
        </audio>
      </div>
    </div>

    <!-- 视频播放器 -->
    <div v-else-if="fileType === 'video'" class="preview-container video-container">
      <video
        ref="videoRef"
        :src="previewUrl"
        controls
        class="video-element"
        @error="handleMediaError"
      >
        您的浏览器不支持视频播放
      </video>
    </div>

    <!-- 图片预览 -->
    <div v-else-if="fileType === 'image'" class="preview-container image-container">
      <a-image
        :src="previewUrl"
        :preview="true"
        class="preview-image"
        @error="handleImageError"
      />
    </div>

    <!-- PPT 预览（使用 Office Online 或 Google Docs 预览） -->
    <div v-else-if="fileType === 'ppt'" class="preview-container ppt-container">
      <div class="ppt-notice">
        <FilePptOutlined style="font-size: 48px; color: #ff7a45;" />
        <h3>PPT 文件预览</h3>
        <p>PPT 文件建议下载后使用 PowerPoint 或 WPS 查看</p>
        <a-space>
          <a-button type="primary" @click="downloadFile">
            <DownloadOutlined /> 下载文件
          </a-button>
          <a-button @click="openInOfficeOnline">
            <EyeOutlined /> 在线预览
          </a-button>
        </a-space>
      </div>
    </div>

    <!-- 其他文件类型 -->
    <div v-else class="preview-container other-container">
      <div class="other-notice">
        <FileOutlined style="font-size: 48px; color: #999;" />
        <h3>暂不支持预览</h3>
        <p>此文件类型暂不支持在线预览，请下载后查看</p>
        <a-button type="primary" @click="downloadFile">
          <DownloadOutlined /> 下载文件
        </a-button>
      </div>
    </div>

    <!-- 底部操作栏 -->
    <div class="preview-footer" v-if="fileType !== 'other'">
      <a-space>
        <a-button @click="downloadFile">
          <DownloadOutlined /> 下载
        </a-button>
        <a-button type="link" @click="openInNewTab">
          <ExportOutlined /> 新窗口打开
        </a-button>
      </a-space>
    </div>
  </a-modal>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue';
import {
  FileTextOutlined,
  AudioOutlined,
  FilePptOutlined,
  FileOutlined,
  DownloadOutlined,
  EyeOutlined,
  ExportOutlined,
} from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';

const props = defineProps<{
  open: boolean;
  fileUrl: string;
  fileName: string;
}>();

const emit = defineEmits<{
  (e: 'update:open', value: boolean): void;
}>();

const visible = computed({
  get: () => props.open,
  set: (value) => emit('update:open', value),
});

const audioRef = ref<HTMLAudioElement>();
const videoRef = ref<HTMLVideoElement>();

// 获取文件类型
const fileType = computed(() => {
  const url = props.fileUrl.toLowerCase();
  const name = props.fileName.toLowerCase();

  // 检查 URL 或文件名后缀
  const checkStr = url || name;

  if (checkStr.endsWith('.pdf')) return 'pdf';
  if (checkStr.endsWith('.ppt') || checkStr.endsWith('.pptx')) return 'ppt';
  if (checkStr.match(/\.(mp3|wav|ogg|aac|flac|m4a)$/)) return 'audio';
  if (checkStr.match(/\.(mp4|webm|ogg|mov|avi|mkv)$/)) return 'video';
  if (checkStr.match(/\.(jpg|jpeg|png|gif|webp|bmp|svg)$/)) return 'image';

  return 'other';
});

// 预览 URL（处理相对路径）
const previewUrl = computed(() => {
  if (!props.fileUrl) return '';

  // 如果已经是完整 URL，直接返回
  if (props.fileUrl.startsWith('http://') || props.fileUrl.startsWith('https://')) {
    return props.fileUrl;
  }

  // 如果是相对路径，拼接服务器地址
  const SERVER_BASE = import.meta.env.VITE_SERVER_BASE_URL || 'http://localhost:3000';
  return `${SERVER_BASE}${props.fileUrl}`;
});

// 模态框标题
const title = computed(() => {
  return `预览: ${props.fileName || '未知文件'}`;
});

// 模态框宽度
const modalWidth = computed(() => {
  switch (fileType.value) {
    case 'pdf':
      return '90%';
    case 'video':
      return 900;
    case 'audio':
      return 500;
    case 'image':
      return 800;
    default:
      return 600;
  }
});

// 关闭弹窗
const handleClose = () => {
  // 停止媒体播放
  if (audioRef.value) {
    audioRef.value.pause();
    audioRef.value.currentTime = 0;
  }
  if (videoRef.value) {
    videoRef.value.pause();
    videoRef.value.currentTime = 0;
  }
  visible.value = false;
};

// 下载文件
const downloadFile = () => {
  const link = document.createElement('a');
  link.href = previewUrl.value;
  link.download = props.fileName;
  link.target = '_blank';
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  message.success('开始下载');
};

// 在新窗口打开
const openInNewTab = () => {
  window.open(previewUrl.value, '_blank');
};

// 使用 Office Online 预览 PPT
const openInOfficeOnline = () => {
  // 需要 Office Online 服务支持，这里使用完整的 URL
  const fullUrl = previewUrl.value;
  if (!fullUrl.startsWith('http')) {
    message.warning('PPT 在线预览需要完整的文件 URL');
    return;
  }

  // 使用微软 Office Online 预览服务
  const officeUrl = `https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(fullUrl)}`;
  window.open(officeUrl, '_blank');
};

// 媒体加载错误处理
const handleMediaError = () => {
  message.error('媒体文件加载失败，请检查文件是否有效');
};

// 图片加载错误处理
const handleImageError = () => {
  message.error('图片加载失败');
};

// 监听弹窗打开，重置媒体状态
watch(visible, (newVal) => {
  if (!newVal) {
    // 关闭时重置
    if (audioRef.value) {
      audioRef.value.pause();
    }
    if (videoRef.value) {
      videoRef.value.pause();
    }
  }
});
</script>

<style scoped lang="scss">
.preview-container {
  min-height: 200px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.pdf-container {
  height: 80vh;

  .pdf-iframe {
    width: 100%;
    height: 100%;
    border: none;
  }

  .preview-error {
    text-align: center;
    padding: 40px;
  }
}

.audio-container {
  padding: 40px 20px;

  .audio-player-wrapper {
    width: 100%;
    text-align: center;

    .audio-icon {
      margin-bottom: 20px;
    }

    .audio-info {
      margin-bottom: 20px;

      h3 {
        margin: 0;
        color: #333;
        word-break: break-all;
      }
    }

    .audio-element {
      width: 100%;
      max-width: 400px;
    }
  }
}

.video-container {
  width: 100%;
  background: #000;
  border-radius: 4px;
  overflow: hidden;

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

.image-container {
  padding: 20px;

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

.ppt-container {
  .ppt-notice {
    text-align: center;
    padding: 40px;

    h3 {
      margin: 16px 0 8px;
      color: #333;
    }

    p {
      color: #666;
      margin-bottom: 20px;
    }
  }
}

.other-container {
  .other-notice {
    text-align: center;
    padding: 40px;

    h3 {
      margin: 16px 0 8px;
      color: #333;
    }

    p {
      color: #666;
      margin-bottom: 20px;
    }
  }
}

.preview-footer {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid #f0f0f0;
  text-align: right;
}
</style>
