<!-- OnlyOfficeViewer.vue -->
<template>
  <div class="onlyoffice-viewer" :style="{ height: height }">
    <!-- 工具栏 -->
    <div v-if="!loading && !error" class="viewer-toolbar">
      <div class="toolbar-left">
        <button @click="handleClose" class="toolbar-btn" :disabled="closing">
          <i class="el-icon-back"></i> 返回
        </button>
        <span class="document-title" :title="documentName">{{ documentName }}</span>
      </div>
      <div class="toolbar-right">
        <button v-if="allowDownload" @click="downloadDocument" class="toolbar-btn download" :disabled="downloading">
          <i class="el-icon-download"></i> {{ downloading ? '下载中...' : '下载' }}
        </button>
        <button v-if="!isMobile && allowFullscreen" @click="toggleFullscreen" class="toolbar-btn">
          <i :class="isFullscreen ? 'el-icon-copy-document' : 'el-icon-full-screen'"></i>
          {{ isFullscreen ? '退出全屏' : '全屏' }}
        </button>
      </div>
    </div>

    <!-- 加载状态 -->
    <div v-if="loading" class="viewer-loading">
      <div class="loading-content">
        <div class="loading-spinner"></div>
        <p>{{ loadingText }}</p>
      </div>
    </div>

    <!-- 错误状态 -->
    <div v-if="error" class="viewer-error">
      <div class="error-content">
        <div class="error-icon">❌</div>
        <h3>加载失败</h3>
        <p>{{ errorMessage }}</p>
        <button @click="retry" class="retry-btn" :disabled="loading">重试</button>
      </div>
    </div>

    <!-- 编辑器容器 -->
    <div v-show="!loading && !error" ref="editorContainer" class="editor-container"
      :class="{ 'fullscreen': isFullscreen }" :style="{ height: containerHeight }"></div>

    <!-- 移动端提示 -->
    <div v-if="isMobile && !loading && !error" class="mobile-tip">
      <p>💡 在移动端建议横屏查看以获得更好体验</p>
    </div>
  </div>
</template>

<script>
import { getConfigAPI } from '@/api/common/onlyOfficeViewer';
import { downloadFileWithLoading } from '@/utils/download';

