// 媒体文件管理器 - 微信小程序专用
// 处理图片、视频、音频、文件的上传、下载、预览、缓存等

const apiClient = require('./api-client.js');

/**
 * 媒体文件管理器
 * 功能：
 * 1. 文件选择和上传
 * 2. 媒体文件预览
 * 3. 文件下载和缓存
 * 4. 文件压缩和优化
 * 5. 云存储管理
 * 6. 文件类型检测
 */
class MediaManager {
  constructor() {
    this.isInitialized = false;
    
    // 媒体配置
    this.mediaConfig = {
      // 图片配置
      image: {
        maxSize: 10 * 1024 * 1024, // 10MB
        maxCount: 9, // 最多选择9张
        quality: 80, // 压缩质量
        formats: ['jpg', 'jpeg', 'png', 'gif', 'webp'],
        compressWidth: 1080 // 压缩宽度
      },
      
      // 视频配置
      video: {
        maxSize: 100 * 1024 * 1024, // 100MB
        maxDuration: 300, // 最长5分钟
        formats: ['mp4', 'mov', 'avi'],
        compressQuality: 'medium'
      },
      
      // 音频配置
      audio: {
        maxSize: 20 * 1024 * 1024, // 20MB
        maxDuration: 600, // 最长10分钟
        formats: ['mp3', 'wav', 'aac', 'm4a'],
        sampleRate: 16000
      },
      
      // 文件配置
      file: {
        maxSize: 50 * 1024 * 1024, // 50MB
        allowedTypes: ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'zip', 'rar'],
        maxCount: 5
      },
      
      // 缓存配置
      cache: {
        maxSize: 200 * 1024 * 1024, // 200MB
        expireTime: 7 * 24 * 60 * 60 * 1000, // 7天
        cleanupInterval: 24 * 60 * 60 * 1000 // 24小时清理一次
      }
    };
    
    // 文件缓存
    this.fileCache = new Map();
    
    // 上传队列
    this.uploadQueue = [];
    
    // 下载队列
    this.downloadQueue = [];
    
    // 当前上传任务
    this.currentUploads = new Map();
    
    // 缓存统计
    this.cacheStats = {
      totalSize: 0,
      fileCount: 0,
      lastCleanup: 0
    };
    
