import axios from 'axios';
/**
 * 文件操作工具类，支持上传、下载和删除文件
 */

export class FileService {
    constructor(baseUrl = '') {
      this.baseUrl = baseUrl;
    }
  
    /**
     * 上传文件到MinIO
     * @param {Object} options - 上传参数
     * @param {string} options.bucketName - 存储桶名称
     * @param {string} options.filePath - 文件路径
     * @param {File} options.file - 文件对象
     * @param {Function} [options.onProgress] - 进度回调函数
     * @returns {Promise<string>} - 上传成功后的文件路径
     */
    uploadFile(options) {
      const {
        bucketName,
        filePath,
        file,
      } = options;
  
      if (!bucketName || !filePath || !file) {
        return Promise.reject(new Error('缺少必要的上传参数'));
      }
  
      const formData = new FormData();
      formData.append('bucketName', bucketName);
      formData.append('filePath', filePath);
      formData.append('file', file);
  
      return axios({
        url: `${this.baseUrl}/api/file/upload`,
        method: 'post',
        data: formData,
        headers: { 'Accept': 'application/json' },
        timeout: 60000
      })
      .then(response => {
        if (response.status === 200) {
          return response.data;
        }
        throw new Error(`上传失败，状态码：${response.status}`);
      })
      .catch(this._handleError);
    }
  
    /**
     * 下载文件
     * @param {Object} options - 下载参数
     * @param {string} options.bucketName - 存储桶名称
     * @param {string} options.filePath - 文件路径
     * @param {string} [options.fileName] - 下载时使用的文件名
     * @returns {Promise<void>}
     */
    downloadFile(options) {
      const { bucketName, filePath, fileName } = options;
      
      if (!bucketName || !filePath) {
        return Promise.reject(new Error('缺少必要的下载参数'));
      }
  
      return axios({
        url: `${this.baseUrl}/api/file/download`,
        method: 'get',
        params: { bucketName, filePath },
        responseType: 'blob',
        timeout: 60000
      })
      .then(response => {
        if (response.status === 200) {
          this._saveFile(response.data, fileName || filePath.split('/').pop());
          return;
        }
        throw new Error(`下载失败，状态码：${response.status}`);
      })
      .catch(this._handleError);
    }
  
    /**
     * 删除文件
     * @param {Object} options - 删除参数
     * @param {string} options.bucketName - 存储桶名称
     * @param {string} options.filePath - 文件路径
     * @returns {Promise<void>}
     */
    deleteFile(options) {
      const { bucketName, filePath } = options;
      
      if (!bucketName || !filePath) {
        return Promise.reject(new Error('缺少必要的删除参数'));
      }
  
      return axios({
        url: `${this.baseUrl}/api/file/delete`,
        method: 'delete',
        params: { bucketName, filePath },
        timeout: 30000
      })
      .then(response => {
        if (response.status === 204) {
          return;
        }
        throw new Error(`删除失败，状态码：${response.status}`);
      })
      .catch(this._handleError);
    }
  
    /**
     * 检查文件是否存在
     * @param {Object} options - 参数
     * @param {string} options.bucketName - 存储桶名称
     * @param {string} options.filePath - 文件路径
     * @returns {Promise<boolean>} - 文件是否存在
     */
    fileExists(options) {
      const { bucketName, filePath } = options;
      
      if (!bucketName || !filePath) {
        return Promise.reject(new Error('缺少必要的参数'));
      }
  
      return axios({
        url: `${this.baseUrl}/api/file/exists`,
        method: 'get',
        params: { bucketName, filePath },
        timeout: 30000
      })
      .then(response => {
        if (response.status === 200) {
          return response.data;
        }
        throw new Error(`检查失败，状态码：${response.status}`);
      })
      .catch(this._handleError);
    }
  
    /**
     * 获取文件URL
     * @param {Object} options - 参数
     * @param {string} options.bucketName - 存储桶名称
     * @param {string} options.filePath - 文件路径
     * @param {number} [options.expirySeconds=3600] - URL有效期（秒）
     * @returns {Promise<string>} - 文件URL
     */
    getFileUrl(options) {
      const { bucketName, filePath, expirySeconds = 3600 } = options;
      
      if (!bucketName || !filePath) {
        return Promise.reject(new Error('缺少必要的参数'));
      }
  
      return axios({
        url: `${this.baseUrl}/api/file/url`,
        method: 'get',
        params: { bucketName, filePath, expirySeconds },
        timeout: 30000
      })
      .then(response => {
        if (response.status === 200) {
          return response.data;
        }
        throw new Error(`获取URL失败，状态码：${response.status}`);
      })
      .catch(this._handleError);
    }
  
    /**
     * 保存文件到本地
     * @param {Blob} blob - 文件内容
     * @param {string} fileName - 文件名
     */
    _saveFile(blob, fileName) {
      // 处理中文文件名
      const encodedFileName = encodeURIComponent(fileName);
      
      if (navigator.msSaveBlob) {
        // 兼容IE
        navigator.msSaveBlob(blob, fileName);
      } else {
        // 现代浏览器
        const link = document.createElement('a');
        link.href = URL.createObjectURL(blob);
        link.setAttribute('download', encodedFileName);
        link.style.display = 'none';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        URL.revokeObjectURL(link.href);
      }
    }
  
    /**
     * 统一处理错误
     * @param {Error} error - 错误对象
     */
    _handleError(error) {
      let errorMsg = '操作失败';
      if (error.response) {
        errorMsg += `，服务器错误：${error.response.status} ${error.response.statusText}`;
      } else if (error.request) {
        errorMsg += '，未收到服务器响应';
      } else {
        errorMsg += `，${error.message}`;
      }
      console.error(errorMsg, error);
      throw new Error(errorMsg);
    }
  }
  
  // 创建Vue插件
export const FileServicePlugin = {
    install(Vue, options = {}) {
      // 创建全局实例
      const fileService = new FileService(options.baseUrl);
      
      // 方式1：添加到Vue原型，全局可用
      Vue.prototype.$fileService = fileService;
      
      // 方式2：注册为全局组件
      Vue.fileService = fileService;
    }
  };