export default {
  name: 'OnlyOfficeViewer',

  props: {
    // 文档ID
    documentId: {
      type: String,
      required: true
    },
    // 文档名称
    documentName: {
      type: String,
      required: true
    },
    // 组件高度
    height: {
      type: String,
      default: '600px'
    },
    // 是否允许下载
    allowDownload: {
      type: Boolean,
      default: true
    },
    // 是否允许全屏
    allowFullscreen: {
      type: Boolean,
      default: true
    },
    // 查看模式：view（查看）或 edit（编辑）
    mode: {
      type: String,
      default: 'view',
      validator: (value) => ['view', 'edit'].includes(value)
    },
    // 下载API路径（可选，默认使用统一的下载接口）
    downloadUrl: {
      type: String,
      default: ''
    }
  },

  data() {
    return {
      loading: false,
      loadingText: '正在加载文档...',
      error: false,
      errorMessage: '',
      editor: null,
      isFullscreen: false,
      isMobile: false,
      downloading: false,
      closing: false
    };
  },

  computed: {
    // API基础URL
    apiBaseUrl() {
      return process.env.VUE_APP_BASE_API || '';
    },
    // OnlyOffice服务URL
    onlyOfficeUrl() {
      return process.env.VUE_APP_ONLYOFFICE_URL || process.env.VUE_APP_BASE_API || '';
    },
    // 容器高度（减去工具栏高度）
    containerHeight() {
      if (this.isFullscreen) {
        return '100vh';
      }
      // 工具栏高度约48px，减去后计算容器高度
      const heightValue = parseInt(this.height);
      if (isNaN(heightValue)) {
        return 'calc(100% - 48px)';
      }
      return `${heightValue - 48}px`;
    }
  },

  mounted() {
    this.checkMobile();
    this.setupFullscreenListener();
    this.initViewer();
  },

  beforeDestroy() {
    this.cleanup();
  },

  methods: {
    /**
     * 初始化查看器
     */
    async initViewer() {
      try {
        this.loading = true;
        this.loadingText = '正在加载文档...';
        this.error = false;
        this.errorMessage = '';

        // 检查容器是否存在
        if (!this.$refs.editorContainer) {
          throw new Error('编辑器容器未找到');
        }

        // 加载 OnlyOffice 脚本
        this.loadingText = '正在加载 OnlyOffice 脚本...';
        await this.loadOnlyOfficeScript();

        // 获取编辑器配置
        this.loadingText = '正在获取文档配置...';
        const config = await this.getEditorConfig();

        // 创建编辑器实例
        if (!window.DocsAPI) {
          throw new Error('OnlyOffice API 未加载成功');
        }

        this.loadingText = '正在初始化编辑器...';
        this.editor = new window.DocsAPI.DocEditor(
          this.$refs.editorContainer,
          config
        );

        this.loading = false;
        this.$emit('loaded', this.editor);
      } catch (error) {
        console.error('初始化文档查看器失败:', error);
        const errorMsg = error?.message || error?.response?.data?.msg || '加载文档失败，请重试';
        this.handleError(errorMsg);
      }
    },

    /**
     * 加载 OnlyOffice 脚本
     * @returns {Promise}
     */
    loadOnlyOfficeScript() {
      return new Promise((resolve, reject) => {
        // 如果已经加载，直接返回
        if (window.DocsAPI) {
          resolve();
          return;
        }

        // 检查是否正在加载
        const existingScript = document.querySelector('script[data-onlyoffice-api]');
        if (existingScript) {
          existingScript.addEventListener('load', resolve);
          existingScript.addEventListener('error', () => {
            reject(new Error('加载 OnlyOffice 脚本失败'));
          });
          return;
        }

        // 创建并加载脚本
        const script = document.createElement('script');
        script.src = `${this.onlyOfficeUrl}/web-apps/apps/api/documents/api.js`;
        script.setAttribute('data-onlyoffice-api', 'true');

        script.onload = () => {
          // 等待一小段时间确保 API 完全初始化
          setTimeout(resolve, 100);
        };
        script.onerror = () => {
          reject(new Error('加载 OnlyOffice 脚本失败，请检查 OnlyOffice 服务是否正常运行'));
        };

        document.head.appendChild(script);
      });
    },

    /**
     * 获取编辑器配置
     * @returns {Promise<Object>}
     */
    async getEditorConfig() {
      try {
        const res = await getConfigAPI({
          fileId: this.documentId,
          fileName: this.documentName,
          mode: this.mode
        });

        if (res.code !== 200) {
          throw new Error(res.msg || '获取编辑器配置失败');
        }

        return res.data;
      } catch (error) {
        console.error('获取编辑器配置失败:', error);
        const errorMsg = error?.response?.data?.msg || error?.message || '获取文档配置失败';
        throw new Error(errorMsg);
      }
    },

    /**
     * 下载文档
     */
    async downloadDocument() {
      if (!this.allowDownload || this.downloading) {
        return;
      }

      try {
        this.downloading = true;
        this.$emit('downloading');

        // 使用统一的下载方法
        let downloadPath = this.downloadUrl;
        if (!downloadPath) {
          // 默认下载路径
          downloadPath = `smartBid/documents/download?fileId=${this.documentId}&fileName=${encodeURIComponent(this.documentName)}`;
        }

        await downloadFileWithLoading(
          downloadPath,
          this.documentName,
          '正在下载文档，请稍候...'
        );

        this.$emit('download-success');
      } catch (error) {
        console.error('下载文档失败:', error);
        this.$message?.error?.('下载文档失败，请稍后重试');
        this.$emit('download-error', error);
      } finally {
        this.downloading = false;
      }
    },

    /**
     * 切换全屏
     */
    toggleFullscreen() {
      if (!this.allowFullscreen) {
        return;
      }

      if (!this.isFullscreen) {
        this.enterFullscreen();
      } else {
        this.exitFullscreen();
      }
    },

    /**
     * 进入全屏
     */
    enterFullscreen() {
      const element = this.$refs.editorContainer;
      if (!element) {
        return;
      }

      const requestFullscreen =
        element.requestFullscreen ||
        element.webkitRequestFullscreen ||
        element.mozRequestFullScreen ||
        element.msRequestFullscreen;

      if (requestFullscreen) {
        requestFullscreen.call(element);
      } else {
        this.$message?.warning?.('您的浏览器不支持全屏功能');
      }
    },

    /**
     * 退出全屏
     */
    exitFullscreen() {
      const exitFullscreen =
        document.exitFullscreen ||
        document.webkitExitFullscreen ||
        document.mozCancelFullScreen ||
        document.msExitFullscreen;

      if (exitFullscreen) {
        exitFullscreen.call(document);
      }
    },

    /**
     * 设置全屏监听
     */
    setupFullscreenListener() {
      const events = [
        'fullscreenchange',
        'webkitfullscreenchange',
        'mozfullscreenchange',
        'msfullscreenchange'
      ];

      events.forEach(event => {
        document.addEventListener(event, this.handleFullscreenChange);
      });
    },

    /**
     * 清理全屏监听
     */
    cleanupFullscreenListener() {
      const events = [
        'fullscreenchange',
        'webkitfullscreenchange',
        'mozfullscreenchange',
        'msfullscreenchange'
      ];

      events.forEach(event => {
        document.removeEventListener(event, this.handleFullscreenChange);
      });
    },

    /**
     * 处理全屏变化
     */
    handleFullscreenChange() {
      this.isFullscreen = !!(
        document.fullscreenElement ||
        document.webkitFullscreenElement ||
        document.mozFullScreenElement ||
        document.msFullscreenElement
      );
    },

    /**
     * 检查移动端
     */
    checkMobile() {
      const userAgent = navigator.userAgent || navigator.vendor || window.opera;
      this.isMobile = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(
        userAgent.toLowerCase()
      );
    },

    /**
     * 销毁编辑器
     */
    destroyEditor() {
      try {
        if (this.editor && typeof this.editor.destroy === 'function') {
          this.editor.destroy();
        }
      } catch (error) {
        console.warn('销毁编辑器时出错:', error);
      } finally {
        const container = this.$refs.editorContainer;
        if (container) {
          container.innerHTML = '';
        }
        this.editor = null;
      }
    },

    /**
     * 处理错误
     * @param {String} message - 错误消息
     */
    handleError(message) {
      this.error = true;
      this.errorMessage = message || '未知错误';
      this.loading = false;
      this.$emit('error', message);
    },

    /**
     * 重试加载
     */
    retry() {
      if (this.loading) {
        return;
      }
      this.error = false;
      this.errorMessage = '';
      this.initViewer();
    },

    /**
     * 关闭查看器
     */
    handleClose() {
      if (this.closing) {
        return;
      }
      this.closing = true;
      this.$emit('close');
    },

    /**
     * 清理资源
     */
    cleanup() {
      this.destroyEditor();
      this.cleanupFullscreenListener();
    }
  }
};
</script>