    this.init();
  }

  // 初始化媒体管理器
  async init() {
    if (this.isInitialized) return;
    
    console.log('📁 初始化媒体文件管理器...');
    
    try {
      // 加载文件缓存信息
      await this.loadCacheInfo();
      
      // 检查存储权限
      await this.checkStoragePermission();
      
      // 启动缓存清理
      this.startCacheCleanup();
      
      this.isInitialized = true;
      console.log('✅ 媒体文件管理器初始化完成');
      
    } catch (error) {
      console.error('❌ 媒体文件管理器初始化失败:', error);
    }
  }

  // 📷 ===== 图片处理 =====

  // 选择图片
  async chooseImages(options = {}) {
    try {
      const {
        count = this.mediaConfig.image.maxCount,
        sizeType = ['compressed', 'original'],
        sourceType = ['album', 'camera']
      } = options;
      
      console.log('📷 选择图片...');
      
      const result = await new Promise((resolve, reject) => {
        wx.chooseImage({
          count: count,
          sizeType: sizeType,
          sourceType: sourceType,
          success: resolve,
          fail: reject
        });
      });
      
      // 验证和处理图片
      const processedImages = await this.processImages(result.tempFilePaths);
      
      console.log(`📷 选择了 ${processedImages.length} 张图片`);
      return {
        success: true,
        images: processedImages
      };
      
    } catch (error) {
      console.error('❌ 选择图片失败:', error);
      return {
        success: false,
        error: error.errMsg || '选择图片失败'
      };
    }
  }

  // 处理图片
  async processImages(tempFilePaths) {
    const processedImages = [];
    
    for (const tempPath of tempFilePaths) {
      try {
        // 获取图片信息
        const imageInfo = await this.getImageInfo(tempPath);
        
        // 检查文件大小
        if (imageInfo.size > this.mediaConfig.image.maxSize) {
          console.warn('⚠️ 图片过大，需要压缩:', imageInfo.size);
          // 压缩图片
          const compressedPath = await this.compressImage(tempPath);
          imageInfo.tempFilePath = compressedPath;
        }
        
        // 生成缩略图
        const thumbnailPath = await this.generateThumbnail(imageInfo.tempFilePath);
        
        processedImages.push({
          ...imageInfo,
          thumbnailPath: thumbnailPath,
          type: 'image',
          status: 'ready'
        });
        
      } catch (error) {
        console.error('❌ 处理图片失败:', error);
      }
    }
    
    return processedImages;
  }

  // 获取图片信息
  async getImageInfo(src) {
    return new Promise((resolve, reject) => {
      wx.getImageInfo({
        src: src,
        success: (res) => {
          // 获取文件大小
          wx.getFileInfo({
            filePath: src,
            success: (fileInfo) => {
              resolve({
                ...res,
                size: fileInfo.size,
                tempFilePath: src
              });
            },
            fail: () => {
              resolve({
                ...res,
                size: 0,
                tempFilePath: src
              });
            }
          });
        },
        fail: reject
      });
    });
  }

  // 压缩图片
  async compressImage(src) {
    try {
      const result = await new Promise((resolve, reject) => {
        wx.compressImage({
          src: src,
          quality: this.mediaConfig.image.quality,
          success: resolve,
          fail: reject
        });
      });
      
      console.log('📷 图片压缩完成');
      return result.tempFilePath;
      
    } catch (error) {
      console.error('❌ 图片压缩失败:', error);
      return src; // 压缩失败返回原图
    }
  }

  // 生成缩略图
  async generateThumbnail(src) {
    try {
      // 创建canvas生成缩略图
      const canvas = wx.createOffscreenCanvas({ type: '2d' });
      const ctx = canvas.getContext('2d');
      
      // 设置缩略图尺寸
      const thumbnailSize = 200;
      canvas.width = thumbnailSize;
      canvas.height = thumbnailSize;
      
      // 加载图片
      const image = canvas.createImage();
      
      return new Promise((resolve) => {
        image.onload = () => {
          // 计算绘制尺寸
          const { drawWidth, drawHeight, drawX, drawY } = this.calculateDrawSize(
            image.width, 
            image.height, 
            thumbnailSize, 
            thumbnailSize
          );
          
          // 绘制缩略图
          ctx.drawImage(image, drawX, drawY, drawWidth, drawHeight);
          
          // 导出为临时文件
          wx.canvasToTempFilePath({
            canvas: canvas,
            success: (res) => {
              resolve(res.tempFilePath);
            },
            fail: () => {
              resolve(src); // 生成失败返回原图
            }
          });
        };
        
        image.onerror = () => {
          resolve(src); // 加载失败返回原图
        };
        
        image.src = src;
      });
      
    } catch (error) {
      console.error('❌ 生成缩略图失败:', error);
      return src;
    }
  }

  // 计算绘制尺寸
  calculateDrawSize(imageWidth, imageHeight, canvasWidth, canvasHeight) {
    const imageRatio = imageWidth / imageHeight;
    const canvasRatio = canvasWidth / canvasHeight;
    
    let drawWidth, drawHeight, drawX, drawY;
    
    if (imageRatio > canvasRatio) {
      // 图片更宽，以高度为准
      drawHeight = canvasHeight;
      drawWidth = drawHeight * imageRatio;
      drawX = (canvasWidth - drawWidth) / 2;
      drawY = 0;
    } else {
      // 图片更高，以宽度为准
      drawWidth = canvasWidth;
      drawHeight = drawWidth / imageRatio;
      drawX = 0;
      drawY = (canvasHeight - drawHeight) / 2;
    }
    
    return { drawWidth, drawHeight, drawX, drawY };
  }

  // 🎬 ===== 视频处理 =====

  // 选择视频
  async chooseVideo(options = {}) {
    try {
      const {
        sourceType = ['album', 'camera'],
        maxDuration = this.mediaConfig.video.maxDuration,
        camera = 'back'
      } = options;
      
      console.log('🎬 选择视频...');
      
      const result = await new Promise((resolve, reject) => {
        wx.chooseVideo({
          sourceType: sourceType,
          maxDuration: maxDuration,
          camera: camera,
          success: resolve,
          fail: reject
        });
      });
      
      // 验证和处理视频
      const processedVideo = await this.processVideo(result);
      
      console.log('🎬 选择视频完成');
      return {
        success: true,
        video: processedVideo
      };
      
    } catch (error) {
      console.error('❌ 选择视频失败:', error);
      return {
        success: false,
        error: error.errMsg || '选择视频失败'
      };
    }
  }

  // 处理视频
  async processVideo(videoResult) {
    try {
      // 检查文件大小
      if (videoResult.size > this.mediaConfig.video.maxSize) {
        throw new Error('视频文件过大');
      }
      
      // 检查时长
      if (videoResult.duration > this.mediaConfig.video.maxDuration) {
        throw new Error('视频时长超出限制');
      }
      
      // 生成视频缩略图
      const thumbnailPath = await this.generateVideoThumbnail(videoResult.tempFilePath);
      
      return {
        tempFilePath: videoResult.tempFilePath,
        duration: videoResult.duration,
        size: videoResult.size,
        width: videoResult.width,
        height: videoResult.height,
        thumbnailPath: thumbnailPath,
        type: 'video',
        status: 'ready'
      };
      
    } catch (error) {
      console.error('❌ 处理视频失败:', error);
      throw error;
    }
  }

  // 生成视频缩略图
  async generateVideoThumbnail(videoPath) {
    try {
      // 微信小程序暂不支持视频帧提取，使用默认图标
      return null;
    } catch (error) {
      console.error('❌ 生成视频缩略图失败:', error);
      return null;
    }
  }

  // 📄 ===== 文件处理 =====

  // 选择文件
  async chooseFile(options = {}) {
    try {
      const {
        count = this.mediaConfig.file.maxCount,
        type = 'all'
      } = options;
      
      console.log('📄 选择文件...');
      
      const result = await new Promise((resolve, reject) => {
        wx.chooseMessageFile({
          count: count,
          type: type,
          success: resolve,
          fail: reject
        });
      });
      
      // 验证和处理文件
      const processedFiles = await this.processFiles(result.tempFiles);
      
      console.log(`📄 选择了 ${processedFiles.length} 个文件`);
      return {
        success: true,
        files: processedFiles
      };
      
    } catch (error) {
      console.error('❌ 选择文件失败:', error);
      return {
        success: false,
        error: error.errMsg || '选择文件失败'
      };
    }
  }

  // 处理文件
  async processFiles(tempFiles) {
    const processedFiles = [];
    
    for (const file of tempFiles) {
      try {
        // 检查文件大小
        if (file.size > this.mediaConfig.file.maxSize) {
          console.warn('⚠️ 文件过大:', file.name, file.size);
          continue;
        }
        
        // 检查文件类型
        const fileExtension = this.getFileExtension(file.name);
        if (!this.isAllowedFileType(fileExtension)) {
          console.warn('⚠️ 不支持的文件类型:', fileExtension);
          continue;
        }
        
        processedFiles.push({
          tempFilePath: file.path,
          name: file.name,
          size: file.size,
          type: 'file',
          extension: fileExtension,
          status: 'ready'
        });
        
      } catch (error) {
        console.error('❌ 处理文件失败:', error);
      }
    }
    
    return processedFiles;
  }

  // 获取文件扩展名
  getFileExtension(fileName) {
    const lastDotIndex = fileName.lastIndexOf('.');
    if (lastDotIndex === -1) return '';
    return fileName.substring(lastDotIndex + 1).toLowerCase();
  }

  // 检查文件类型是否允许
  isAllowedFileType(extension) {
    return this.mediaConfig.file.allowedTypes.includes(extension);
  }

  // 📤 ===== 文件上传 =====

  // 上传文件
  async uploadFile(file, options = {}) {
    try {
      const {
        onProgress,
        onSuccess,
        onError
      } = options;
      
      console.log('📤 开始上传文件:', file.name || 'unknown');
      
      // 生成上传ID
      const uploadId = this.generateUploadId();
      
      // 添加到上传队列
      const uploadTask = {
        id: uploadId,
        file: file,
        status: 'uploading',
        progress: 0,
        onProgress: onProgress,
        onSuccess: onSuccess,
        onError: onError
      };
      
      this.currentUploads.set(uploadId, uploadTask);
      
      // 执行上传
      const result = await this.performUpload(uploadTask);
      
      // 移除上传任务
      this.currentUploads.delete(uploadId);
      
      return result;
      
    } catch (error) {
      console.error('❌ 上传文件失败:', error);
      return {
        success: false,
        error: error.message
      };
    }
  }

  // 执行上传
  async performUpload(uploadTask) {
    return new Promise((resolve, reject) => {
      const uploadTask_wx = wx.uploadFile({
        url: `${apiClient.baseURL}/api/v1/files/upload`,
        filePath: uploadTask.file.tempFilePath,
        name: 'file',
        header: {
          'Authorization': `Bearer ${wx.getStorageSync('token')}`
        },
        formData: {
          type: uploadTask.file.type,
          name: uploadTask.file.name || 'unknown'
        },
        success: (res) => {
          try {
            const data = JSON.parse(res.data);
            if (data.success) {
              console.log('✅ 文件上传成功:', data.data.url);
              
              const result = {
                success: true,
                data: {
                  url: data.data.url,
                  fileId: data.data.fileId,
                  fileName: uploadTask.file.name,
                  fileSize: uploadTask.file.size,
                  fileType: uploadTask.file.type
                }
              };
              
              if (uploadTask.onSuccess) {
                uploadTask.onSuccess(result);
              }
              
              resolve(result);
            } else {
              throw new Error(data.error || '上传失败');
            }
          } catch (error) {
            reject(error);
          }
        },
        fail: (error) => {
          console.error('❌ 上传请求失败:', error);
          if (uploadTask.onError) {
            uploadTask.onError(error);
          }
          reject(error);
        }
      });
      
      // 监听上传进度
      uploadTask_wx.onProgressUpdate((res) => {
        uploadTask.progress = res.progress;
        
        if (uploadTask.onProgress) {
          uploadTask.onProgress({
            progress: res.progress,
            totalBytesSent: res.totalBytesSent,
            totalBytesExpectedToSend: res.totalBytesExpectedToSend
          });
        }
      });
      
      // 保存上传任务引用
      uploadTask.wxTask = uploadTask_wx;
    });
  }

  // 取消上传
  cancelUpload(uploadId) {
    const uploadTask = this.currentUploads.get(uploadId);
    if (uploadTask && uploadTask.wxTask) {
      uploadTask.wxTask.abort();
      this.currentUploads.delete(uploadId);
      console.log('📤 取消上传:', uploadId);
    }
  }

  // 生成上传ID
  generateUploadId() {
    return `upload_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
  }

  // 📥 ===== 文件下载和缓存 =====

  // 下载文件
  async downloadFile(url, options = {}) {
    try {
      const {
        fileName,
        onProgress,
        useCache = true
      } = options;
      
      console.log('📥 下载文件:', url);
      
      // 检查缓存
      if (useCache) {
        const cachedPath = this.getCachedFilePath(url);
        if (cachedPath) {
          console.log('📥 使用缓存文件:', cachedPath);
          return {
            success: true,
            tempFilePath: cachedPath,
            cached: true
          };
        }
      }
      
      // 执行下载
      const result = await this.performDownload(url, { fileName, onProgress });
      
      // 缓存文件
      if (result.success && useCache) {
        this.cacheFile(url, result.tempFilePath);
      }
      
      return result;
      
    } catch (error) {
      console.error('❌ 下载文件失败:', error);
      return {
        success: false,
        error: error.message
      };
    }
  }

  // 执行下载
  async performDownload(url, options = {}) {
    return new Promise((resolve, reject) => {
      const downloadTask = wx.downloadFile({
        url: url,
        success: (res) => {
          if (res.statusCode === 200) {
            console.log('✅ 文件下载成功');
            resolve({
              success: true,
              tempFilePath: res.tempFilePath,
              cached: false
            });
          } else {
            reject(new Error(`下载失败: ${res.statusCode}`));
          }
        },
        fail: reject
      });
      
      // 监听下载进度
      if (options.onProgress) {
        downloadTask.onProgressUpdate((res) => {
          options.onProgress({
            progress: res.progress,
            totalBytesWritten: res.totalBytesWritten,
            totalBytesExpectedToWrite: res.totalBytesExpectedToWrite
          });
        });
      }
    });
  }

  // 检查存储权限
  async checkStoragePermission() {
    try {
      const storageInfo = wx.getStorageInfoSync();
      console.log('📁 存储信息:', storageInfo);
      return true;
    } catch (error) {
      console.error('❌ 检查存储权限失败:', error);
      return false;
    }
  }

  // 加载缓存信息
  async loadCacheInfo() {
    try {
      const cacheInfo = wx.getStorageSync('mediaCacheInfo') || {};
      this.cacheStats = {
        totalSize: cacheInfo.totalSize || 0,
        fileCount: cacheInfo.fileCount || 0,
        lastCleanup: cacheInfo.lastCleanup || 0
      };
    } catch (error) {
      console.error('❌ 加载缓存信息失败:', error);
    }
  }

  // 保存缓存信息
  async saveCacheInfo() {
    try {
      wx.setStorageSync('mediaCacheInfo', this.cacheStats);
    } catch (error) {
      console.error('❌ 保存缓存信息失败:', error);
    }
  }

  // 获取缓存文件路径
  getCachedFilePath(url) {
    const cacheKey = this.generateCacheKey(url);
    return this.fileCache.get(cacheKey);
  }

  // 缓存文件
  cacheFile(url, filePath) {
    const cacheKey = this.generateCacheKey(url);
    this.fileCache.set(cacheKey, filePath);
    
    // 更新缓存统计
    this.cacheStats.fileCount++;
    this.saveCacheInfo();
  }

  // 生成缓存键
  generateCacheKey(url) {
    // 使用URL的hash作为缓存键
    let hash = 0;
    for (let i = 0; i < url.length; i++) {
      const char = url.charCodeAt(i);
      hash = ((hash << 5) - hash) + char;
      hash = hash & hash; // 转换为32位整数
    }
    return `cache_${Math.abs(hash)}`;
  }

  // 启动缓存清理
  startCacheCleanup() {
    setInterval(() => {
      this.performCacheCleanup();
    }, this.mediaConfig.cache.cleanupInterval);
  }

  // 执行缓存清理
  performCacheCleanup() {
    try {
      console.log('📁 执行缓存清理...');
      
      const now = Date.now();
      const expireTime = this.mediaConfig.cache.expireTime;
      
      // 清理过期缓存
      for (const [key, filePath] of this.fileCache) {
        try {
          const stats = wx.getFileInfo({ filePath });
          if (now - stats.createTime > expireTime) {
            this.fileCache.delete(key);
            // 删除文件
            wx.removeSavedFile({ filePath });
          }
        } catch (error) {
          // 文件不存在，从缓存中移除
          this.fileCache.delete(key);
        }
      }
      
      // 更新清理时间
      this.cacheStats.lastCleanup = now;
      this.saveCacheInfo();
      
      console.log('✅ 缓存清理完成');
      
    } catch (error) {
      console.error('❌ 缓存清理失败:', error);
    }
  }

  // 获取媒体管理器状态
  getStatus() {
    return {
      isInitialized: this.isInitialized,
      uploadCount: this.currentUploads.size,
      cacheStats: { ...this.cacheStats },
      config: this.mediaConfig
    };
  }

  // 清除所有缓存
  clearAllCache() {
    this.fileCache.clear();
    this.cacheStats = {
      totalSize: 0,
      fileCount: 0,
      lastCleanup: Date.now()
    };
    this.saveCacheInfo();
    console.log('📁 已清除所有媒体缓存');
  }

  // 重置管理器
  reset() {
    // 取消所有上传任务
    for (const [uploadId] of this.currentUploads) {
      this.cancelUpload(uploadId);
    }
    
    this.clearAllCache();
  }
}

// 创建全局实例
const mediaManager = new MediaManager();

module.exports = mediaManager;