<style scoped lang="scss">
.onlyoffice-viewer {
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  overflow: hidden;
  background: white;
  display: flex;
  flex-direction: column;
  height: 100%;
}

.viewer-toolbar {
  background: #f8f9fa;
  padding: 12px 16px;
  border-bottom: 1px solid #e0e0e0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
  min-height: 48px;
  box-sizing: border-box;
}

.toolbar-left,
.toolbar-right {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1;
}

.toolbar-right {
  justify-content: flex-end;
}

.toolbar-btn {
  padding: 6px 12px;
  border: 1px solid #ddd;
  background: white;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  transition: all 0.2s;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  white-space: nowrap;

  i {
    font-size: 14px;
  }

  &:hover:not(:disabled) {
    background: #f0f0f0;
    border-color: #bbb;
  }

  &:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }

  &.download {
    background: #27ae60;
    color: white;
    border-color: #27ae60;

    &:hover:not(:disabled) {
      background: #219a52;
      border-color: #219a52;
    }
  }
}

.document-title {
  font-weight: 500;
  color: #333;
  margin-left: 8px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 300px;
  flex: 1;
}

.viewer-loading,
.viewer-error {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 400px;
  padding: 40px;
}

.loading-content,
.error-content {
  text-align: center;
}

.loading-spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #f3f3f3;
  border-top: 4px solid #3498db;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin: 0 auto 16px;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

.error-icon {
  font-size: 48px;
  margin-bottom: 16px;
}

.error-content h3 {
  margin: 0 0 8px 0;
  color: #e74c3c;
}

.error-content p {
  margin: 0 0 16px 0;
  color: #666;
}

.retry-btn {
  background: #3498db;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
}

.retry-btn:hover {
  background: #2980b9;
}

.editor-container {
  width: 100%;
  flex: 1;
  overflow: hidden;
  position: relative;
  transition: all 0.3s ease;
  background: #f5f5f5;
}

.editor-container.fullscreen {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 9999;
  background: white;
  border-radius: 0;
}

.mobile-tip {
  background: #fff3cd;
  border: 1px solid #ffeaa7;
  color: #856404;
  padding: 8px 16px;
  text-align: center;
  font-size: 14px;
}

@media (max-width: 768px) {
  .viewer-toolbar {
    padding: 8px 12px;
    flex-direction: column;
    gap: 8px;
    align-items: stretch;
  }

  .toolbar-left,
  .toolbar-right {
    justify-content: space-between;
  }

  .document-title {
    font-size: 14px;
    text-align: center;
    margin: 4px 0;
  }
}
</style>